From 846f78d414101dbd33ff9c370d379bae73ae0efa Mon Sep 17 00:00:00 2001 From: Prathamesh Kulkarni Date: Wed, 21 Aug 2019 18:34:43 +0000 Subject: re PR target/90724 (ICE with __sync_bool_compare_and_swap with -march=armv8.2-a+sve) 2019-08-21 Prathamesh Kulkarni PR target/90724 * config/aarch64/aarch64.c (aarch64_gen_compare_reg_maybe_ze): Force y in reg if it fails aarch64_plus_operand predicate. From-SVN: r274805 --- gcc/ChangeLog | 6 ++++++ gcc/config/aarch64/aarch64.c | 3 +++ 2 files changed, 9 insertions(+) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7550e42..e5ae7ad 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-08-21 Prathamesh Kulkarni + + PR target/90724 + * config/aarch64/aarch64.c (aarch64_gen_compare_reg_maybe_ze): Force y + in reg if it fails aarch64_plus_operand predicate. + 2019-08-21 Richard Biener PR tree-optimization/91482 diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 146d020..23f7216 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -2070,6 +2070,9 @@ aarch64_gen_compare_reg_maybe_ze (RTX_CODE code, rtx x, rtx y, } } + if (!aarch64_plus_operand (y, y_mode)) + y = force_reg (y_mode, y); + return aarch64_gen_compare_reg (code, x, y); } -- cgit v1.1 From 9556ef20164e69d094f5a3e1af262dbb45ed8e3a Mon Sep 17 00:00:00 2001 From: Prathamesh Kulkarni Date: Wed, 21 Aug 2019 20:41:41 +0000 Subject: re PR target/88839 ([SVE] Poor implementation of blend-like permutes) 2019-08-22 Prathamesh Kulkarni Richard Sandiford PR target/88839 * config/aarch64/aarch64.c (aarch64_evpc_sel): New function. (aarch64_expand_vec_perm_const_1): Call aarch64_evpc_sel. testsuite/ * gcc.target/aarch64/sve/sel_1.c: New test. * gcc.target/aarch64/sve/sel_2.c: Likewise. * gcc.target/aarch64/sve/sel_3.c: Likewise. * gcc.target/aarch64/sve/sel_4.c: Likewise. * gcc.target/aarch64/sve/sel_5.c: Likewise. * gcc.target/aarch64/sve/sel_6.c: Likewise. Co-Authored-By: Richard Sandiford From-SVN: r274810 --- gcc/ChangeLog | 7 ++++ gcc/config/aarch64/aarch64.c | 46 +++++++++++++++++++++++++ gcc/testsuite/ChangeLog | 11 ++++++ gcc/testsuite/gcc.target/aarch64/sve/sel_1.c | 27 +++++++++++++++ gcc/testsuite/gcc.target/aarch64/sve/sel_2.c | 41 +++++++++++++++++++++++ gcc/testsuite/gcc.target/aarch64/sve/sel_3.c | 50 ++++++++++++++++++++++++++++ gcc/testsuite/gcc.target/aarch64/sve/sel_4.c | 50 ++++++++++++++++++++++++++++ gcc/testsuite/gcc.target/aarch64/sve/sel_5.c | 50 ++++++++++++++++++++++++++++ gcc/testsuite/gcc.target/aarch64/sve/sel_6.c | 42 +++++++++++++++++++++++ 9 files changed, 324 insertions(+) create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/sel_1.c create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/sel_2.c create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/sel_3.c create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/sel_4.c create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/sel_5.c create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/sel_6.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e5ae7ad..8f08e39 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2019-08-22 Prathamesh Kulkarni + Richard Sandiford + + PR target/88839 + * config/aarch64/aarch64.c (aarch64_evpc_sel): New function. + (aarch64_expand_vec_perm_const_1): Call aarch64_evpc_sel. + 2019-08-21 Prathamesh Kulkarni PR target/90724 diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 23f7216..01b138d 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -17975,6 +17975,50 @@ aarch64_evpc_sve_tbl (struct expand_vec_perm_d *d) return true; } +/* Try to implement D using SVE SEL instruction. */ + +static bool +aarch64_evpc_sel (struct expand_vec_perm_d *d) +{ + machine_mode vmode = d->vmode; + int unit_size = GET_MODE_UNIT_SIZE (vmode); + + if (d->vec_flags != VEC_SVE_DATA + || unit_size > 8) + return false; + + int n_patterns = d->perm.encoding ().npatterns (); + poly_int64 vec_len = d->perm.length (); + + for (int i = 0; i < n_patterns; ++i) + if (!known_eq (d->perm[i], i) + && !known_eq (d->perm[i], vec_len + i)) + return false; + + for (int i = n_patterns; i < n_patterns * 2; i++) + if (!d->perm.series_p (i, n_patterns, i, n_patterns) + && !d->perm.series_p (i, n_patterns, vec_len + i, n_patterns)) + return false; + + if (d->testing_p) + return true; + + machine_mode pred_mode = aarch64_sve_pred_mode (unit_size).require (); + + rtx_vector_builder builder (pred_mode, n_patterns, 2); + for (int i = 0; i < n_patterns * 2; i++) + { + rtx elem = known_eq (d->perm[i], i) ? CONST1_RTX (BImode) + : CONST0_RTX (BImode); + builder.quick_push (elem); + } + + rtx const_vec = builder.build (); + rtx pred = force_reg (pred_mode, const_vec); + emit_insn (gen_vcond_mask (vmode, vmode, d->target, d->op1, d->op0, pred)); + return true; +} + static bool aarch64_expand_vec_perm_const_1 (struct expand_vec_perm_d *d) { @@ -18007,6 +18051,8 @@ aarch64_expand_vec_perm_const_1 (struct expand_vec_perm_d *d) return true; else if (aarch64_evpc_trn (d)) return true; + else if (aarch64_evpc_sel (d)) + return true; if (d->vec_flags == VEC_SVE_DATA) return aarch64_evpc_sve_tbl (d); else if (d->vec_flags == VEC_ADVSIMD) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 27c5144..0d141dc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2019-08-22 Prathamesh Kulkarni + Richard Sandiford + + PR target/88839 + * gcc.target/aarch64/sve/sel_1.c: New test. + * gcc.target/aarch64/sve/sel_2.c: Likewise. + * gcc.target/aarch64/sve/sel_3.c: Likewise. + * gcc.target/aarch64/sve/sel_4.c: Likewise. + * gcc.target/aarch64/sve/sel_5.c: Likewise. + * gcc.target/aarch64/sve/sel_6.c: Likewise. + 2019-08-21 Richard Sandiford PR c++/91505 diff --git a/gcc/testsuite/gcc.target/aarch64/sve/sel_1.c b/gcc/testsuite/gcc.target/aarch64/sve/sel_1.c new file mode 100644 index 0000000..e651e5b9 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/sel_1.c @@ -0,0 +1,27 @@ +/* { dg-do assemble { target aarch64_asm_sve_ok } } */ +/* { dg-options "-O2 -msve-vector-bits=256 --save-temps" } */ + +#include + +typedef int8_t vnx16qi __attribute__((vector_size (32))); + +/* Predicate vector: 1 0 1 0 ... */ + +#define MASK_32 { 0, 33, 2, 35, 4, 37, 6, 39, 8, 41, \ + 10, 43, 12, 45, 14, 47, 16, 49, 18, 51, \ + 20, 53, 22, 55, 24, 57, 26, 59, 28, 61, 30, 63 } + +#define INDEX_32 vnx16qi + +#define PERMUTE(type, nunits) \ +type permute_##type (type x, type y) \ +{ \ + return __builtin_shuffle (x, y, (INDEX_##nunits) MASK_##nunits); \ +} + +PERMUTE(vnx16qi, 32) + +/* { dg-final { scan-assembler-not {\ttbl\t} } } */ + +/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.b, p[0-9]+, z[0-9]+\.b, z[0-9]+\.b\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tptrue\tp[0-9]+\.h, vl16\n} 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/sel_2.c b/gcc/testsuite/gcc.target/aarch64/sve/sel_2.c new file mode 100644 index 0000000..0539147 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/sel_2.c @@ -0,0 +1,41 @@ +/* { dg-do assemble { target aarch64_asm_sve_ok } } */ +/* { dg-options "-O2 -msve-vector-bits=256 --save-temps" } */ + +#include + +typedef int8_t vnx16qi __attribute__((vector_size (32))); +typedef int16_t vnx8hi __attribute__((vector_size (32))); +typedef int32_t vnx4si __attribute__((vector_size (32))); + +typedef _Float16 vnx8hf __attribute__((vector_size (32))); +typedef float vnx4sf __attribute__((vector_size (32))); + +/* Predicate vector: 1 0 0 0 ... */ + +#define MASK_32 { 0, 33, 34, 35, 4, 37, 38, 39, 8, 41, 42, 43, 12, \ + 45, 46, 47, 16, 49, 50, 51, 20, 53, 54, 55, 24, \ + 57, 58, 59, 28, 61, 62, 63 } + +/* Predicate vector: 1 0 1 0 ... */ + +#define MASK_16 {0, 17, 2, 19, 4, 21, 6, 23, 8, 25, 10, 27, 12, 29, 14, 31} + +#define INDEX_32 vnx16qi +#define INDEX_16 vnx8hi + +#define PERMUTE(type, nunits) \ +type permute_##type (type x, type y) \ +{ \ + return __builtin_shuffle (x, y, (INDEX_##nunits) MASK_##nunits); \ +} + +PERMUTE(vnx16qi, 32) +PERMUTE(vnx8hi, 16) +PERMUTE(vnx8hf, 16) + +/* { dg-final { scan-assembler-not {\ttbl\t} } } */ + +/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.b, p[0-9]+, z[0-9]+\.b, z[0-9]+\.b\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.h, p[0-9]+, z[0-9]+\.h, z[0-9]+\.h\n} 2 } } */ + +/* { dg-final { scan-assembler-times {\tptrue\tp[0-9]+\.s, vl8\n} 3 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/sel_3.c b/gcc/testsuite/gcc.target/aarch64/sve/sel_3.c new file mode 100644 index 0000000..a87492d --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/sel_3.c @@ -0,0 +1,50 @@ +/* { dg-do assemble { target aarch64_asm_sve_ok } } */ +/* { dg-options "-O2 -msve-vector-bits=256 --save-temps" } */ + +#include + +typedef int8_t vnx16qi __attribute__((vector_size (32))); +typedef int16_t vnx8hi __attribute__((vector_size (32))); +typedef int32_t vnx4si __attribute__((vector_size (32))); +typedef _Float16 vnx8hf __attribute__((vector_size (32))); +typedef float vnx4sf __attribute__((vector_size (32))); + +/* Predicate vector: 1 0 0 0 0 0 0 0 ... */ + +#define MASK_32 { 0, 33, 34, 35, 36, 37, 38, 39, \ + 8, 41, 42, 43, 44, 45, 46, 47, \ + 16, 49, 50, 51, 52, 53, 54, 55, \ + 24, 57, 58, 59, 60, 61, 62, 63 } + +/* Predicate vector: 1 0 0 0 ... */ + +#define MASK_16 { 0, 17, 18, 19, 4, 21, 22, 23, \ + 8, 25, 26, 27, 12, 29, 30, 31 } + +/* Predicate vector: 1 0 ... */ + +#define MASK_8 { 0, 9, 2, 11, 4, 13, 6, 15 } + +#define INDEX_32 vnx16qi +#define INDEX_16 vnx8hi +#define INDEX_8 vnx4si + +#define PERMUTE(type, nunits) \ +type permute_##type (type x, type y) \ +{ \ + return __builtin_shuffle (x, y, (INDEX_##nunits) MASK_##nunits); \ +} + +PERMUTE(vnx16qi, 32) +PERMUTE(vnx8hi, 16) +PERMUTE(vnx4si, 8) +PERMUTE(vnx8hf, 16) +PERMUTE(vnx4sf, 8) + +/* { dg-final { scan-assembler-not {\ttbl\t} } } */ + +/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.b, p[0-9]+, z[0-9]+\.b, z[0-9]+\.b\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.h, p[0-9]+, z[0-9]+\.h, z[0-9]+\.h\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.s, p[0-9]+, z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */ + +/* { dg-final { scan-assembler-times {\tptrue\tp[0-9]+\.d, vl4\n} 5 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/sel_4.c b/gcc/testsuite/gcc.target/aarch64/sve/sel_4.c new file mode 100644 index 0000000..e9bbc55 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/sel_4.c @@ -0,0 +1,50 @@ +/* { dg-do assemble { target aarch64_asm_sve_ok } } */ +/* { dg-options "-O2 -msve-vector-bits=256 --save-temps" } */ + +#include + +typedef int8_t vnx16qi __attribute__((vector_size (32))); +typedef int16_t vnx8hi __attribute__((vector_size (32))); +typedef int32_t vnx4si __attribute__((vector_size (32))); +typedef int64_t vnx2di __attribute__((vector_size (32))); + +typedef _Float16 vnx8hf __attribute__((vector_size (32))); +typedef float vnx4sf __attribute__((vector_size (32))); +typedef double vnx2df __attribute__((vector_size (32))); + +/* Predicate vector: 1 1 0 0 ... */ + +#define MASK_32 { 0, 1, 34, 35, 4, 5, 38, 39, 8, 9, 42, 43, 12, 13, \ + 46, 47, 16, 17, 50, 51, 20, 21, 54, 55, 24, 25, \ + 58, 59, 28, 29, 62, 63 } + +#define MASK_16 {0, 1, 18, 19, 4, 5, 22, 23, 8, 9, 26, 27, 12, 13, 30, 31} +#define MASK_8 {0, 1, 10, 11, 4, 5, 14, 15} +#define MASK_4 {0, 1, 6, 7} + +#define INDEX_32 vnx16qi +#define INDEX_16 vnx8hi +#define INDEX_8 vnx4si +#define INDEX_4 vnx2di + +#define PERMUTE(type, nunits) \ +type permute_##type (type x, type y) \ +{ \ + return __builtin_shuffle (x, y, (INDEX_##nunits) MASK_##nunits); \ +} + +PERMUTE(vnx16qi, 32) +PERMUTE(vnx8hi, 16) +PERMUTE(vnx4si, 8) +PERMUTE(vnx2di, 4) + +PERMUTE(vnx8hf, 16) +PERMUTE(vnx4sf, 8) +PERMUTE(vnx2df, 4) + +/* { dg-final { scan-assembler-not {\ttbl\t} } } */ + +/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.b, p[0-9]+, z[0-9]+\.b, z[0-9]+\.b\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.h, p[0-9]+, z[0-9]+\.h, z[0-9]+\.h\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.s, p[0-9]+, z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.d, p[0-9]+, z[0-9]+\.d, z[0-9]+\.d\n} 2 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/sel_5.c b/gcc/testsuite/gcc.target/aarch64/sve/sel_5.c new file mode 100644 index 0000000..935abb5 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/sel_5.c @@ -0,0 +1,50 @@ +/* { dg-do assemble { target aarch64_asm_sve_ok } } */ +/* { dg-options "-O2 -msve-vector-bits=256 --save-temps" } */ + +#include + +typedef int8_t vnx16qi __attribute__((vector_size (32))); +typedef int16_t vnx8hi __attribute__((vector_size (32))); +typedef int32_t vnx4si __attribute__((vector_size (32))); +typedef int64_t vnx2di __attribute__((vector_size (32))); + +typedef _Float16 vnx8hf __attribute__((vector_size (32))); +typedef float vnx4sf __attribute__((vector_size (32))); +typedef double vnx2df __attribute__((vector_size (32))); + +/* Predicate vector: 1 0 0 1 ... */ + +#define MASK_32 { 0, 33, 34, 3, 4, 37, 38, 7, 8, 41, 42, 11, 12, 45, 46, \ + 15, 16, 49, 50, 19, 20, 53, 54, 23, 24, 57, 58, 27, 28, \ + 61, 62, 31 } + +#define MASK_16 {0, 17, 18, 3, 4, 21, 22, 7, 8, 25, 26, 11, 12, 29, 30, 15} +#define MASK_8 {0, 9, 10, 3, 4, 13, 14, 7} +#define MASK_4 {0, 5, 6, 3} + +#define INDEX_32 vnx16qi +#define INDEX_16 vnx8hi +#define INDEX_8 vnx4si +#define INDEX_4 vnx2di + +#define PERMUTE(type, nunits) \ +type permute_##type (type x, type y) \ +{ \ + return __builtin_shuffle (x, y, (INDEX_##nunits) MASK_##nunits); \ +} + +PERMUTE(vnx16qi, 32) +PERMUTE(vnx8hi, 16) +PERMUTE(vnx4si, 8) +PERMUTE(vnx2di, 4) + +PERMUTE(vnx8hf, 16) +PERMUTE(vnx4sf, 8) +PERMUTE(vnx2df, 4) + +/* { dg-final { scan-assembler-not {\ttbl\t} } } */ + +/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.b, p[0-9]+, z[0-9]+\.b, z[0-9]+\.b\n} 1 } } */ +/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.h, p[0-9]+, z[0-9]+\.h, z[0-9]+\.h\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.s, p[0-9]+, z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.d, p[0-9]+, z[0-9]+\.d, z[0-9]+\.d\n} 2 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/sel_6.c b/gcc/testsuite/gcc.target/aarch64/sve/sel_6.c new file mode 100644 index 0000000..772938f --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/sel_6.c @@ -0,0 +1,42 @@ +/* { dg-do assemble { target aarch64_asm_sve_ok } } */ +/* { dg-options "-O2 -msve-vector-bits=256 --save-temps" } */ + +#include + +typedef int32_t vnx4si __attribute__((vector_size (32))); +typedef int64_t vnx2di __attribute__((vector_size (32))); + +typedef float vnx4sf __attribute__((vector_size (32))); +typedef double vnx2df __attribute__((vector_size (32))); + +/* Predicate vector: 1 0 0 0 ... */ + +#define MASK_32 { 0, 33, 34, 35, 4, 37, 38, 39, 8, 41, 42, 43, 12, \ + 45, 46, 47, 16, 49, 50, 51, 20, 53, 54, 55, 24, \ + 57, 58, 59, 28, 61, 62, 63 } + +#define MASK_16 {0, 17, 18, 19, 4, 21, 22, 23, 8, 25, 26, 27, 12, 29, 30, 31} +#define MASK_8 {0, 9, 10, 11, 4, 13, 14, 15} +#define MASK_4 {0, 5, 6, 7} + +#define INDEX_8 vnx4si +#define INDEX_4 vnx2di + +#define PERMUTE(type, nunits) \ +type permute_##type (type x, type y) \ +{ \ + return __builtin_shuffle (x, y, (INDEX_##nunits) MASK_##nunits); \ +} + +PERMUTE(vnx4si, 8) +PERMUTE(vnx2di, 4) + +PERMUTE(vnx4sf, 8) +PERMUTE(vnx2df, 4) + +/* { dg-final { scan-assembler-not {\ttbl\t} } } */ + +/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.s, p[0-9]+, z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.d, p[0-9]+, z[0-9]+\.d, z[0-9]+\.d\n} 2 } } */ + +/* { dg-final { scan-assembler-times {\tptrue\tp[0-9]+\.d, vl4\n} 2 } } */ -- cgit v1.1 From ae12842109f7095d2b653d4ede6e33c80d7d7fcd Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Thu, 22 Aug 2019 00:16:17 +0000 Subject: Daily bump. From-SVN: r274816 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 8810ce1..63ca370 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20190821 +20190822 -- cgit v1.1 From b1c9ec725da365165ce4c2fdf63daa33b7d86649 Mon Sep 17 00:00:00 2001 From: Prathamesh Kulkarni Date: Thu, 22 Aug 2019 08:48:42 +0000 Subject: aarch64-sve.md (vcond_mask): Add "@". 2019-08-22 Prathamesh Kulkarni * config/aarch64/aarch64-sve.md (vcond_mask): Add "@". From-SVN: r274817 --- gcc/ChangeLog | 4 ++++ gcc/config/aarch64/aarch64-sve.md | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8f08e39..603687e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,8 @@ 2019-08-22 Prathamesh Kulkarni + + * config/aarch64/aarch64-sve.md (vcond_mask): Add "@". + +2019-08-22 Prathamesh Kulkarni Richard Sandiford PR target/88839 diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md index ac65e69..f58353e 100644 --- a/gcc/config/aarch64/aarch64-sve.md +++ b/gcc/config/aarch64/aarch64-sve.md @@ -3927,7 +3927,7 @@ ;; vcond_mask operand order: true, false, mask ;; UNSPEC_SEL operand order: mask, true, false (as for VEC_COND_EXPR) ;; SEL operand order: mask, true, false -(define_expand "vcond_mask_" +(define_expand "@vcond_mask_" [(set (match_operand:SVE_ALL 0 "register_operand") (unspec:SVE_ALL [(match_operand: 3 "register_operand") -- cgit v1.1 From 391625888d4d97f9016ab9ac04acc55d81f0c26f Mon Sep 17 00:00:00 2001 From: Sylvia Taylor Date: Thu, 22 Aug 2019 11:28:26 +0000 Subject: [aarch64]: add intrinsics for vld1(q)_x4 and vst1(q)_x4 This patch adds the intrinsic functions for: - vld1__x4 - vst1__x4 - vld1q__x4 - vst1q__x4 Bootstrapped and tested on aarch64-none-linux-gnu. Committed on behalf of Sylvia Taylor. 2019-08-22 Sylvia Taylor * config/aarch64/aarch64-simd-builtins.def: (ld1x4): New. (st1x4): Likewise. * config/aarch64/aarch64-simd.md: (aarch64_ld1x4): New pattern. (aarch64_st1x4): Likewise. (aarch64_ld1_x4_): Likewise. (aarch64_st1_x4_): Likewise. * config/aarch64/arm_neon.h: (vld1_s8_x4): New function. (vld1q_s8_x4): Likewise. (vld1_s16_x4): Likewise. (vld1q_s16_x4): Likewise. (vld1_s32_x4): Likewise. (vld1q_s32_x4): Likewise. (vld1_u8_x4): Likewise. (vld1q_u8_x4): Likewise. (vld1_u16_x4): Likewise. (vld1q_u16_x4): Likewise. (vld1_u32_x4): Likewise. (vld1q_u32_x4): Likewise. (vld1_f16_x4): Likewise. (vld1q_f16_x4): Likewise. (vld1_f32_x4): Likewise. (vld1q_f32_x4): Likewise. (vld1_p8_x4): Likewise. (vld1q_p8_x4): Likewise. (vld1_p16_x4): Likewise. (vld1q_p16_x4): Likewise. (vld1_s64_x4): Likewise. (vld1_u64_x4): Likewise. (vld1_p64_x4): Likewise. (vld1q_s64_x4): Likewise. (vld1q_u64_x4): Likewise. (vld1q_p64_x4): Likewise. (vld1_f64_x4): Likewise. (vld1q_f64_x4): Likewise. (vst1_s8_x4): Likewise. (vst1q_s8_x4): Likewise. (vst1_s16_x4): Likewise. (vst1q_s16_x4): Likewise. (vst1_s32_x4): Likewise. (vst1q_s32_x4): Likewise. (vst1_u8_x4): Likewise. (vst1q_u8_x4): Likewise. (vst1_u16_x4): Likewise. (vst1q_u16_x4): Likewise. (vst1_u32_x4): Likewise. (vst1q_u32_x4): Likewise. (vst1_f16_x4): Likewise. (vst1q_f16_x4): Likewise. (vst1_f32_x4): Likewise. (vst1q_f32_x4): Likewise. (vst1_p8_x4): Likewise. (vst1q_p8_x4): Likewise. (vst1_p16_x4): Likewise. (vst1q_p16_x4): Likewise. (vst1_s64_x4): Likewise. (vst1_u64_x4): Likewise. (vst1_p64_x4): Likewise. (vst1q_s64_x4): Likewise. (vst1q_u64_x4): Likewise. (vst1q_p64_x4): Likewise. (vst1_f64_x4): Likewise. (vst1q_f64_x4): Likewise. * gcc.target/aarch64/advsimd-intrinsics/vld1x4.c: New test. * gcc.target/aarch64/advsimd-intrinsics/vst1x4.c: New test. From-SVN: r274820 --- gcc/ChangeLog | 68 +++ gcc/config/aarch64/aarch64-simd-builtins.def | 6 + gcc/config/aarch64/aarch64-simd.md | 44 ++ gcc/config/aarch64/arm_neon.h | 508 +++++++++++++++++++++ gcc/testsuite/ChangeLog | 5 + .../gcc.target/aarch64/advsimd-intrinsics/vld1x4.c | 83 ++++ .../gcc.target/aarch64/advsimd-intrinsics/vst1x4.c | 83 ++++ 7 files changed, 797 insertions(+) create mode 100644 gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vld1x4.c create mode 100644 gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vst1x4.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 603687e..271786f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,71 @@ +2019-08-22 Sylvia Taylor + + * config/aarch64/aarch64-simd-builtins.def: + (ld1x4): New. + (st1x4): Likewise. + * config/aarch64/aarch64-simd.md: + (aarch64_ld1x4): New pattern. + (aarch64_st1x4): Likewise. + (aarch64_ld1_x4_): Likewise. + (aarch64_st1_x4_): Likewise. + * config/aarch64/arm_neon.h: + (vld1_s8_x4): New function. + (vld1q_s8_x4): Likewise. + (vld1_s16_x4): Likewise. + (vld1q_s16_x4): Likewise. + (vld1_s32_x4): Likewise. + (vld1q_s32_x4): Likewise. + (vld1_u8_x4): Likewise. + (vld1q_u8_x4): Likewise. + (vld1_u16_x4): Likewise. + (vld1q_u16_x4): Likewise. + (vld1_u32_x4): Likewise. + (vld1q_u32_x4): Likewise. + (vld1_f16_x4): Likewise. + (vld1q_f16_x4): Likewise. + (vld1_f32_x4): Likewise. + (vld1q_f32_x4): Likewise. + (vld1_p8_x4): Likewise. + (vld1q_p8_x4): Likewise. + (vld1_p16_x4): Likewise. + (vld1q_p16_x4): Likewise. + (vld1_s64_x4): Likewise. + (vld1_u64_x4): Likewise. + (vld1_p64_x4): Likewise. + (vld1q_s64_x4): Likewise. + (vld1q_u64_x4): Likewise. + (vld1q_p64_x4): Likewise. + (vld1_f64_x4): Likewise. + (vld1q_f64_x4): Likewise. + (vst1_s8_x4): Likewise. + (vst1q_s8_x4): Likewise. + (vst1_s16_x4): Likewise. + (vst1q_s16_x4): Likewise. + (vst1_s32_x4): Likewise. + (vst1q_s32_x4): Likewise. + (vst1_u8_x4): Likewise. + (vst1q_u8_x4): Likewise. + (vst1_u16_x4): Likewise. + (vst1q_u16_x4): Likewise. + (vst1_u32_x4): Likewise. + (vst1q_u32_x4): Likewise. + (vst1_f16_x4): Likewise. + (vst1q_f16_x4): Likewise. + (vst1_f32_x4): Likewise. + (vst1q_f32_x4): Likewise. + (vst1_p8_x4): Likewise. + (vst1q_p8_x4): Likewise. + (vst1_p16_x4): Likewise. + (vst1q_p16_x4): Likewise. + (vst1_s64_x4): Likewise. + (vst1_u64_x4): Likewise. + (vst1_p64_x4): Likewise. + (vst1q_s64_x4): Likewise. + (vst1q_u64_x4): Likewise. + (vst1q_p64_x4): Likewise. + (vst1_f64_x4): Likewise. + (vst1q_f64_x4): Likewise. + 2019-08-22 Prathamesh Kulkarni * config/aarch64/aarch64-sve.md (vcond_mask): Add "@". diff --git a/gcc/config/aarch64/aarch64-simd-builtins.def b/gcc/config/aarch64/aarch64-simd-builtins.def index 01518fe..779111a 100644 --- a/gcc/config/aarch64/aarch64-simd-builtins.def +++ b/gcc/config/aarch64/aarch64-simd-builtins.def @@ -465,12 +465,18 @@ /* Implemented by aarch64_ld1x3. */ BUILTIN_VALLDIF (LOADSTRUCT, ld1x3, 0) + /* Implemented by aarch64_ld1x4. */ + BUILTIN_VALLDIF (LOADSTRUCT, ld1x4, 0) + /* Implemented by aarch64_st1x2. */ BUILTIN_VALLDIF (STORESTRUCT, st1x2, 0) /* Implemented by aarch64_st1x3. */ BUILTIN_VALLDIF (STORESTRUCT, st1x3, 0) + /* Implemented by aarch64_st1x4. */ + BUILTIN_VALLDIF (STORESTRUCT, st1x4, 0) + /* Implemented by fma4. */ BUILTIN_VHSDF (TERNOP, fma, 4) VAR1 (TERNOP, fma, 4, hf) diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index e33a009..6f7fb1c 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -5284,6 +5284,28 @@ [(set_attr "type" "neon_load1_3reg")] ) +(define_expand "aarch64_ld1x4" + [(match_operand:XI 0 "register_operand" "=w") + (match_operand:DI 1 "register_operand" "r") + (unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + "TARGET_SIMD" +{ + rtx mem = gen_rtx_MEM (XImode, operands[1]); + emit_insn (gen_aarch64_ld1_x4_ (operands[0], mem)); + DONE; +}) + +(define_insn "aarch64_ld1_x4_" + [(set (match_operand:XI 0 "register_operand" "=w") + (unspec:XI + [(match_operand:XI 1 "aarch64_simd_struct_operand" "Utv") + (unspec:VALLDIF [(const_int 4)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_LD1))] + "TARGET_SIMD" + "ld1\\t{%S0. - %V0.}, %1" + [(set_attr "type" "neon_load1_4reg")] +) + (define_expand "aarch64_st1x2" [(match_operand:DI 0 "register_operand") (match_operand:OI 1 "register_operand") @@ -5326,6 +5348,28 @@ [(set_attr "type" "neon_store1_3reg")] ) +(define_expand "aarch64_st1x4" + [(match_operand:DI 0 "register_operand" "") + (match_operand:XI 1 "register_operand" "") + (unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] + "TARGET_SIMD" +{ + rtx mem = gen_rtx_MEM (XImode, operands[0]); + emit_insn (gen_aarch64_st1_x4_ (mem, operands[1])); + DONE; +}) + +(define_insn "aarch64_st1_x4_" + [(set (match_operand:XI 0 "aarch64_simd_struct_operand" "=Utv") + (unspec:XI + [(match_operand:XI 1 "register_operand" "w") + (unspec:VALLDIF [(const_int 4)] UNSPEC_VSTRUCTDUMMY)] + UNSPEC_ST1))] + "TARGET_SIMD" + "st1\\t{%S1. - %V1.}, %0" + [(set_attr "type" "neon_store1_4reg")] +) + (define_insn "*aarch64_mov" [(set (match_operand:VSTRUCT 0 "aarch64_simd_nonimmediate_operand" "=w,Utv,w") (match_operand:VSTRUCT 1 "aarch64_simd_general_operand" " w,w,Utv"))] diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h index 314ef30..9ecc00c 100644 --- a/gcc/config/aarch64/arm_neon.h +++ b/gcc/config/aarch64/arm_neon.h @@ -17968,6 +17968,288 @@ vld1q_u64 (const uint64_t *a) __builtin_aarch64_ld1v2di ((const __builtin_aarch64_simd_di *) a); } +/* vld1(q)_x4. */ + +__extension__ extern __inline int8x8x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_s8_x4 (const int8_t *__a) +{ + union { int8x8x4_t __i; __builtin_aarch64_simd_xi __o; } __au; + __au.__o + = __builtin_aarch64_ld1x4v8qi ((const __builtin_aarch64_simd_qi *) __a); + return __au.__i; +} + +__extension__ extern __inline int8x16x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_s8_x4 (const int8_t *__a) +{ + union { int8x16x4_t __i; __builtin_aarch64_simd_xi __o; } __au; + __au.__o + = __builtin_aarch64_ld1x4v16qi ((const __builtin_aarch64_simd_qi *) __a); + return __au.__i; +} + +__extension__ extern __inline int16x4x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_s16_x4 (const int16_t *__a) +{ + union { int16x4x4_t __i; __builtin_aarch64_simd_xi __o; } __au; + __au.__o + = __builtin_aarch64_ld1x4v4hi ((const __builtin_aarch64_simd_hi *) __a); + return __au.__i; +} + +__extension__ extern __inline int16x8x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_s16_x4 (const int16_t *__a) +{ + union { int16x8x4_t __i; __builtin_aarch64_simd_xi __o; } __au; + __au.__o + = __builtin_aarch64_ld1x4v8hi ((const __builtin_aarch64_simd_hi *) __a); + return __au.__i; +} + +__extension__ extern __inline int32x2x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_s32_x4 (const int32_t *__a) +{ + union { int32x2x4_t __i; __builtin_aarch64_simd_xi __o; } __au; + __au.__o + = __builtin_aarch64_ld1x4v2si ((const __builtin_aarch64_simd_si *) __a); + return __au.__i; +} + +__extension__ extern __inline int32x4x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_s32_x4 (const int32_t *__a) +{ + union { int32x4x4_t __i; __builtin_aarch64_simd_xi __o; } __au; + __au.__o + = __builtin_aarch64_ld1x4v4si ((const __builtin_aarch64_simd_si *) __a); + return __au.__i; +} + +__extension__ extern __inline uint8x8x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_u8_x4 (const uint8_t *__a) +{ + union { uint8x8x4_t __i; __builtin_aarch64_simd_xi __o; } __au; + __au.__o + = __builtin_aarch64_ld1x4v8qi ((const __builtin_aarch64_simd_qi *) __a); + return __au.__i; +} + +__extension__ extern __inline uint8x16x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_u8_x4 (const uint8_t *__a) +{ + union { uint8x16x4_t __i; __builtin_aarch64_simd_xi __o; } __au; + __au.__o + = __builtin_aarch64_ld1x4v16qi ((const __builtin_aarch64_simd_qi *) __a); + return __au.__i; +} + +__extension__ extern __inline uint16x4x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_u16_x4 (const uint16_t *__a) +{ + union { uint16x4x4_t __i; __builtin_aarch64_simd_xi __o; } __au; + __au.__o + = __builtin_aarch64_ld1x4v4hi ((const __builtin_aarch64_simd_hi *) __a); + return __au.__i; +} + +__extension__ extern __inline uint16x8x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_u16_x4 (const uint16_t *__a) +{ + union { uint16x8x4_t __i; __builtin_aarch64_simd_xi __o; } __au; + __au.__o + = __builtin_aarch64_ld1x4v8hi ((const __builtin_aarch64_simd_hi *) __a); + return __au.__i; +} + +__extension__ extern __inline uint32x2x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_u32_x4 (const uint32_t *__a) +{ + union { uint32x2x4_t __i; __builtin_aarch64_simd_xi __o; } __au; + __au.__o + = __builtin_aarch64_ld1x4v2si ((const __builtin_aarch64_simd_si *) __a); + return __au.__i; +} + +__extension__ extern __inline uint32x4x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_u32_x4 (const uint32_t *__a) +{ + union { uint32x4x4_t __i; __builtin_aarch64_simd_xi __o; } __au; + __au.__o + = __builtin_aarch64_ld1x4v4si ((const __builtin_aarch64_simd_si *) __a); + return __au.__i; +} + +__extension__ extern __inline float16x4x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_f16_x4 (const float16_t *__a) +{ + union { float16x4x4_t __i; __builtin_aarch64_simd_xi __o; } __au; + __au.__o + = __builtin_aarch64_ld1x4v4hf ((const __builtin_aarch64_simd_hf *) __a); + return __au.__i; +} + +__extension__ extern __inline float16x8x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_f16_x4 (const float16_t *__a) +{ + union { float16x8x4_t __i; __builtin_aarch64_simd_xi __o; } __au; + __au.__o + = __builtin_aarch64_ld1x4v8hf ((const __builtin_aarch64_simd_hf *) __a); + return __au.__i; +} + +__extension__ extern __inline float32x2x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_f32_x4 (const float32_t *__a) +{ + union { float32x2x4_t __i; __builtin_aarch64_simd_xi __o; } __au; + __au.__o + = __builtin_aarch64_ld1x4v2sf ((const __builtin_aarch64_simd_sf *) __a); + return __au.__i; +} + +__extension__ extern __inline float32x4x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_f32_x4 (const float32_t *__a) +{ + union { float32x4x4_t __i; __builtin_aarch64_simd_xi __o; } __au; + __au.__o + = __builtin_aarch64_ld1x4v4sf ((const __builtin_aarch64_simd_sf *) __a); + return __au.__i; +} + +__extension__ extern __inline poly8x8x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_p8_x4 (const poly8_t *__a) +{ + union { poly8x8x4_t __i; __builtin_aarch64_simd_xi __o; } __au; + __au.__o + = __builtin_aarch64_ld1x4v8qi ((const __builtin_aarch64_simd_qi *) __a); + return __au.__i; +} + +__extension__ extern __inline poly8x16x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_p8_x4 (const poly8_t *__a) +{ + union { poly8x16x4_t __i; __builtin_aarch64_simd_xi __o; } __au; + __au.__o + = __builtin_aarch64_ld1x4v16qi ((const __builtin_aarch64_simd_qi *) __a); + return __au.__i; +} + +__extension__ extern __inline poly16x4x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_p16_x4 (const poly16_t *__a) +{ + union { poly16x4x4_t __i; __builtin_aarch64_simd_xi __o; } __au; + __au.__o + = __builtin_aarch64_ld1x4v4hi ((const __builtin_aarch64_simd_hi *) __a); + return __au.__i; +} + +__extension__ extern __inline poly16x8x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_p16_x4 (const poly16_t *__a) +{ + union { poly16x8x4_t __i; __builtin_aarch64_simd_xi __o; } __au; + __au.__o + = __builtin_aarch64_ld1x4v8hi ((const __builtin_aarch64_simd_hi *) __a); + return __au.__i; +} + +__extension__ extern __inline int64x1x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_s64_x4 (const int64_t *__a) +{ + union { int64x1x4_t __i; __builtin_aarch64_simd_xi __o; } __au; + __au.__o + = __builtin_aarch64_ld1x4di ((const __builtin_aarch64_simd_di *) __a); + return __au.__i; +} + +__extension__ extern __inline uint64x1x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_u64_x4 (const uint64_t *__a) +{ + union { uint64x1x4_t __i; __builtin_aarch64_simd_xi __o; } __au; + __au.__o + = __builtin_aarch64_ld1x4di ((const __builtin_aarch64_simd_di *) __a); + return __au.__i; +} + +__extension__ extern __inline poly64x1x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_p64_x4 (const poly64_t *__a) +{ + union { poly64x1x4_t __i; __builtin_aarch64_simd_xi __o; } __au; + __au.__o + = __builtin_aarch64_ld1x4di ((const __builtin_aarch64_simd_di *) __a); + return __au.__i; +} + +__extension__ extern __inline int64x2x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_s64_x4 (const int64_t *__a) +{ + union { int64x2x4_t __i; __builtin_aarch64_simd_xi __o; } __au; + __au.__o + = __builtin_aarch64_ld1x4v2di ((const __builtin_aarch64_simd_di *) __a); + return __au.__i; +} + +__extension__ extern __inline uint64x2x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_u64_x4 (const uint64_t *__a) +{ + union { uint64x2x4_t __i; __builtin_aarch64_simd_xi __o; } __au; + __au.__o + = __builtin_aarch64_ld1x4v2di ((const __builtin_aarch64_simd_di *) __a); + return __au.__i; +} + +__extension__ extern __inline poly64x2x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_p64_x4 (const poly64_t *__a) +{ + union { poly64x2x4_t __i; __builtin_aarch64_simd_xi __o; } __au; + __au.__o + = __builtin_aarch64_ld1x4v2di ((const __builtin_aarch64_simd_di *) __a); + return __au.__i; +} + +__extension__ extern __inline float64x1x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1_f64_x4 (const float64_t *__a) +{ + union { float64x1x4_t __i; __builtin_aarch64_simd_xi __o; } __au; + __au.__o + = __builtin_aarch64_ld1x4df ((const __builtin_aarch64_simd_df *) __a); + return __au.__i; +} + +__extension__ extern __inline float64x2x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vld1q_f64_x4 (const float64_t *__a) +{ + union { float64x2x4_t __i; __builtin_aarch64_simd_xi __o; } __au; + __au.__o + = __builtin_aarch64_ld1x4v2df ((const __builtin_aarch64_simd_df *) __a); + return __au.__i; +} + /* vld1_dup */ __extension__ extern __inline float16x4_t @@ -28596,6 +28878,232 @@ vst1q_p64_x3 (poly64_t * __a, poly64x2x3_t val) __builtin_aarch64_st1x3v2di ((__builtin_aarch64_simd_di *) __a, __o); } +/* vst1(q)_x4. */ + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_s8_x4 (int8_t * __a, int8x8x4_t val) +{ + union { int8x8x4_t __i; __builtin_aarch64_simd_xi __o; } __u = { val }; + __builtin_aarch64_st1x4v8qi ((__builtin_aarch64_simd_qi *) __a, __u.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_s8_x4 (int8_t * __a, int8x16x4_t val) +{ + union { int8x16x4_t __i; __builtin_aarch64_simd_xi __o; } __u = { val }; + __builtin_aarch64_st1x4v16qi ((__builtin_aarch64_simd_qi *) __a, __u.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_s16_x4 (int16_t * __a, int16x4x4_t val) +{ + union { int16x4x4_t __i; __builtin_aarch64_simd_xi __o; } __u = { val }; + __builtin_aarch64_st1x4v4hi ((__builtin_aarch64_simd_hi *) __a, __u.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_s16_x4 (int16_t * __a, int16x8x4_t val) +{ + union { int16x8x4_t __i; __builtin_aarch64_simd_xi __o; } __u = { val }; + __builtin_aarch64_st1x4v8hi ((__builtin_aarch64_simd_hi *) __a, __u.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_s32_x4 (int32_t * __a, int32x2x4_t val) +{ + union { int32x2x4_t __i; __builtin_aarch64_simd_xi __o; } __u = { val }; + __builtin_aarch64_st1x4v2si ((__builtin_aarch64_simd_si *) __a, __u.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_s32_x4 (int32_t * __a, int32x4x4_t val) +{ + union { int32x4x4_t __i; __builtin_aarch64_simd_xi __o; } __u = { val }; + __builtin_aarch64_st1x4v4si ((__builtin_aarch64_simd_si *) __a, __u.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_u8_x4 (uint8_t * __a, uint8x8x4_t val) +{ + union { uint8x8x4_t __i; __builtin_aarch64_simd_xi __o; } __u = { val }; + __builtin_aarch64_st1x4v8qi ((__builtin_aarch64_simd_qi *) __a, __u.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_u8_x4 (uint8_t * __a, uint8x16x4_t val) +{ + union { uint8x16x4_t __i; __builtin_aarch64_simd_xi __o; } __u = { val }; + __builtin_aarch64_st1x4v16qi ((__builtin_aarch64_simd_qi *) __a, __u.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_u16_x4 (uint16_t * __a, uint16x4x4_t val) +{ + union { uint16x4x4_t __i; __builtin_aarch64_simd_xi __o; } __u = { val }; + __builtin_aarch64_st1x4v4hi ((__builtin_aarch64_simd_hi *) __a, __u.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_u16_x4 (uint16_t * __a, uint16x8x4_t val) +{ + union { uint16x8x4_t __i; __builtin_aarch64_simd_xi __o; } __u = { val }; + __builtin_aarch64_st1x4v8hi ((__builtin_aarch64_simd_hi *) __a, __u.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_u32_x4 (uint32_t * __a, uint32x2x4_t val) +{ + union { uint32x2x4_t __i; __builtin_aarch64_simd_xi __o; } __u = { val }; + __builtin_aarch64_st1x4v2si ((__builtin_aarch64_simd_si *) __a, __u.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_u32_x4 (uint32_t * __a, uint32x4x4_t val) +{ + union { uint32x4x4_t __i; __builtin_aarch64_simd_xi __o; } __u = { val }; + __builtin_aarch64_st1x4v4si ((__builtin_aarch64_simd_si *) __a, __u.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_f16_x4 (float16_t * __a, float16x4x4_t val) +{ + union { float16x4x4_t __i; __builtin_aarch64_simd_xi __o; } __u = { val }; + __builtin_aarch64_st1x4v4hf ((__builtin_aarch64_simd_hf *) __a, __u.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_f16_x4 (float16_t * __a, float16x8x4_t val) +{ + union { float16x8x4_t __i; __builtin_aarch64_simd_xi __o; } __u = { val }; + __builtin_aarch64_st1x4v8hf ((__builtin_aarch64_simd_hf *) __a, __u.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_f32_x4 (float32_t * __a, float32x2x4_t val) +{ + union { float32x2x4_t __i; __builtin_aarch64_simd_xi __o; } __u = { val }; + __builtin_aarch64_st1x4v2sf ((__builtin_aarch64_simd_sf *) __a, __u.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_f32_x4 (float32_t * __a, float32x4x4_t val) +{ + union { float32x4x4_t __i; __builtin_aarch64_simd_xi __o; } __u = { val }; + __builtin_aarch64_st1x4v4sf ((__builtin_aarch64_simd_sf *) __a, __u.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_p8_x4 (poly8_t * __a, poly8x8x4_t val) +{ + union { poly8x8x4_t __i; __builtin_aarch64_simd_xi __o; } __u = { val }; + __builtin_aarch64_st1x4v8qi ((__builtin_aarch64_simd_qi *) __a, __u.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_p8_x4 (poly8_t * __a, poly8x16x4_t val) +{ + union { poly8x16x4_t __i; __builtin_aarch64_simd_xi __o; } __u = { val }; + __builtin_aarch64_st1x4v16qi ((__builtin_aarch64_simd_qi *) __a, __u.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_p16_x4 (poly16_t * __a, poly16x4x4_t val) +{ + union { poly16x4x4_t __i; __builtin_aarch64_simd_xi __o; } __u = { val }; + __builtin_aarch64_st1x4v4hi ((__builtin_aarch64_simd_hi *) __a, __u.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_p16_x4 (poly16_t * __a, poly16x8x4_t val) +{ + union { poly16x8x4_t __i; __builtin_aarch64_simd_xi __o; } __u = { val }; + __builtin_aarch64_st1x4v8hi ((__builtin_aarch64_simd_hi *) __a, __u.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_s64_x4 (int64_t * __a, int64x1x4_t val) +{ + union { int64x1x4_t __i; __builtin_aarch64_simd_xi __o; } __u = { val }; + __builtin_aarch64_st1x4di ((__builtin_aarch64_simd_di *) __a, __u.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_u64_x4 (uint64_t * __a, uint64x1x4_t val) +{ + union { uint64x1x4_t __i; __builtin_aarch64_simd_xi __o; } __u = { val }; + __builtin_aarch64_st1x4di ((__builtin_aarch64_simd_di *) __a, __u.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_p64_x4 (poly64_t * __a, poly64x1x4_t val) +{ + union { poly64x1x4_t __i; __builtin_aarch64_simd_xi __o; } __u = { val }; + __builtin_aarch64_st1x4di ((__builtin_aarch64_simd_di *) __a, __u.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_s64_x4 (int64_t * __a, int64x2x4_t val) +{ + union { int64x2x4_t __i; __builtin_aarch64_simd_xi __o; } __u = { val }; + __builtin_aarch64_st1x4v2di ((__builtin_aarch64_simd_di *) __a, __u.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_u64_x4 (uint64_t * __a, uint64x2x4_t val) +{ + union { uint64x2x4_t __i; __builtin_aarch64_simd_xi __o; } __u = { val }; + __builtin_aarch64_st1x4v2di ((__builtin_aarch64_simd_di *) __a, __u.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_p64_x4 (poly64_t * __a, poly64x2x4_t val) +{ + union { poly64x2x4_t __i; __builtin_aarch64_simd_xi __o; } __u = { val }; + __builtin_aarch64_st1x4v2di ((__builtin_aarch64_simd_di *) __a, __u.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1_f64_x4 (float64_t * __a, float64x1x4_t val) +{ + union { float64x1x4_t __i; __builtin_aarch64_simd_xi __o; } __u = { val }; + __builtin_aarch64_st1x4df ((__builtin_aarch64_simd_df *) __a, __u.__o); +} + +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vst1q_f64_x4 (float64_t * __a, float64x2x4_t val) +{ + union { float64x2x4_t __i; __builtin_aarch64_simd_xi __o; } __u = { val }; + __builtin_aarch64_st1x4v2df ((__builtin_aarch64_simd_df *) __a, __u.__o); +} + /* vstn */ __extension__ extern __inline void diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0d141dc..03fd832 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-08-22 Sylvia Taylor + + * gcc.target/aarch64/advsimd-intrinsics/vld1x4.c: New test. + * gcc.target/aarch64/advsimd-intrinsics/vst1x4.c: New test. + 2019-08-22 Prathamesh Kulkarni Richard Sandiford diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vld1x4.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vld1x4.c new file mode 100644 index 0000000..451a0af --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vld1x4.c @@ -0,0 +1,83 @@ +/* We haven't implemented these intrinsics for arm yet. */ +/* { dg-xfail-if "" { arm*-*-* } } */ +/* { dg-do run } */ +/* { dg-options "-O3" } */ + +#include +#include "arm-neon-ref.h" + +extern void abort (void); + +#define TESTMETH(BASE, ELTS, SUFFIX) \ +int __attribute__ ((noinline)) \ +test_vld1##SUFFIX##_x4 () \ +{ \ + BASE##_t data[ELTS * 4]; \ + BASE##_t temp[ELTS * 4]; \ + BASE##x##ELTS##x##4##_t vectors; \ + int i,j; \ + for (i = 0; i < ELTS * 4; i++) \ + data [i] = (BASE##_t) 4*i; \ + asm volatile ("" : : : "memory"); \ + vectors = vld1##SUFFIX##_x4 (data); \ + vst1##SUFFIX (temp, vectors.val[0]); \ + vst1##SUFFIX (&temp[ELTS], vectors.val[1]); \ + vst1##SUFFIX (&temp[ELTS * 2], vectors.val[2]); \ + vst1##SUFFIX (&temp[ELTS * 3], vectors.val[3]); \ + asm volatile ("" : : : "memory"); \ + for (j = 0; j < ELTS * 4; j++) \ + if (temp[j] != data[j]) \ + return 1; \ + return 0; \ +} + +#define VARIANTS_1(VARIANT) \ +VARIANT (uint8, 8, _u8) \ +VARIANT (uint16, 4, _u16) \ +VARIANT (uint32, 2, _u32) \ +VARIANT (uint64, 1, _u64) \ +VARIANT (int8, 8, _s8) \ +VARIANT (int16, 4, _s16) \ +VARIANT (int32, 2, _s32) \ +VARIANT (int64, 1, _s64) \ +VARIANT (poly8, 8, _p8) \ +VARIANT (poly16, 4, _p16) \ +VARIANT (poly64, 1, _p64) \ +VARIANT (float16, 4, _f16) \ +VARIANT (float32, 2, _f32) \ +VARIANT (uint8, 16, q_u8) \ +VARIANT (uint16, 8, q_u16) \ +VARIANT (uint32, 4, q_u32) \ +VARIANT (uint64, 2, q_u64) \ +VARIANT (int8, 16, q_s8) \ +VARIANT (int16, 8, q_s16) \ +VARIANT (int32, 4, q_s32) \ +VARIANT (int64, 2, q_s64) \ +VARIANT (poly8, 16, q_p8) \ +VARIANT (poly16, 8, q_p16) \ +VARIANT (poly64, 2, q_p64) \ +VARIANT (float16, 8, q_f16) \ +VARIANT (float32, 4, q_f32) + +#ifdef __aarch64__ +#define VARIANTS(VARIANT) VARIANTS_1(VARIANT) \ +VARIANT (float64, 1, _f64) \ +VARIANT (float64, 2, q_f64) +#else +#define VARIANTS(VARIANT) VARIANTS_1(VARIANT) +#endif + +/* Tests of vld1_x4 and vld1q_x4. */ +VARIANTS (TESTMETH) + +#define CHECKS(BASE, ELTS, SUFFIX) \ + if (test_vld1##SUFFIX##_x4 () != 0) \ + fprintf (stderr, "test_vld1##SUFFIX##_x4"); + +int +main (int argc, char **argv) +{ + VARIANTS (CHECKS) + + return 0; +} diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vst1x4.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vst1x4.c new file mode 100644 index 0000000..1f17b53 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vst1x4.c @@ -0,0 +1,83 @@ +/* We haven't implemented these intrinsics for arm yet. */ +/* { dg-xfail-if "" { arm*-*-* } } */ +/* { dg-do run } */ +/* { dg-options "-O3" } */ + +#include +#include "arm-neon-ref.h" + +extern void abort (void); + +#define TESTMETH(BASE, ELTS, SUFFIX) \ +int __attribute__ ((noinline)) \ +test_vst1##SUFFIX##_x4 () \ +{ \ + BASE##_t data[ELTS * 4]; \ + BASE##_t temp[ELTS * 4]; \ + BASE##x##ELTS##x##4##_t vectors; \ + int i,j; \ + for (i = 0; i < ELTS * 4; i++) \ + data [i] = (BASE##_t) 4*i; \ + asm volatile ("" : : : "memory"); \ + vectors.val[0] = vld1##SUFFIX (data); \ + vectors.val[1] = vld1##SUFFIX (&data[ELTS]); \ + vectors.val[2] = vld1##SUFFIX (&data[ELTS * 2]); \ + vectors.val[3] = vld1##SUFFIX (&data[ELTS * 3]); \ + vst1##SUFFIX##_x4 (temp, vectors); \ + asm volatile ("" : : : "memory"); \ + for (j = 0; j < ELTS * 4; j++) \ + if (temp[j] != data[j]) \ + return 1; \ + return 0; \ +} + +#define VARIANTS_1(VARIANT) \ +VARIANT (uint8, 8, _u8) \ +VARIANT (uint16, 4, _u16) \ +VARIANT (uint32, 2, _u32) \ +VARIANT (uint64, 1, _u64) \ +VARIANT (int8, 8, _s8) \ +VARIANT (int16, 4, _s16) \ +VARIANT (int32, 2, _s32) \ +VARIANT (int64, 1, _s64) \ +VARIANT (poly8, 8, _p8) \ +VARIANT (poly16, 4, _p16) \ +VARIANT (poly64, 1, _p64) \ +VARIANT (float16, 4, _f16) \ +VARIANT (float32, 2, _f32) \ +VARIANT (uint8, 16, q_u8) \ +VARIANT (uint16, 8, q_u16) \ +VARIANT (uint32, 4, q_u32) \ +VARIANT (uint64, 2, q_u64) \ +VARIANT (int8, 16, q_s8) \ +VARIANT (int16, 8, q_s16) \ +VARIANT (int32, 4, q_s32) \ +VARIANT (int64, 2, q_s64) \ +VARIANT (poly8, 16, q_p8) \ +VARIANT (poly16, 8, q_p16) \ +VARIANT (poly64, 2, q_p64) \ +VARIANT (float16, 8, q_f16) \ +VARIANT (float32, 4, q_f32) + +#ifdef __aarch64__ +#define VARIANTS(VARIANT) VARIANTS_1(VARIANT) \ +VARIANT (float64, 1, _f64) \ +VARIANT (float64, 2, q_f64) +#else +#define VARIANTS(VARIANT) VARIANTS_1(VARIANT) +#endif + +/* Tests of vst1_x4 and vst1q_x4. */ +VARIANTS (TESTMETH) + +#define CHECKS(BASE, ELTS, SUFFIX) \ + if (test_vst1##SUFFIX##_x4 () != 0) \ + fprintf (stderr, "test_vst1##SUFFIX##_x4"); + +int +main (int argc, char **argv) +{ + VARIANTS (CHECKS) + + return 0; +} -- cgit v1.1 From 203ef022c6a0477c33a8cf4a65890e33d0912cf0 Mon Sep 17 00:00:00 2001 From: Richard Earnshaw Date: Thu, 22 Aug 2019 14:40:52 +0000 Subject: [Arm] Add 16-bit thumb alternatives to iorsi3_compare0[_scratch] The iorsi3_compare0 and iorsi3_compare0_scratch patterns can make use of the 16-bit thumb orrs instruction if suitable registers are allocated. This patch adds the alternative to allow this to happen. * config/arm/arm.md (iorsi3_compare0): Add alternative for 16-bit thumb insn. (iorsi3_compare0_scratch): Likewise. From-SVN: r274822 --- gcc/ChangeLog | 6 ++++++ gcc/config/arm/arm.md | 26 ++++++++++++++++---------- 2 files changed, 22 insertions(+), 10 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 271786f..93e8420 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-08-22 Richard Earnshaw + + * config/arm/arm.md (iorsi3_compare0): Add alternative for 16-bit thumb + insn. + (iorsi3_compare0_scratch): Likewise. + 2019-08-22 Sylvia Taylor * config/aarch64/aarch64-simd-builtins.def: diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 50e1b90..4ba246c 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -3339,27 +3339,33 @@ (define_insn "*iorsi3_compare0" [(set (reg:CC_NOOV CC_REGNUM) - (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r") - (match_operand:SI 2 "arm_rhs_operand" "I,r")) - (const_int 0))) - (set (match_operand:SI 0 "s_register_operand" "=r,r") + (compare:CC_NOOV + (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r") + (match_operand:SI 2 "arm_rhs_operand" "I,l,r")) + (const_int 0))) + (set (match_operand:SI 0 "s_register_operand" "=r,l,r") (ior:SI (match_dup 1) (match_dup 2)))] "TARGET_32BIT" "orrs%?\\t%0, %1, %2" [(set_attr "conds" "set") - (set_attr "type" "logics_imm,logics_reg")] + (set_attr "arch" "*,t2,*") + (set_attr "length" "4,2,4") + (set_attr "type" "logics_imm,logics_reg,logics_reg")] ) (define_insn "*iorsi3_compare0_scratch" [(set (reg:CC_NOOV CC_REGNUM) - (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r") - (match_operand:SI 2 "arm_rhs_operand" "I,r")) - (const_int 0))) - (clobber (match_scratch:SI 0 "=r,r"))] + (compare:CC_NOOV + (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r") + (match_operand:SI 2 "arm_rhs_operand" "I,l,r")) + (const_int 0))) + (clobber (match_scratch:SI 0 "=r,l,r"))] "TARGET_32BIT" "orrs%?\\t%0, %1, %2" [(set_attr "conds" "set") - (set_attr "type" "logics_imm,logics_reg")] + (set_attr "arch" "*,t2,*") + (set_attr "length" "4,2,4") + (set_attr "type" "logics_imm,logics_reg,logics_reg")] ) (define_expand "xordi3" -- cgit v1.1 From cdfc0e863a03698a80c74896cbdc9f5c8c652e64 Mon Sep 17 00:00:00 2001 From: Wilco Dijkstra Date: Thu, 22 Aug 2019 14:52:24 +0000 Subject: [ARM] Cleanup logical DImode operations Cleanup the logical DImode operations since the current implementation is way too complicated. Thumb-1, Thumb-2, VFP/Neon and iwMMXt all work differently, resulting in a bewildering number of expansions, patterns and splits across several md files. All this complexity is counterproductive and results in inefficient code. A much simpler approach is to split these operations early in the expander so that optimizations and register allocation are applied on the 32-bit halves. Codegeneration is unchanged on Thumb-1 and Arm/Thumb-2 without Neon or iwMMXt (which already expand these instructions early). With Neon these changes save ~1000 instructions from the PR77308 testcase, mostly by significantly reducing register pressure and spilling. Bootstrap OK on arm-none-linux-gnueabihf --with-cpu=cortex-a57 gcc/ * config/arm/arm.md (split and/eor/ior): Remove Neon check. (split not): Add DImode not splitter. (anddi3): Remove pattern. (anddi3_insn): Likewise. (anddi_zesidi_di): Likewise. (anddi_sesdi_di): Likewise. (anddi_notdi_di): Likewise. (anddi_notzesidi_di): Likewise. (anddi_notsesidi_di): Likewise. (iordi3): Likewise. (iordi3_insn): Likewise. (iordi_zesidi_di): Likewise. (iordi_sesidi_di): Likewise. (xordi3): Likewise. (xordi3_insn): Likewise. (xordi_sesidi_di): Likewise. (xordi_zesidi_di): Likewise. (one_cmpldi2): Likewise. (one_cmpldi2_insn): Likewise. * config/arm/constraints.md: Remove De, Df, Dg constraints. * config/arm/iwmmxt.md (iwmmxt_iordi3): Remove general register alternative. (iwmmxt_xordi3): Likewise. (iwmmxt_anddi3): Likewise. * config/arm/neon.md (orndi3_neon): Remove pattern. (anddi_notdi_di): Likewise. * config/arm/predicates.md (arm_anddi_operand_neon): Remove. (arm_iordi_operand_neon): Likewise. (arm_xordi_operand_neon): Likewise. * config/arm/thumb2.md(iordi_notdi_di): Remove pattern. (iordi_notzesidi_di): Likewise. (iordi_notdi_zesidi): Likewise. (iordi_notsesidi_di): Likewise. From-SVN: r274823 --- gcc/ChangeLog | 36 +++ gcc/config/arm/arm.md | 511 +----------------------------------------- gcc/config/arm/constraints.md | 18 -- gcc/config/arm/iwmmxt.md | 45 ++-- gcc/config/arm/neon.md | 54 ----- gcc/config/arm/predicates.md | 17 -- gcc/config/arm/thumb2.md | 97 -------- 7 files changed, 65 insertions(+), 713 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 93e8420..e6057c4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,39 @@ +2019-08-22 Wilco Dijkstra + + * config/arm/arm.md (split and/eor/ior): Remove Neon check. + (split not): Add DImode not splitter. + (anddi3): Remove pattern. + (anddi3_insn): Likewise. + (anddi_zesidi_di): Likewise. + (anddi_sesdi_di): Likewise. + (anddi_notdi_di): Likewise. + (anddi_notzesidi_di): Likewise. + (anddi_notsesidi_di): Likewise. + (iordi3): Likewise. + (iordi3_insn): Likewise. + (iordi_zesidi_di): Likewise. + (iordi_sesidi_di): Likewise. + (xordi3): Likewise. + (xordi3_insn): Likewise. + (xordi_sesidi_di): Likewise. + (xordi_zesidi_di): Likewise. + (one_cmpldi2): Likewise. + (one_cmpldi2_insn): Likewise. + * config/arm/constraints.md: Remove De, Df, Dg constraints. + * config/arm/iwmmxt.md (iwmmxt_iordi3): Remove general register + alternative. + (iwmmxt_xordi3): Likewise. + (iwmmxt_anddi3): Likewise. + * config/arm/neon.md (orndi3_neon): Remove pattern. + (anddi_notdi_di): Likewise. + * config/arm/predicates.md (arm_anddi_operand_neon): Remove. + (arm_iordi_operand_neon): Likewise. + (arm_xordi_operand_neon): Likewise. + * config/arm/thumb2.md(iordi_notdi_di): Remove pattern. + (iordi_notzesidi_di): Likewise. + (iordi_notdi_zesidi): Likewise. + (iordi_notsesidi_di): Likewise. + 2019-08-22 Richard Earnshaw * config/arm/arm.md (iorsi3_compare0): Add alternative for 16-bit thumb diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 4ba246c..eb5838d 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -2198,19 +2198,17 @@ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" "") -;; Boolean and,ior,xor insns -;; Split up double word logical operations - -;; Split up simple DImode logical operations. Simply perform the logical +;; Split DImode and, ior, xor operations. Simply perform the logical ;; operation on the upper and lower halves of the registers. +;; This is needed for atomic operations in arm_split_atomic_op. +;; Avoid splitting IWMMXT instructions. (define_split [(set (match_operand:DI 0 "s_register_operand" "") (match_operator:DI 6 "logical_binary_operator" [(match_operand:DI 1 "s_register_operand" "") (match_operand:DI 2 "s_register_operand" "")]))] "TARGET_32BIT && reload_completed - && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0]))) && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))" [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)])) (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))] @@ -2225,167 +2223,21 @@ }" ) +;; Split DImode not (needed for atomic operations in arm_split_atomic_op). +;; Unconditionally split since there is no SIMD DImode NOT pattern. (define_split - [(set (match_operand:DI 0 "s_register_operand" "") - (match_operator:DI 6 "logical_binary_operator" - [(sign_extend:DI (match_operand:SI 2 "s_register_operand" "")) - (match_operand:DI 1 "s_register_operand" "")]))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)])) - (set (match_dup 3) (match_op_dup:SI 6 - [(ashiftrt:SI (match_dup 2) (const_int 31)) - (match_dup 4)]))] - " - { - operands[3] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - operands[4] = gen_highpart (SImode, operands[1]); - operands[1] = gen_lowpart (SImode, operands[1]); - operands[5] = gen_highpart (SImode, operands[2]); - operands[2] = gen_lowpart (SImode, operands[2]); - }" -) - -;; The zero extend of operand 2 means we can just copy the high part of -;; operand1 into operand0. -(define_split - [(set (match_operand:DI 0 "s_register_operand" "") - (ior:DI - (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")) - (match_operand:DI 1 "s_register_operand" "")))] - "TARGET_32BIT && operands[0] != operands[1] && reload_completed" - [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2))) - (set (match_dup 3) (match_dup 4))] - " - { - operands[4] = gen_highpart (SImode, operands[1]); - operands[3] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - operands[1] = gen_lowpart (SImode, operands[1]); - }" -) - -;; The zero extend of operand 2 means we can just copy the high part of -;; operand1 into operand0. -(define_split - [(set (match_operand:DI 0 "s_register_operand" "") - (xor:DI - (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")) - (match_operand:DI 1 "s_register_operand" "")))] - "TARGET_32BIT && operands[0] != operands[1] && reload_completed" - [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2))) - (set (match_dup 3) (match_dup 4))] - " - { - operands[4] = gen_highpart (SImode, operands[1]); - operands[3] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - operands[1] = gen_lowpart (SImode, operands[1]); - }" -) - -(define_expand "anddi3" - [(set (match_operand:DI 0 "s_register_operand") - (and:DI (match_operand:DI 1 "s_register_operand") - (match_operand:DI 2 "neon_inv_logic_op2")))] - "TARGET_32BIT" - " - if (!TARGET_NEON && !TARGET_IWMMXT) - { - rtx low = simplify_gen_binary (AND, SImode, - gen_lowpart (SImode, operands[1]), - gen_lowpart (SImode, operands[2])); - rtx high = simplify_gen_binary (AND, SImode, - gen_highpart (SImode, operands[1]), - gen_highpart_mode (SImode, DImode, - operands[2])); - - emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low)); - emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high)); - - DONE; - } - /* Otherwise expand pattern as above. */ - " -) - -(define_insn_and_split "*anddi3_insn" - [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w") - (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0") - (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))] - "TARGET_32BIT && !TARGET_IWMMXT" -{ - switch (which_alternative) - { - case 0: /* fall through */ - case 6: return "vand\t%P0, %P1, %P2"; - case 1: /* fall through */ - case 7: return neon_output_logic_immediate ("vand", &operands[2], - DImode, 1, VALID_NEON_QREG_MODE (DImode)); - case 2: - case 3: - case 4: - case 5: /* fall through */ - return "#"; - default: gcc_unreachable (); - } -} - "TARGET_32BIT && !TARGET_IWMMXT && reload_completed - && !(IS_VFP_REGNUM (REGNO (operands[0])))" - [(set (match_dup 3) (match_dup 4)) - (set (match_dup 5) (match_dup 6))] - " - { - operands[3] = gen_lowpart (SImode, operands[0]); - operands[5] = gen_highpart (SImode, operands[0]); - - operands[4] = simplify_gen_binary (AND, SImode, - gen_lowpart (SImode, operands[1]), - gen_lowpart (SImode, operands[2])); - operands[6] = simplify_gen_binary (AND, SImode, - gen_highpart (SImode, operands[1]), - gen_highpart_mode (SImode, DImode, operands[2])); - - }" - [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\ - multiple,multiple,neon_logic,neon_logic") - (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*, - avoid_neon_for_64bits,avoid_neon_for_64bits") - (set_attr "length" "*,*,8,8,8,8,*,*") - ] -) - -(define_insn_and_split "*anddi_zesidi_di" - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") - (and:DI (zero_extend:DI - (match_operand:SI 2 "s_register_operand" "r,r")) - (match_operand:DI 1 "s_register_operand" "0,r")))] + [(set (match_operand:DI 0 "s_register_operand") + (not:DI (match_operand:DI 1 "s_register_operand")))] "TARGET_32BIT" - "#" - "TARGET_32BIT && reload_completed" - ; The zero extend of operand 2 clears the high word of the output - ; operand. - [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2))) - (set (match_dup 3) (const_int 0))] + [(set (match_dup 0) (not:SI (match_dup 1))) + (set (match_dup 2) (not:SI (match_dup 3)))] " { - operands[3] = gen_highpart (SImode, operands[0]); + operands[2] = gen_highpart (SImode, operands[0]); operands[0] = gen_lowpart (SImode, operands[0]); + operands[3] = gen_highpart (SImode, operands[1]); operands[1] = gen_lowpart (SImode, operands[1]); }" - [(set_attr "length" "8") - (set_attr "type" "multiple")] -) - -(define_insn "*anddi_sesdi_di" - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") - (and:DI (sign_extend:DI - (match_operand:SI 2 "s_register_operand" "r,r")) - (match_operand:DI 1 "s_register_operand" "0,r")))] - "TARGET_32BIT" - "#" - [(set_attr "length" "8") - (set_attr "type" "multiple")] ) (define_expand "andsi3" @@ -2967,105 +2819,6 @@ (set_attr "type" "bfm")] ) -; constants for op 2 will never be given to these patterns. -(define_insn_and_split "*anddi_notdi_di" - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") - (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r")) - (match_operand:DI 2 "s_register_operand" "r,0")))] - "TARGET_32BIT" - "#" - "TARGET_32BIT && reload_completed - && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0]))) - && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))" - [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2))) - (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))] - " - { - operands[3] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - operands[4] = gen_highpart (SImode, operands[1]); - operands[1] = gen_lowpart (SImode, operands[1]); - operands[5] = gen_highpart (SImode, operands[2]); - operands[2] = gen_lowpart (SImode, operands[2]); - }" - [(set_attr "length" "8") - (set_attr "predicable" "yes") - (set_attr "type" "multiple")] -) - -(define_insn_and_split "*anddi_notzesidi_di" - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") - (and:DI (not:DI (zero_extend:DI - (match_operand:SI 2 "s_register_operand" "r,r"))) - (match_operand:DI 1 "s_register_operand" "0,?r")))] - "TARGET_32BIT" - "@ - bic%?\\t%Q0, %Q1, %2 - #" - ; (not (zero_extend ...)) allows us to just copy the high word from - ; operand1 to operand0. - "TARGET_32BIT - && reload_completed - && operands[0] != operands[1]" - [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1))) - (set (match_dup 3) (match_dup 4))] - " - { - operands[3] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - operands[4] = gen_highpart (SImode, operands[1]); - operands[1] = gen_lowpart (SImode, operands[1]); - }" - [(set_attr "length" "4,8") - (set_attr "predicable" "yes") - (set_attr "type" "multiple")] -) - -(define_insn_and_split "*anddi_notdi_zesidi" - [(set (match_operand:DI 0 "s_register_operand" "=r") - (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r")) - (zero_extend:DI - (match_operand:SI 1 "s_register_operand" "r"))))] - "TARGET_32BIT" - "#" - "TARGET_32BIT && reload_completed" - [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1))) - (set (match_dup 3) (const_int 0))] - " - { - operands[3] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - operands[2] = gen_lowpart (SImode, operands[2]); - }" - [(set_attr "length" "8") - (set_attr "predicable" "yes") - (set_attr "type" "multiple")] -) - -(define_insn_and_split "*anddi_notsesidi_di" - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") - (and:DI (not:DI (sign_extend:DI - (match_operand:SI 2 "s_register_operand" "r,r"))) - (match_operand:DI 1 "s_register_operand" "0,r")))] - "TARGET_32BIT" - "#" - "TARGET_32BIT && reload_completed" - [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1))) - (set (match_dup 3) (and:SI (not:SI - (ashiftrt:SI (match_dup 2) (const_int 31))) - (match_dup 4)))] - " - { - operands[3] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - operands[4] = gen_highpart (SImode, operands[1]); - operands[1] = gen_lowpart (SImode, operands[1]); - }" - [(set_attr "length" "8") - (set_attr "predicable" "yes") - (set_attr "type" "multiple")] -) - (define_insn "andsi_notsi_si" [(set (match_operand:SI 0 "s_register_operand" "=r") (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r")) @@ -3165,101 +2918,6 @@ (set_attr "type" "logics_shift_reg")] ) -(define_expand "iordi3" - [(set (match_operand:DI 0 "s_register_operand") - (ior:DI (match_operand:DI 1 "s_register_operand") - (match_operand:DI 2 "neon_logic_op2")))] - "TARGET_32BIT" - " - if (!TARGET_NEON && !TARGET_IWMMXT) - { - rtx low = simplify_gen_binary (IOR, SImode, - gen_lowpart (SImode, operands[1]), - gen_lowpart (SImode, operands[2])); - rtx high = simplify_gen_binary (IOR, SImode, - gen_highpart (SImode, operands[1]), - gen_highpart_mode (SImode, DImode, - operands[2])); - - emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low)); - emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high)); - - DONE; - } - /* Otherwise expand pattern as above. */ - " -) - -(define_insn_and_split "*iordi3_insn" - [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w") - (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0") - (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))] - "TARGET_32BIT && !TARGET_IWMMXT" - { - switch (which_alternative) - { - case 0: /* fall through */ - case 6: return "vorr\t%P0, %P1, %P2"; - case 1: /* fall through */ - case 7: return neon_output_logic_immediate ("vorr", &operands[2], - DImode, 0, VALID_NEON_QREG_MODE (DImode)); - case 2: - case 3: - case 4: - case 5: - return "#"; - default: gcc_unreachable (); - } - } - "TARGET_32BIT && !TARGET_IWMMXT && reload_completed - && !(IS_VFP_REGNUM (REGNO (operands[0])))" - [(set (match_dup 3) (match_dup 4)) - (set (match_dup 5) (match_dup 6))] - " - { - operands[3] = gen_lowpart (SImode, operands[0]); - operands[5] = gen_highpart (SImode, operands[0]); - - operands[4] = simplify_gen_binary (IOR, SImode, - gen_lowpart (SImode, operands[1]), - gen_lowpart (SImode, operands[2])); - operands[6] = simplify_gen_binary (IOR, SImode, - gen_highpart (SImode, operands[1]), - gen_highpart_mode (SImode, DImode, operands[2])); - - }" - [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\ - multiple,neon_logic,neon_logic") - (set_attr "length" "*,*,8,8,8,8,*,*") - (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")] -) - -(define_insn "*iordi_zesidi_di" - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") - (ior:DI (zero_extend:DI - (match_operand:SI 2 "s_register_operand" "r,r")) - (match_operand:DI 1 "s_register_operand" "0,?r")))] - "TARGET_32BIT" - "@ - orr%?\\t%Q0, %Q1, %2 - #" - [(set_attr "length" "4,8") - (set_attr "predicable" "yes") - (set_attr "type" "logic_reg,multiple")] -) - -(define_insn "*iordi_sesidi_di" - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") - (ior:DI (sign_extend:DI - (match_operand:SI 2 "s_register_operand" "r,r")) - (match_operand:DI 1 "s_register_operand" "0,r")))] - "TARGET_32BIT" - "#" - [(set_attr "length" "8") - (set_attr "predicable" "yes") - (set_attr "type" "multiple")] -) - (define_expand "iorsi3" [(set (match_operand:SI 0 "s_register_operand") (ior:SI (match_operand:SI 1 "s_register_operand") @@ -3368,103 +3026,6 @@ (set_attr "type" "logics_imm,logics_reg,logics_reg")] ) -(define_expand "xordi3" - [(set (match_operand:DI 0 "s_register_operand") - (xor:DI (match_operand:DI 1 "s_register_operand") - (match_operand:DI 2 "arm_xordi_operand")))] - "TARGET_32BIT" - { - /* The iWMMXt pattern for xordi3 accepts only register operands but we want - to reuse this expander for all TARGET_32BIT targets so just force the - constants into a register. Unlike for the anddi3 and iordi3 there are - no NEON instructions that take an immediate. */ - if (TARGET_IWMMXT && !REG_P (operands[2])) - operands[2] = force_reg (DImode, operands[2]); - if (!TARGET_NEON && !TARGET_IWMMXT) - { - rtx low = simplify_gen_binary (XOR, SImode, - gen_lowpart (SImode, operands[1]), - gen_lowpart (SImode, operands[2])); - rtx high = simplify_gen_binary (XOR, SImode, - gen_highpart (SImode, operands[1]), - gen_highpart_mode (SImode, DImode, - operands[2])); - - emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low)); - emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high)); - - DONE; - } - /* Otherwise expand pattern as above. */ - } -) - -(define_insn_and_split "*xordi3_insn" - [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w") - (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w") - (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))] - "TARGET_32BIT && !TARGET_IWMMXT" -{ - switch (which_alternative) - { - case 1: - case 2: - case 3: - case 4: /* fall through */ - return "#"; - case 0: /* fall through */ - case 5: return "veor\t%P0, %P1, %P2"; - default: gcc_unreachable (); - } -} - "TARGET_32BIT && !TARGET_IWMMXT && reload_completed - && !(IS_VFP_REGNUM (REGNO (operands[0])))" - [(set (match_dup 3) (match_dup 4)) - (set (match_dup 5) (match_dup 6))] - " - { - operands[3] = gen_lowpart (SImode, operands[0]); - operands[5] = gen_highpart (SImode, operands[0]); - - operands[4] = simplify_gen_binary (XOR, SImode, - gen_lowpart (SImode, operands[1]), - gen_lowpart (SImode, operands[2])); - operands[6] = simplify_gen_binary (XOR, SImode, - gen_highpart (SImode, operands[1]), - gen_highpart_mode (SImode, DImode, operands[2])); - - }" - [(set_attr "length" "*,8,8,8,8,*") - (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic") - (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")] -) - -(define_insn "*xordi_zesidi_di" - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") - (xor:DI (zero_extend:DI - (match_operand:SI 2 "s_register_operand" "r,r")) - (match_operand:DI 1 "s_register_operand" "0,?r")))] - "TARGET_32BIT" - "@ - eor%?\\t%Q0, %Q1, %2 - #" - [(set_attr "length" "4,8") - (set_attr "predicable" "yes") - (set_attr "type" "logic_reg")] -) - -(define_insn "*xordi_sesidi_di" - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") - (xor:DI (sign_extend:DI - (match_operand:SI 2 "s_register_operand" "r,r")) - (match_operand:DI 1 "s_register_operand" "0,r")))] - "TARGET_32BIT" - "#" - [(set_attr "length" "8") - (set_attr "predicable" "yes") - (set_attr "type" "multiple")] -) - (define_expand "xorsi3" [(set (match_operand:SI 0 "s_register_operand") (xor:SI (match_operand:SI 1 "s_register_operand") @@ -5054,56 +4615,6 @@ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" "") -(define_expand "one_cmpldi2" - [(set (match_operand:DI 0 "s_register_operand") - (not:DI (match_operand:DI 1 "s_register_operand")))] - "TARGET_32BIT" - " - if (!TARGET_NEON && !TARGET_IWMMXT) - { - rtx low = simplify_gen_unary (NOT, SImode, - gen_lowpart (SImode, operands[1]), - SImode); - rtx high = simplify_gen_unary (NOT, SImode, - gen_highpart_mode (SImode, DImode, - operands[1]), - SImode); - - emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low)); - emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high)); - - DONE; - } - /* Otherwise expand pattern as above. */ - " -) - -(define_insn_and_split "*one_cmpldi2_insn" - [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w") - (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))] - "TARGET_32BIT" - "@ - vmvn\t%P0, %P1 - # - # - vmvn\t%P0, %P1" - "TARGET_32BIT && reload_completed - && arm_general_register_operand (operands[0], DImode)" - [(set (match_dup 0) (not:SI (match_dup 1))) - (set (match_dup 2) (not:SI (match_dup 3)))] - " - { - operands[2] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - operands[3] = gen_highpart (SImode, operands[1]); - operands[1] = gen_lowpart (SImode, operands[1]); - }" - [(set_attr "length" "*,8,8,*") - (set_attr "predicable" "no,yes,yes,no") - (set_attr "type" "neon_move,multiple,multiple,neon_move") - (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")] -) - (define_expand "one_cmplsi2" [(set (match_operand:SI 0 "s_register_operand") (not:SI (match_operand:SI 1 "s_register_operand")))] diff --git a/gcc/config/arm/constraints.md b/gcc/config/arm/constraints.md index d4a4c59..b76de81 100644 --- a/gcc/config/arm/constraints.md +++ b/gcc/config/arm/constraints.md @@ -273,24 +273,6 @@ (and (match_code "const_int") (match_test "TARGET_32BIT && const_ok_for_dimode_op (ival, PLUS)"))) -(define_constraint "De" - "@internal - In ARM/Thumb-2 state a const_int that can be used by insn anddi." - (and (match_code "const_int") - (match_test "TARGET_32BIT && const_ok_for_dimode_op (ival, AND)"))) - -(define_constraint "Df" - "@internal - In ARM/Thumb-2 state a const_int that can be used by insn iordi." - (and (match_code "const_int") - (match_test "TARGET_32BIT && const_ok_for_dimode_op (ival, IOR)"))) - -(define_constraint "Dg" - "@internal - In ARM/Thumb-2 state a const_int that can be used by insn xordi." - (and (match_code "const_int") - (match_test "TARGET_32BIT && const_ok_for_dimode_op (ival, XOR)"))) - (define_constraint "Di" "@internal In ARM/Thumb-2 state a const_int or const_double where both the high diff --git a/gcc/config/arm/iwmmxt.md b/gcc/config/arm/iwmmxt.md index 310019a..86158ea 100644 --- a/gcc/config/arm/iwmmxt.md +++ b/gcc/config/arm/iwmmxt.md @@ -55,45 +55,36 @@ ) (define_insn "iwmmxt_iordi3" - [(set (match_operand:DI 0 "register_operand" "=y,?&r,?&r") - (ior:DI (match_operand:DI 1 "register_operand" "%y,0,r") - (match_operand:DI 2 "register_operand" "y,r,r")))] + [(set (match_operand:DI 0 "register_operand" "=y") + (ior:DI (match_operand:DI 1 "register_operand" "%y") + (match_operand:DI 2 "register_operand" "y")))] "TARGET_REALLY_IWMMXT" - "@ - wor%?\\t%0, %1, %2 - # - #" + "wor%?\\t%0, %1, %2" [(set_attr "predicable" "yes") - (set_attr "length" "4,8,8") - (set_attr "type" "wmmx_wor,*,*")] + (set_attr "length" "4") + (set_attr "type" "wmmx_wor")] ) (define_insn "iwmmxt_xordi3" - [(set (match_operand:DI 0 "register_operand" "=y,?&r,?&r") - (xor:DI (match_operand:DI 1 "register_operand" "%y,0,r") - (match_operand:DI 2 "register_operand" "y,r,r")))] + [(set (match_operand:DI 0 "register_operand" "=y") + (xor:DI (match_operand:DI 1 "register_operand" "%y") + (match_operand:DI 2 "register_operand" "y")))] "TARGET_REALLY_IWMMXT" - "@ - wxor%?\\t%0, %1, %2 - # - #" + "wxor%?\\t%0, %1, %2" [(set_attr "predicable" "yes") - (set_attr "length" "4,8,8") - (set_attr "type" "wmmx_wxor,*,*")] + (set_attr "length" "4") + (set_attr "type" "wmmx_wxor")] ) (define_insn "iwmmxt_anddi3" - [(set (match_operand:DI 0 "register_operand" "=y,?&r,?&r") - (and:DI (match_operand:DI 1 "register_operand" "%y,0,r") - (match_operand:DI 2 "register_operand" "y,r,r")))] + [(set (match_operand:DI 0 "register_operand" "=y") + (and:DI (match_operand:DI 1 "register_operand" "%y") + (match_operand:DI 2 "register_operand" "y")))] "TARGET_REALLY_IWMMXT" - "@ - wand%?\\t%0, %1, %2 - # - #" + "wand%?\\t%0, %1, %2" [(set_attr "predicable" "yes") - (set_attr "length" "4,8,8") - (set_attr "type" "wmmx_wand,*,*")] + (set_attr "length" "4") + (set_attr "type" "wmmx_wand")] ) (define_insn "iwmmxt_nanddi3" diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md index 6333e0e..ef73c77 100644 --- a/gcc/config/arm/neon.md +++ b/gcc/config/arm/neon.md @@ -838,46 +838,6 @@ [(set_attr "type" "neon_logic")] ) -;; TODO: investigate whether we should disable -;; this and bicdi3_neon for the A8 in line with the other -;; changes above. -(define_insn_and_split "orndi3_neon" - [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?&r") - (ior:DI (not:DI (match_operand:DI 2 "s_register_operand" "w,0,0,r")) - (match_operand:DI 1 "s_register_operand" "w,r,r,0")))] - "TARGET_NEON" - "@ - vorn\t%P0, %P1, %P2 - # - # - #" - "reload_completed && - (TARGET_NEON && !(IS_VFP_REGNUM (REGNO (operands[0]))))" - [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1))) - (set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))] - " - { - if (TARGET_THUMB2) - { - operands[3] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - operands[4] = gen_highpart (SImode, operands[2]); - operands[2] = gen_lowpart (SImode, operands[2]); - operands[5] = gen_highpart (SImode, operands[1]); - operands[1] = gen_lowpart (SImode, operands[1]); - } - else - { - emit_insn (gen_one_cmpldi2 (operands[0], operands[2])); - emit_insn (gen_iordi3 (operands[0], operands[1], operands[0])); - DONE; - } - }" - [(set_attr "type" "neon_logic,multiple,multiple,multiple") - (set_attr "length" "*,16,8,8") - (set_attr "arch" "any,a,t2,t2")] -) - (define_insn "bic3_neon" [(set (match_operand:VDQ 0 "s_register_operand" "=w") (and:VDQ (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w")) @@ -887,20 +847,6 @@ [(set_attr "type" "neon_logic")] ) -;; Compare to *anddi_notdi_di. -(define_insn "bicdi3_neon" - [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r") - (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "w,r,0")) - (match_operand:DI 1 "s_register_operand" "w,0,r")))] - "TARGET_NEON" - "@ - vbic\t%P0, %P1, %P2 - # - #" - [(set_attr "type" "neon_logic,multiple,multiple") - (set_attr "length" "*,8,8")] -) - (define_insn "xor3" [(set (match_operand:VDQ 0 "s_register_operand" "=w") (xor:VDQ (match_operand:VDQ 1 "s_register_operand" "w") diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md index 25f8647..59dc2e8 100644 --- a/gcc/config/arm/predicates.md +++ b/gcc/config/arm/predicates.md @@ -201,23 +201,6 @@ (ior (match_operand 0 "arm_rhs_operand") (match_operand 0 "arm_neg_immediate_operand"))) -(define_predicate "arm_anddi_operand_neon" - (ior (match_operand 0 "s_register_operand") - (and (match_code "const_int") - (match_test "const_ok_for_dimode_op (INTVAL (op), AND)")) - (match_operand 0 "neon_inv_logic_op2"))) - -(define_predicate "arm_iordi_operand_neon" - (ior (match_operand 0 "s_register_operand") - (and (match_code "const_int") - (match_test "const_ok_for_dimode_op (INTVAL (op), IOR)")) - (match_operand 0 "neon_logic_op2"))) - -(define_predicate "arm_xordi_operand" - (ior (match_operand 0 "s_register_operand") - (and (match_code "const_int") - (match_test "const_ok_for_dimode_op (INTVAL (op), XOR)")))) - (define_predicate "arm_adddi_operand" (ior (match_operand 0 "s_register_operand") (and (match_code "const_int") diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md index 608ea70..6ccc875 100644 --- a/gcc/config/arm/thumb2.md +++ b/gcc/config/arm/thumb2.md @@ -1476,103 +1476,6 @@ (set_attr "type" "alu_sreg")] ) -; Constants for op 2 will never be given to these patterns. -(define_insn_and_split "*iordi_notdi_di" - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") - (ior:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r")) - (match_operand:DI 2 "s_register_operand" "r,0")))] - "TARGET_THUMB2" - "#" - "TARGET_THUMB2 && reload_completed" - [(set (match_dup 0) (ior:SI (not:SI (match_dup 1)) (match_dup 2))) - (set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))] - " - { - operands[3] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - operands[4] = gen_highpart (SImode, operands[1]); - operands[1] = gen_lowpart (SImode, operands[1]); - operands[5] = gen_highpart (SImode, operands[2]); - operands[2] = gen_lowpart (SImode, operands[2]); - }" - [(set_attr "length" "8") - (set_attr "predicable" "yes") - (set_attr "predicable_short_it" "no") - (set_attr "type" "multiple")] -) - -(define_insn_and_split "*iordi_notzesidi_di" - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") - (ior:DI (not:DI (zero_extend:DI - (match_operand:SI 2 "s_register_operand" "r,r"))) - (match_operand:DI 1 "s_register_operand" "0,?r")))] - "TARGET_THUMB2" - "#" - ; (not (zero_extend...)) means operand0 will always be 0xffffffff - "TARGET_THUMB2 && reload_completed" - [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1))) - (set (match_dup 3) (const_int -1))] - " - { - operands[3] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - operands[1] = gen_lowpart (SImode, operands[1]); - }" - [(set_attr "length" "4,8") - (set_attr "predicable" "yes") - (set_attr "predicable_short_it" "no") - (set_attr "type" "multiple")] -) - -(define_insn_and_split "*iordi_notdi_zesidi" - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") - (ior:DI (not:DI (match_operand:DI 2 "s_register_operand" "0,?r")) - (zero_extend:DI - (match_operand:SI 1 "s_register_operand" "r,r"))))] - "TARGET_THUMB2" - "#" - "TARGET_THUMB2 && reload_completed" - [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1))) - (set (match_dup 3) (not:SI (match_dup 4)))] - " - { - operands[3] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - operands[1] = gen_lowpart (SImode, operands[1]); - operands[4] = gen_highpart (SImode, operands[2]); - operands[2] = gen_lowpart (SImode, operands[2]); - }" - [(set_attr "length" "8") - (set_attr "predicable" "yes") - (set_attr "predicable_short_it" "no") - (set_attr "type" "multiple")] -) - -(define_insn_and_split "*iordi_notsesidi_di" - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") - (ior:DI (not:DI (sign_extend:DI - (match_operand:SI 2 "s_register_operand" "r,r"))) - (match_operand:DI 1 "s_register_operand" "0,r")))] - "TARGET_THUMB2" - "#" - "TARGET_THUMB2 && reload_completed" - [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1))) - (set (match_dup 3) (ior:SI (not:SI - (ashiftrt:SI (match_dup 2) (const_int 31))) - (match_dup 4)))] - " - { - operands[3] = gen_highpart (SImode, operands[0]); - operands[0] = gen_lowpart (SImode, operands[0]); - operands[4] = gen_highpart (SImode, operands[1]); - operands[1] = gen_lowpart (SImode, operands[1]); - }" - [(set_attr "length" "8") - (set_attr "predicable" "yes") - (set_attr "predicable_short_it" "no") - (set_attr "type" "multiple")] -) - (define_insn "*orsi_notsi_si" [(set (match_operand:SI 0 "s_register_operand" "=r") (ior:SI (not:SI (match_operand:SI 2 "s_register_operand" "r")) -- cgit v1.1 From 5c7c6c5fc13503b2b71aee34d57370ae03531809 Mon Sep 17 00:00:00 2001 From: Wilco Dijkstra Date: Thu, 22 Aug 2019 15:06:37 +0000 Subject: [ARM] Cleanup DImode shifts Like the logical operations, expand all shifts early rather than only sometimes. The Neon shift expansions are never emitted (not even with -fneon-for-64bits), so they are not useful. So all the late expansions and Neon shift patterns can be removed, and shifts are more optimized as a result. Since some extend patterns use Neon DImode shifts, remove the Neon extend variants and related splits. A simple example now generates the same efficient code after this patch with -mfpu=neon and -mfpu=vfp (previously just the fact of having Neon enabled resulted inefficient code for no reason). unsigned long long f(unsigned long long x, unsigned long long y) { return x & (y >> 33); } Before: strd r4, r5, [sp, #-8]! lsr r4, r3, #1 mov r5, #0 and r1, r1, r5 and r0, r0, r4 ldrd r4, r5, [sp] add sp, sp, #8 bx lr After: and r0, r0, r3, lsr #1 mov r1, #0 bx lr Bootstrap and regress OK on arm-none-linux-gnueabihf --with-cpu=cortex-a57 gcc/ * config/arm/iterators.md (qhs_extenddi_cstr): Update. (qhs_extenddi_cstr): Likewise. * config/arm/arm.md (ashldi3): Always expand early. (ashlsi3): Likewise. (ashrsi3): Likewise. (zero_extenddi2): Remove Neon variants. (extenddi2): Likewise. * config/arm/neon.md (ashldi3_neon_noclobber): Remove. (signed_shift_di3_neon): Likewise. (unsigned_shift_di3_neon): Likewise. (ashrdi3_neon_imm_noclobber): Likewise. (lshrdi3_neon_imm_noclobber): Likewise. (di3_neon): Likewise. (split extend): Remove DI extend split patterns. gcc/testsuite/ * gcc.target/arm/neon-extend-1.c: Remove test. * gcc.target/arm/neon-extend-2.c: Remove test. From-SVN: r274824 --- gcc/ChangeLog | 17 ++ gcc/config/arm/arm.md | 126 +++------------ gcc/config/arm/iterators.md | 4 +- gcc/config/arm/neon.md | 229 --------------------------- gcc/testsuite/ChangeLog | 5 + gcc/testsuite/gcc.target/arm/neon-extend-1.c | 13 -- gcc/testsuite/gcc.target/arm/neon-extend-2.c | 13 -- 7 files changed, 48 insertions(+), 359 deletions(-) delete mode 100644 gcc/testsuite/gcc.target/arm/neon-extend-1.c delete mode 100644 gcc/testsuite/gcc.target/arm/neon-extend-2.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e6057c4..6c1335e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,22 @@ 2019-08-22 Wilco Dijkstra + * config/arm/iterators.md (qhs_extenddi_cstr): Update. + (qhs_extenddi_cstr): Likewise. + * config/arm/arm.md (ashldi3): Always expand early. + (ashlsi3): Likewise. + (ashrsi3): Likewise. + (zero_extenddi2): Remove Neon variants. + (extenddi2): Likewise. + * config/arm/neon.md (ashldi3_neon_noclobber): Remove. + (signed_shift_di3_neon): Likewise. + (unsigned_shift_di3_neon): Likewise. + (ashrdi3_neon_imm_noclobber): Likewise. + (lshrdi3_neon_imm_noclobber): Likewise. + (di3_neon): Likewise. + (split extend): Remove DI extend split patterns. + +2019-08-22 Wilco Dijkstra + * config/arm/arm.md (split and/eor/ior): Remove Neon check. (split not): Add DImode not splitter. (anddi3): Remove pattern. diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index eb5838d..4f6e3aa 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -3621,44 +3621,14 @@ (define_expand "ashldi3" [(set (match_operand:DI 0 "s_register_operand") (ashift:DI (match_operand:DI 1 "s_register_operand") - (match_operand:SI 2 "general_operand")))] + (match_operand:SI 2 "reg_or_int_operand")))] "TARGET_32BIT" " - if (TARGET_NEON) - { - /* Delay the decision whether to use NEON or core-regs until - register allocation. */ - emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2])); - DONE; - } - else - { - /* Only the NEON case can handle in-memory shift counts. */ - if (!reg_or_int_operand (operands[2], SImode)) - operands[2] = force_reg (SImode, operands[2]); - } - - if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT) - ; /* No special preparation statements; expand pattern as above. */ - else - { - rtx scratch1, scratch2; - - /* Ideally we should use iwmmxt here if we could know that operands[1] - ends up already living in an iwmmxt register. Otherwise it's - cheaper to have the alternate code being generated than moving - values to iwmmxt regs and back. */ - - /* Expand operation using core-registers. - 'FAIL' would achieve the same thing, but this is a bit smarter. */ - scratch1 = gen_reg_rtx (SImode); - scratch2 = gen_reg_rtx (SImode); - arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1], - operands[2], scratch1, scratch2); - DONE; - } - " -) + arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1], + operands[2], gen_reg_rtx (SImode), + gen_reg_rtx (SImode)); + DONE; +") (define_expand "ashlsi3" [(set (match_operand:SI 0 "s_register_operand") @@ -3681,35 +3651,11 @@ (match_operand:SI 2 "reg_or_int_operand")))] "TARGET_32BIT" " - if (TARGET_NEON) - { - /* Delay the decision whether to use NEON or core-regs until - register allocation. */ - emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2])); - DONE; - } - - if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT) - ; /* No special preparation statements; expand pattern as above. */ - else - { - rtx scratch1, scratch2; - - /* Ideally we should use iwmmxt here if we could know that operands[1] - ends up already living in an iwmmxt register. Otherwise it's - cheaper to have the alternate code being generated than moving - values to iwmmxt regs and back. */ - - /* Expand operation using core-registers. - 'FAIL' would achieve the same thing, but this is a bit smarter. */ - scratch1 = gen_reg_rtx (SImode); - scratch2 = gen_reg_rtx (SImode); - arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1], - operands[2], scratch1, scratch2); - DONE; - } - " -) + arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1], + operands[2], gen_reg_rtx (SImode), + gen_reg_rtx (SImode)); + DONE; +") (define_expand "ashrsi3" [(set (match_operand:SI 0 "s_register_operand") @@ -3729,35 +3675,11 @@ (match_operand:SI 2 "reg_or_int_operand")))] "TARGET_32BIT" " - if (TARGET_NEON) - { - /* Delay the decision whether to use NEON or core-regs until - register allocation. */ - emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2])); - DONE; - } - - if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT) - ; /* No special preparation statements; expand pattern as above. */ - else - { - rtx scratch1, scratch2; - - /* Ideally we should use iwmmxt here if we could know that operands[1] - ends up already living in an iwmmxt register. Otherwise it's - cheaper to have the alternate code being generated than moving - values to iwmmxt regs and back. */ - - /* Expand operation using core-registers. - 'FAIL' would achieve the same thing, but this is a bit smarter. */ - scratch1 = gen_reg_rtx (SImode); - scratch2 = gen_reg_rtx (SImode); - arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1], - operands[2], scratch1, scratch2); - DONE; - } - " -) + arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1], + operands[2], gen_reg_rtx (SImode), + gen_reg_rtx (SImode)); + DONE; +") (define_expand "lshrsi3" [(set (match_operand:SI 0 "s_register_operand") @@ -4782,30 +4704,30 @@ ;; Zero and sign extension instructions. (define_insn "zero_extenddi2" - [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w") + [(set (match_operand:DI 0 "s_register_operand" "=r,?r") (zero_extend:DI (match_operand:QHSI 1 "" "")))] "TARGET_32BIT " "#" - [(set_attr "length" "8,4,8,8") - (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits") + [(set_attr "length" "4,8") + (set_attr "arch" "*,*") (set_attr "ce_count" "2") (set_attr "predicable" "yes") - (set_attr "type" "multiple,mov_reg,multiple,multiple")] + (set_attr "type" "mov_reg,multiple")] ) (define_insn "extenddi2" - [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w") + [(set (match_operand:DI 0 "s_register_operand" "=r,?r,?r") (sign_extend:DI (match_operand:QHSI 1 "" "")))] "TARGET_32BIT " "#" - [(set_attr "length" "8,4,8,8,8") + [(set_attr "length" "4,8,8") (set_attr "ce_count" "2") (set_attr "shift" "1") (set_attr "predicable" "yes") - (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits") - (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")] + (set_attr "arch" "*,a,t") + (set_attr "type" "mov_reg,multiple,multiple")] ) ;; Splits for all extensions to DImode diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md index eca1663..fa6f0c0 100644 --- a/gcc/config/arm/iterators.md +++ b/gcc/config/arm/iterators.md @@ -741,8 +741,8 @@ (define_mode_attr qhs_extenddi_op [(SI "s_register_operand") (HI "nonimmediate_operand") (QI "arm_reg_or_extendqisi_mem_op")]) -(define_mode_attr qhs_extenddi_cstr [(SI "r,0,r,r,r") (HI "r,0,rm,rm,r") (QI "r,0,rUq,rm,r")]) -(define_mode_attr qhs_zextenddi_cstr [(SI "r,0,r,r") (HI "r,0,rm,r") (QI "r,0,rm,r")]) +(define_mode_attr qhs_extenddi_cstr [(SI "0,r,r") (HI "0,rm,rm") (QI "0,rUq,rm")]) +(define_mode_attr qhs_zextenddi_cstr [(SI "0,r") (HI "0,rm") (QI "0,rm")]) ;; Mode attributes used for fixed-point support. (define_mode_attr qaddsub_suf [(V4UQQ "8") (V2UHQ "16") (UQQ "8") (UHQ "16") diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md index ef73c77..757f2c0 100644 --- a/gcc/config/arm/neon.md +++ b/gcc/config/arm/neon.md @@ -1135,173 +1135,6 @@ [(set_attr "type" "neon_load1_1reg,neon_from_gp")] ) -(define_insn "ashldi3_neon_noclobber" - [(set (match_operand:DI 0 "s_register_operand" "=w,w") - (ashift:DI (match_operand:DI 1 "s_register_operand" " w,w") - (match_operand:DI 2 "reg_or_int_operand" " i,w")))] - "TARGET_NEON && reload_completed - && (!CONST_INT_P (operands[2]) - || (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 64))" - "@ - vshl.u64\t%P0, %P1, %2 - vshl.u64\t%P0, %P1, %P2" - [(set_attr "type" "neon_shift_imm, neon_shift_reg")] -) - -(define_insn_and_split "ashldi3_neon" - [(set (match_operand:DI 0 "s_register_operand" "= w, w, &r, r, &r, ?w,?w") - (ashift:DI (match_operand:DI 1 "s_register_operand" " 0w, w, 0r, 0, r, 0w, w") - (match_operand:SI 2 "general_operand" "rUm, i, r, i, i,rUm, i"))) - (clobber (match_scratch:SI 3 "= X, X, &r, X, X, X, X")) - (clobber (match_scratch:SI 4 "= X, X, &r, X, X, X, X")) - (clobber (match_scratch:DI 5 "=&w, X, X, X, X, &w, X")) - (clobber (reg:CC_C CC_REGNUM))] - "TARGET_NEON" - "#" - "TARGET_NEON && reload_completed" - [(const_int 0)] - " - { - if (IS_VFP_REGNUM (REGNO (operands[0]))) - { - if (CONST_INT_P (operands[2])) - { - if (INTVAL (operands[2]) < 1) - { - emit_insn (gen_movdi (operands[0], operands[1])); - DONE; - } - else if (INTVAL (operands[2]) > 63) - operands[2] = gen_rtx_CONST_INT (VOIDmode, 63); - } - else - { - emit_insn (gen_neon_load_count (operands[5], operands[2])); - operands[2] = operands[5]; - } - - /* Ditch the unnecessary clobbers. */ - emit_insn (gen_ashldi3_neon_noclobber (operands[0], operands[1], - operands[2])); - } - else - { - /* The shift expanders support either full overlap or no overlap. */ - gcc_assert (!reg_overlap_mentioned_p (operands[0], operands[1]) - || REGNO (operands[0]) == REGNO (operands[1])); - - arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1], - operands[2], operands[3], operands[4]); - } - DONE; - }" - [(set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits") - (set_attr "opt" "*,*,speed,speed,speed,*,*") - (set_attr "type" "multiple")] -) - -; The shift amount needs to be negated for right-shifts -(define_insn "signed_shift_di3_neon" - [(set (match_operand:DI 0 "s_register_operand" "=w") - (unspec:DI [(match_operand:DI 1 "s_register_operand" " w") - (match_operand:DI 2 "s_register_operand" " w")] - UNSPEC_ASHIFT_SIGNED))] - "TARGET_NEON && reload_completed" - "vshl.s64\t%P0, %P1, %P2" - [(set_attr "type" "neon_shift_reg")] -) - -; The shift amount needs to be negated for right-shifts -(define_insn "unsigned_shift_di3_neon" - [(set (match_operand:DI 0 "s_register_operand" "=w") - (unspec:DI [(match_operand:DI 1 "s_register_operand" " w") - (match_operand:DI 2 "s_register_operand" " w")] - UNSPEC_ASHIFT_UNSIGNED))] - "TARGET_NEON && reload_completed" - "vshl.u64\t%P0, %P1, %P2" - [(set_attr "type" "neon_shift_reg")] -) - -(define_insn "ashrdi3_neon_imm_noclobber" - [(set (match_operand:DI 0 "s_register_operand" "=w") - (ashiftrt:DI (match_operand:DI 1 "s_register_operand" " w") - (match_operand:DI 2 "const_int_operand" " i")))] - "TARGET_NEON && reload_completed - && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 64" - "vshr.s64\t%P0, %P1, %2" - [(set_attr "type" "neon_shift_imm")] -) - -(define_insn "lshrdi3_neon_imm_noclobber" - [(set (match_operand:DI 0 "s_register_operand" "=w") - (lshiftrt:DI (match_operand:DI 1 "s_register_operand" " w") - (match_operand:DI 2 "const_int_operand" " i")))] - "TARGET_NEON && reload_completed - && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 64" - "vshr.u64\t%P0, %P1, %2" - [(set_attr "type" "neon_shift_imm")] -) - -;; ashrdi3_neon -;; lshrdi3_neon -(define_insn_and_split "di3_neon" - [(set (match_operand:DI 0 "s_register_operand" "= w, w, &r, r, &r,?w,?w") - (RSHIFTS:DI (match_operand:DI 1 "s_register_operand" " 0w, w, 0r, 0, r,0w, w") - (match_operand:SI 2 "reg_or_int_operand" " r, i, r, i, i, r, i"))) - (clobber (match_scratch:SI 3 "=2r, X, &r, X, X,2r, X")) - (clobber (match_scratch:SI 4 "= X, X, &r, X, X, X, X")) - (clobber (match_scratch:DI 5 "=&w, X, X, X, X,&w, X")) - (clobber (reg:CC CC_REGNUM))] - "TARGET_NEON" - "#" - "TARGET_NEON && reload_completed" - [(const_int 0)] - " - { - if (IS_VFP_REGNUM (REGNO (operands[0]))) - { - if (CONST_INT_P (operands[2])) - { - if (INTVAL (operands[2]) < 1) - { - emit_insn (gen_movdi (operands[0], operands[1])); - DONE; - } - else if (INTVAL (operands[2]) > 64) - operands[2] = gen_rtx_CONST_INT (VOIDmode, 64); - - /* Ditch the unnecessary clobbers. */ - emit_insn (gen_di3_neon_imm_noclobber (operands[0], - operands[1], - operands[2])); - } - else - { - /* We must use a negative left-shift. */ - emit_insn (gen_negsi2 (operands[3], operands[2])); - emit_insn (gen_neon_load_count (operands[5], operands[3])); - emit_insn (gen__shift_di3_neon (operands[0], operands[1], - operands[5])); - } - } - else - { - /* The shift expanders support either full overlap or no overlap. */ - gcc_assert (!reg_overlap_mentioned_p (operands[0], operands[1]) - || REGNO (operands[0]) == REGNO (operands[1])); - - /* This clobbers CC (ASHIFTRT by register only). */ - arm_emit_coreregs_64bit_shift (, operands[0], operands[1], - operands[2], operands[3], operands[4]); - } - - DONE; - }" - [(set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits") - (set_attr "opt" "*,*,speed,speed,speed,*,*") - (set_attr "type" "multiple")] -) - ;; Widening operations (define_expand "widen_ssum3" @@ -6792,65 +6625,3 @@ if (BYTES_BIG_ENDIAN) "vabd. %0, %1, %2" [(set_attr "type" "neon_fp_abd_s")] ) - -;; Copy from core-to-neon regs, then extend, not vice-versa - -(define_split - [(set (match_operand:DI 0 "s_register_operand" "") - (sign_extend:DI (match_operand:SI 1 "s_register_operand" "")))] - "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))" - [(set (match_dup 2) (vec_duplicate:V2SI (match_dup 1))) - (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 32)))] - { - operands[2] = gen_rtx_REG (V2SImode, REGNO (operands[0])); - }) - -(define_split - [(set (match_operand:DI 0 "s_register_operand" "") - (sign_extend:DI (match_operand:HI 1 "s_register_operand" "")))] - "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))" - [(set (match_dup 2) (vec_duplicate:V4HI (match_dup 1))) - (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))] - { - operands[2] = gen_rtx_REG (V4HImode, REGNO (operands[0])); - }) - -(define_split - [(set (match_operand:DI 0 "s_register_operand" "") - (sign_extend:DI (match_operand:QI 1 "s_register_operand" "")))] - "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))" - [(set (match_dup 2) (vec_duplicate:V8QI (match_dup 1))) - (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))] - { - operands[2] = gen_rtx_REG (V8QImode, REGNO (operands[0])); - }) - -(define_split - [(set (match_operand:DI 0 "s_register_operand" "") - (zero_extend:DI (match_operand:SI 1 "s_register_operand" "")))] - "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))" - [(set (match_dup 2) (vec_duplicate:V2SI (match_dup 1))) - (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 32)))] - { - operands[2] = gen_rtx_REG (V2SImode, REGNO (operands[0])); - }) - -(define_split - [(set (match_operand:DI 0 "s_register_operand" "") - (zero_extend:DI (match_operand:HI 1 "s_register_operand" "")))] - "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))" - [(set (match_dup 2) (vec_duplicate:V4HI (match_dup 1))) - (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))] - { - operands[2] = gen_rtx_REG (V4HImode, REGNO (operands[0])); - }) - -(define_split - [(set (match_operand:DI 0 "s_register_operand" "") - (zero_extend:DI (match_operand:QI 1 "s_register_operand" "")))] - "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))" - [(set (match_dup 2) (vec_duplicate:V8QI (match_dup 1))) - (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 56)))] - { - operands[2] = gen_rtx_REG (V8QImode, REGNO (operands[0])); - }) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 03fd832..a389067 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-08-22 Wilco Dijkstra + + * gcc.target/arm/neon-extend-1.c: Remove test. + * gcc.target/arm/neon-extend-2.c: Remove test. + 2019-08-22 Sylvia Taylor * gcc.target/aarch64/advsimd-intrinsics/vld1x4.c: New test. diff --git a/gcc/testsuite/gcc.target/arm/neon-extend-1.c b/gcc/testsuite/gcc.target/arm/neon-extend-1.c deleted file mode 100644 index cfe83ce..0000000 --- a/gcc/testsuite/gcc.target/arm/neon-extend-1.c +++ /dev/null @@ -1,13 +0,0 @@ -/* { dg-require-effective-target arm_neon_hw } */ -/* { dg-options "-O2" } */ -/* { dg-add-options arm_neon } */ - -void -f (unsigned int a) -{ - unsigned long long b = a; - asm volatile ("@ extended to %0" : : "w" (b)); -} - -/* { dg-final { scan-assembler "vdup.32" } } */ -/* { dg-final { scan-assembler "vshr.u64" } } */ diff --git a/gcc/testsuite/gcc.target/arm/neon-extend-2.c b/gcc/testsuite/gcc.target/arm/neon-extend-2.c deleted file mode 100644 index 1c5a17e..0000000 --- a/gcc/testsuite/gcc.target/arm/neon-extend-2.c +++ /dev/null @@ -1,13 +0,0 @@ -/* { dg-require-effective-target arm_neon_hw } */ -/* { dg-options "-O2" } */ -/* { dg-add-options arm_neon } */ - -void -f (int a) -{ - long long b = a; - asm volatile ("@ extended to %0" : : "w" (b)); -} - -/* { dg-final { scan-assembler "vdup.32" } } */ -/* { dg-final { scan-assembler "vshr.s64" } } */ -- cgit v1.1 From ef27f40f488c590d796036ff9ad0ee572d8d8bfe Mon Sep 17 00:00:00 2001 From: Wilco Dijkstra Date: Thu, 22 Aug 2019 15:19:58 +0000 Subject: [ARM] Remove remaining Neon DImode support Remove the remaining Neon adddi3, subdi3 and negdi2 patterns. As a result adddi3, subdi3 and negdi2 can now always be expanded early irrespectively of whether Neon is available. Also expand the extenddi patterns at the same time. Several Neon arch attributes are no longer used and removed. Code generation is improved in all cases, saving another 400-500 instructions from the PR77308 testcase (total improvement is over 1700 instructions with -mcpu=cortex-a57 -O2). Bootstrap & regress OK on arm-none-linux-gnueabihf --with-cpu=cortex-a57 gcc/ * config/arm/arm.md (neon_for_64bits): Remove. (avoid_neon_for_64bits): Remove. (arm_adddi3): Always split early. (arm_subdi3): Always split early. (negdi2): Remove Neon expansion. (split zero_extend): Split before reload. (split sign_extend): Split before reload. From-SVN: r274825 --- gcc/ChangeLog | 10 ++++++ gcc/config/arm/arm.md | 90 ++++++++++++-------------------------------------- gcc/config/arm/neon.md | 89 ------------------------------------------------- 3 files changed, 32 insertions(+), 157 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6c1335e..8984d0e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,15 @@ 2019-08-22 Wilco Dijkstra + * config/arm/arm.md (neon_for_64bits): Remove. + (avoid_neon_for_64bits): Remove. + (arm_adddi3): Always split early. + (arm_subdi3): Always split early. + (negdi2): Remove Neon expansion. + (split zero_extend): Split before reload. + (split sign_extend): Split before reload. + +2019-08-22 Wilco Dijkstra + * config/arm/iterators.md (qhs_extenddi_cstr): Update. (qhs_extenddi_cstr): Likewise. * config/arm/arm.md (ashldi3): Always expand early. diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 4f6e3aa..ed49c4b 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -125,7 +125,7 @@ ; arm_arch6. "v6t2" for Thumb-2 with arm_arch6 and "v8mb" for ARMv8-M ; Baseline. This attribute is used to compute attribute "enabled", ; use type "any" to enable an alternative in all cases. -(define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,v8mb,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3,neon" +(define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,v8mb,iwmmxt,iwmmxt2,armv6_or_vfpv3,neon" (const_string "any")) (define_attr "arch_enabled" "no,yes" @@ -168,16 +168,6 @@ (match_test "TARGET_THUMB1 && arm_arch8")) (const_string "yes") - (and (eq_attr "arch" "avoid_neon_for_64bits") - (match_test "TARGET_NEON") - (not (match_test "TARGET_PREFER_NEON_64BITS"))) - (const_string "yes") - - (and (eq_attr "arch" "neon_for_64bits") - (match_test "TARGET_NEON") - (match_test "TARGET_PREFER_NEON_64BITS")) - (const_string "yes") - (and (eq_attr "arch" "iwmmxt2") (match_test "TARGET_REALLY_IWMMXT2")) (const_string "yes") @@ -450,13 +440,8 @@ (clobber (reg:CC CC_REGNUM))])] "TARGET_EITHER" " - if (TARGET_THUMB1) - { - if (!REG_P (operands[1])) - operands[1] = force_reg (DImode, operands[1]); - if (!REG_P (operands[2])) - operands[2] = force_reg (DImode, operands[2]); - } + if (TARGET_THUMB1 && !REG_P (operands[2])) + operands[2] = force_reg (DImode, operands[2]); " ) @@ -465,9 +450,9 @@ (plus:DI (match_operand:DI 1 "arm_general_register_operand" "%0, 0, r, 0, r") (match_operand:DI 2 "arm_general_adddi_operand" "r, 0, r, Dd, Dd"))) (clobber (reg:CC CC_REGNUM))] - "TARGET_32BIT && !TARGET_NEON" + "TARGET_32BIT" "#" - "TARGET_32BIT && ((!TARGET_NEON && !TARGET_IWMMXT) || reload_completed)" + "TARGET_32BIT" [(parallel [(set (reg:CC_C CC_REGNUM) (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1))) @@ -1304,24 +1289,16 @@ (clobber (reg:CC CC_REGNUM))])] "TARGET_EITHER" " - if (TARGET_THUMB1) - { - if (!REG_P (operands[1])) - operands[1] = force_reg (DImode, operands[1]); - if (!REG_P (operands[2])) - operands[2] = force_reg (DImode, operands[2]); - } - " -) +") (define_insn_and_split "*arm_subdi3" [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r") (minus:DI (match_operand:DI 1 "arm_general_register_operand" "0,r,0") (match_operand:DI 2 "arm_general_register_operand" "r,0,0"))) (clobber (reg:CC CC_REGNUM))] - "TARGET_32BIT && !TARGET_NEON" + "TARGET_32BIT" "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2" - "&& (!TARGET_IWMMXT || reload_completed)" + "TARGET_32BIT" [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (match_dup 2))) (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))]) @@ -4184,13 +4161,6 @@ (neg:DI (match_operand:DI 1 "s_register_operand"))) (clobber (reg:CC CC_REGNUM))])] "TARGET_EITHER" - { - if (TARGET_NEON) - { - emit_insn (gen_negdi2_neon (operands[0], operands[1])); - DONE; - } - } ) ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1). @@ -4202,7 +4172,7 @@ "TARGET_32BIT" "#" ; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0 (ARM) ; negs %Q0, %Q1 ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2) - "&& reload_completed" + "TARGET_32BIT" [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (const_int 0) (match_dup 1))) (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))]) @@ -4734,25 +4704,17 @@ (define_split [(set (match_operand:DI 0 "s_register_operand" "") (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))] - "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))" + "TARGET_32BIT" [(set (match_dup 0) (match_dup 1))] { rtx lo_part = gen_lowpart (SImode, operands[0]); machine_mode src_mode = GET_MODE (operands[1]); - if (REG_P (operands[0]) - && !reg_overlap_mentioned_p (operands[0], operands[1])) - emit_clobber (operands[0]); - if (!REG_P (lo_part) || src_mode != SImode - || !rtx_equal_p (lo_part, operands[1])) - { - if (src_mode == SImode) - emit_move_insn (lo_part, operands[1]); - else - emit_insn (gen_rtx_SET (lo_part, - gen_rtx_ZERO_EXTEND (SImode, operands[1]))); - operands[1] = lo_part; - } + if (src_mode == SImode) + emit_move_insn (lo_part, operands[1]); + else + emit_insn (gen_rtx_SET (lo_part, + gen_rtx_ZERO_EXTEND (SImode, operands[1]))); operands[0] = gen_highpart (SImode, operands[0]); operands[1] = const0_rtx; }) @@ -4760,26 +4722,18 @@ (define_split [(set (match_operand:DI 0 "s_register_operand" "") (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))] - "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))" + "TARGET_32BIT" [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))] { rtx lo_part = gen_lowpart (SImode, operands[0]); machine_mode src_mode = GET_MODE (operands[1]); - if (REG_P (operands[0]) - && !reg_overlap_mentioned_p (operands[0], operands[1])) - emit_clobber (operands[0]); - - if (!REG_P (lo_part) || src_mode != SImode - || !rtx_equal_p (lo_part, operands[1])) - { - if (src_mode == SImode) - emit_move_insn (lo_part, operands[1]); - else - emit_insn (gen_rtx_SET (lo_part, - gen_rtx_SIGN_EXTEND (SImode, operands[1]))); - operands[1] = lo_part; - } + if (src_mode == SImode) + emit_move_insn (lo_part, operands[1]); + else + emit_insn (gen_rtx_SET (lo_part, + gen_rtx_SIGN_EXTEND (SImode, operands[1]))); + operands[1] = lo_part; operands[0] = gen_highpart (SImode, operands[0]); }) diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md index 757f2c0..0c1ee74 100644 --- a/gcc/config/arm/neon.md +++ b/gcc/config/arm/neon.md @@ -527,32 +527,6 @@ (const_string "neon_add")))] ) -(define_insn "adddi3_neon" - [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?w,?&r,?&r,?&r") - (plus:DI (match_operand:DI 1 "s_register_operand" "%w,0,0,w,r,0,r") - (match_operand:DI 2 "arm_adddi_operand" "w,r,0,w,r,Dd,Dd"))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_NEON" -{ - switch (which_alternative) - { - case 0: /* fall through */ - case 3: return "vadd.i64\t%P0, %P1, %P2"; - case 1: return "#"; - case 2: return "#"; - case 4: return "#"; - case 5: return "#"; - case 6: return "#"; - default: gcc_unreachable (); - } -} - [(set_attr "type" "neon_add,multiple,multiple,neon_add,\ - multiple,multiple,multiple") - (set_attr "conds" "*,clob,clob,*,clob,clob,clob") - (set_attr "length" "*,8,8,*,8,8,8") - (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits,*,*,*")] -) - (define_insn "*sub3_neon" [(set (match_operand:VDQ 0 "s_register_operand" "=w") (minus:VDQ (match_operand:VDQ 1 "s_register_operand" "w") @@ -587,29 +561,6 @@ [(set_attr "type" "neon_sub")] ) -(define_insn "subdi3_neon" - [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?&r,?w") - (minus:DI (match_operand:DI 1 "s_register_operand" "w,0,r,0,w") - (match_operand:DI 2 "s_register_operand" "w,r,0,0,w"))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_NEON" -{ - switch (which_alternative) - { - case 0: /* fall through */ - case 4: return "vsub.i64\t%P0, %P1, %P2"; - case 1: /* fall through */ - case 2: /* fall through */ - case 3: return "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"; - default: gcc_unreachable (); - } -} - [(set_attr "type" "neon_sub,multiple,multiple,multiple,neon_sub") - (set_attr "conds" "*,clob,clob,clob,*") - (set_attr "length" "*,8,8,8,*") - (set_attr "arch" "neon_for_64bits,*,*,*,avoid_neon_for_64bits")] -) - (define_insn "*mul3_neon" [(set (match_operand:VDQW 0 "s_register_operand" "=w") (mult:VDQW (match_operand:VDQW 1 "s_register_operand" "w") @@ -886,46 +837,6 @@ (const_string "neon_neg")))] ) -(define_insn "negdi2_neon" - [(set (match_operand:DI 0 "s_register_operand" "=&w, w,r,&r") - (neg:DI (match_operand:DI 1 "s_register_operand" " w, w,0, r"))) - (clobber (match_scratch:DI 2 "= X,&w,X, X")) - (clobber (reg:CC CC_REGNUM))] - "TARGET_NEON" - "#" - [(set_attr "length" "8") - (set_attr "type" "multiple")] -) - -; Split negdi2_neon for vfp registers -(define_split - [(set (match_operand:DI 0 "s_register_operand" "") - (neg:DI (match_operand:DI 1 "s_register_operand" ""))) - (clobber (match_scratch:DI 2 "")) - (clobber (reg:CC CC_REGNUM))] - "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))" - [(set (match_dup 2) (const_int 0)) - (parallel [(set (match_dup 0) (minus:DI (match_dup 2) (match_dup 1))) - (clobber (reg:CC CC_REGNUM))])] - { - if (!REG_P (operands[2])) - operands[2] = operands[0]; - } -) - -; Split negdi2_neon for core registers -(define_split - [(set (match_operand:DI 0 "s_register_operand" "") - (neg:DI (match_operand:DI 1 "s_register_operand" ""))) - (clobber (match_scratch:DI 2 "")) - (clobber (reg:CC CC_REGNUM))] - "TARGET_32BIT && reload_completed - && arm_general_register_operand (operands[0], DImode)" - [(parallel [(set (match_dup 0) (neg:DI (match_dup 1))) - (clobber (reg:CC CC_REGNUM))])] - "" -) - (define_insn "2" [(set (match_operand:VH 0 "s_register_operand" "=w") (ABSNEG:VH (match_operand:VH 1 "s_register_operand" "w")))] -- cgit v1.1 From 943766d37ae4131aa6cbf9e0b2a660ffea3482a8 Mon Sep 17 00:00:00 2001 From: Kyrylo Tkachov Date: Thu, 22 Aug 2019 15:55:39 +0000 Subject: [arm] Fix use of CRC32 intrinsics with Armv8-a and hard-float We currently have a nasty error when trying to use the __crc* intrinsics with an -mfloat-abi=hard. That is because the target pragma guarding them uses armv8-a+crc that does not include fp by default. So we get errors like: error: '-mfloat-abi=hard': selected processor lacks an FPU This patch fixes that by using an FP-enabled arch target pragma to guard these intrinsics when floating-point is available. That way both the softfloat and hardfloat variants work. * config/arm/arm_acle.h: Use arch=armv8-a+crc+simd pragma for CRC32 intrinsics if __ARM_FP. Use __ARM_FEATURE_CRC32 ifdef guard. * gcc.target/arm/acle/crc_hf_1.c: New test. From-SVN: r274827 --- gcc/ChangeLog | 6 ++++++ gcc/config/arm/arm_acle.h | 8 ++++++-- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.target/arm/acle/crc_hf_1.c | 14 ++++++++++++++ 4 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/arm/acle/crc_hf_1.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8984d0e..2e58369 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-08-22 Kyrylo Tkachov + + * config/arm/arm_acle.h: Use arch=armv8-a+crc+simd pragma for CRC32 + intrinsics if __ARM_FP. + Use __ARM_FEATURE_CRC32 ifdef guard. + 2019-08-22 Wilco Dijkstra * config/arm/arm.md (neon_for_64bits): Remove. diff --git a/gcc/config/arm/arm_acle.h b/gcc/config/arm/arm_acle.h index 2c7acc6..6857ab1 100644 --- a/gcc/config/arm/arm_acle.h +++ b/gcc/config/arm/arm_acle.h @@ -174,8 +174,12 @@ __arm_mrrc2 (const unsigned int __coproc, const unsigned int __opc1, #endif /* (!__thumb__ || __thumb2__) && __ARM_ARCH >= 4. */ #pragma GCC push_options -#if __ARM_ARCH >= 8 +#ifdef __ARM_FEATURE_CRC32 +#ifdef __ARM_FP +#pragma GCC target ("arch=armv8-a+crc+simd") +#else #pragma GCC target ("arch=armv8-a+crc") +#endif __extension__ static __inline uint32_t __attribute__ ((__always_inline__)) __crc32b (uint32_t __a, uint8_t __b) @@ -235,7 +239,7 @@ __crc32cd (uint32_t __a, uint64_t __b) } #endif -#endif /* __ARM_ARCH >= 8. */ +#endif /* __ARM_FEATURE_CRC32 */ #pragma GCC pop_options #ifdef __cplusplus diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a389067..46b63d5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-08-22 Kyrylo Tkachov + + * gcc.target/arm/acle/crc_hf_1.c: New test. + 2019-08-22 Wilco Dijkstra * gcc.target/arm/neon-extend-1.c: Remove test. diff --git a/gcc/testsuite/gcc.target/arm/acle/crc_hf_1.c b/gcc/testsuite/gcc.target/arm/acle/crc_hf_1.c new file mode 100644 index 0000000..e6cbfc0 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/acle/crc_hf_1.c @@ -0,0 +1,14 @@ +/* Test that using an Armv8-a hard-float target doesn't + break CRC intrinsics. */ + +/* { dg-do compile } */ +/* { dg-require-effective-target arm_hard_vfp_ok } */ +/* { dg-options "-mfloat-abi=hard -march=armv8-a+simd+crc" } */ + +#include + +uint32_t +foo (uint32_t a, uint32_t b) +{ + return __crc32cw (a, b); +} -- cgit v1.1 From db376f458e0702a731fc13a62fee5485dca223fe Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Thu, 22 Aug 2019 17:31:02 +0000 Subject: c-parser.c (c_parser_declaration_or_fndef): Set DECL_ARGUMENTS of a FUNCTION_DECL to the right value in the presence of... * c-parser.c (c_parser_declaration_or_fndef): Set DECL_ARGUMENTS of a FUNCTION_DECL to the right value in the presence of nested declarators. From-SVN: r274828 --- gcc/c/ChangeLog | 5 ++++ gcc/c/c-parser.c | 35 +++++++++++++++++++++++++-- gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/c-c++-common/dump-ada-spec-15.c | 2 ++ 4 files changed, 44 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 4d2897e..0b3dc74 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,8 @@ +2019-08-22 Eric Botcazou + + * c-parser.c (c_parser_declaration_or_fndef): Set DECL_ARGUMENTS of a + FUNCTION_DECL to the right value in the presence of nested declarators. + 2019-08-13 Richard Sandiford PR middle-end/91421 diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 81919a8..7397f53 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -2161,10 +2161,41 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, all_prefix_attrs)); if (d && TREE_CODE (d) == FUNCTION_DECL - && declarator->kind == cdk_function && DECL_ARGUMENTS (d) == NULL_TREE && DECL_INITIAL (d) == NULL_TREE) - DECL_ARGUMENTS (d) = declarator->u.arg_info->parms; + { + /* Find the innermost declarator that is neither cdk_id + nor cdk_attrs. */ + const struct c_declarator *decl = declarator; + const struct c_declarator *last_non_id_attrs = NULL; + + while (decl) + switch (decl->kind) + { + case cdk_array: + case cdk_function: + case cdk_pointer: + last_non_id_attrs = decl; + decl = decl->declarator; + break; + + case cdk_attrs: + decl = decl->declarator; + break; + + case cdk_id: + decl = 0; + break; + + default: + gcc_unreachable (); + } + + /* If it exists and is cdk_function, use its parameters. */ + if (last_non_id_attrs + && last_non_id_attrs->kind == cdk_function) + DECL_ARGUMENTS (d) = last_non_id_attrs->u.arg_info->parms; + } if (omp_declare_simd_clauses.exists ()) { tree parms = NULL_TREE; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 46b63d5..f8a8065 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-08-22 Eric Botcazou + + * c-c++-common/dump-ada-spec-15.c: Check that the parameters are named. + 2019-08-22 Kyrylo Tkachov * gcc.target/arm/acle/crc_hf_1.c: New test. diff --git a/gcc/testsuite/c-c++-common/dump-ada-spec-15.c b/gcc/testsuite/c-c++-common/dump-ada-spec-15.c index a4b54a6..c51c3e2 100644 --- a/gcc/testsuite/c-c++-common/dump-ada-spec-15.c +++ b/gcc/testsuite/c-c++-common/dump-ada-spec-15.c @@ -3,4 +3,6 @@ extern void (*signal (int __sig, void (*__handler)(int)))(int); +/* { dg-final { scan-ada-spec "uu_sig" } } */ +/* { dg-final { scan-ada-spec "uu_handler" } } */ /* { dg-final { cleanup-ada-spec } } */ -- cgit v1.1 From 71278ecd4e308ce44f804cf4b2e26339b7d6f93f Mon Sep 17 00:00:00 2001 From: Segher Boessenkool Date: Thu, 22 Aug 2019 21:33:38 +0200 Subject: rs6000: Move various non-vector things out of altivec.md * config/rs6000/altivec.md (unspec): Delete UNSPEC_DARN, UNSPEC_DARN_32, UNSPEC_DARN_RAW, UNSPEC_CMPRB, UNSPEC_CMPRB2, UNSPEC_CMPEQB; move to... * config/rs6000/rs6000.md (unspec): ... here. * config/rs6000/altivec.md (darn_32, darn_raw, darn, cmprb, *cmprb_internal, setb_signed, setb_unsigned, cmprb2, *cmprb2_internal, cmpeqb, *cmpeqb_internal): Delete, move to... * config/rs6000/rs6000.md (darn_32, darn_raw, darn, cmprb, *cmprb_internal, setb_signed, setb_unsigned, cmprb2, *cmprb2_internal, cmpeqb, *cmpeqb_internal): ... here. From-SVN: r274834 --- gcc/ChangeLog | 12 +++ gcc/config/rs6000/altivec.md | 223 ------------------------------------------ gcc/config/rs6000/rs6000.md | 224 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 236 insertions(+), 223 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2e58369..a9e5668 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2019-08-22 Segher Boessenkool + + * config/rs6000/altivec.md (unspec): Delete UNSPEC_DARN, UNSPEC_DARN_32, + UNSPEC_DARN_RAW, UNSPEC_CMPRB, UNSPEC_CMPRB2, UNSPEC_CMPEQB; move to... + * config/rs6000/rs6000.md (unspec): ... here. + * config/rs6000/altivec.md (darn_32, darn_raw, darn, cmprb, + *cmprb_internal, setb_signed, setb_unsigned, cmprb2, *cmprb2_internal, + cmpeqb, *cmpeqb_internal): Delete, move to... + * config/rs6000/rs6000.md (darn_32, darn_raw, darn, cmprb, + *cmprb_internal, setb_signed, setb_unsigned, cmprb2, *cmprb2_internal, + cmpeqb, *cmpeqb_internal): ... here. + 2019-08-22 Kyrylo Tkachov * config/arm/arm_acle.h: Use arch=armv8-a+crc+simd pragma for CRC32 diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md index 3a8cd76..6fa4d80 100644 --- a/gcc/config/rs6000/altivec.md +++ b/gcc/config/rs6000/altivec.md @@ -80,9 +80,6 @@ UNSPEC_VUPKHPX UNSPEC_VUPKLPX UNSPEC_CONVERT_4F32_8I16 - UNSPEC_DARN - UNSPEC_DARN_32 - UNSPEC_DARN_RAW UNSPEC_DST UNSPEC_DSTT UNSPEC_DSTST @@ -161,9 +158,6 @@ UNSPEC_BCDADD UNSPEC_BCDSUB UNSPEC_BCD_OVERFLOW - UNSPEC_CMPRB - UNSPEC_CMPRB2 - UNSPEC_CMPEQB UNSPEC_VRLMI UNSPEC_VRLNM ]) @@ -4107,223 +4101,6 @@ "bcd. %0,%1,%2,%3" [(set_attr "type" "vecsimple")]) -(define_insn "darn_32" - [(set (match_operand:SI 0 "register_operand" "=r") - (unspec:SI [(const_int 0)] UNSPEC_DARN_32))] - "TARGET_P9_MISC" - "darn %0,0" - [(set_attr "type" "integer")]) - -(define_insn "darn_raw" - [(set (match_operand:DI 0 "register_operand" "=r") - (unspec:DI [(const_int 0)] UNSPEC_DARN_RAW))] - "TARGET_P9_MISC && TARGET_64BIT" - "darn %0,2" - [(set_attr "type" "integer")]) - -(define_insn "darn" - [(set (match_operand:DI 0 "register_operand" "=r") - (unspec:DI [(const_int 0)] UNSPEC_DARN))] - "TARGET_P9_MISC && TARGET_64BIT" - "darn %0,1" - [(set_attr "type" "integer")]) - -;; Test byte within range. -;; -;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx -;; represents a byte whose value is ignored in this context and -;; vv, the least significant byte, holds the byte value that is to -;; be tested for membership within the range specified by operand 2. -;; The bytes of operand 2 are organized as xx:xx:hi:lo. -;; -;; Return in target register operand 0 a value of 1 if lo <= vv and -;; vv <= hi. Otherwise, set register operand 0 to 0. -;; -;; Though the instructions to which this expansion maps operate on -;; 64-bit registers, the current implementation only operates on -;; SI-mode operands as the high-order bits provide no information -;; that is not already available in the low-order bits. To avoid the -;; costs of data widening operations, future enhancements might allow -;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. -(define_expand "cmprb" - [(set (match_dup 3) - (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "gpc_reg_operand" "r")] - UNSPEC_CMPRB)) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (if_then_else:SI (lt (match_dup 3) - (const_int 0)) - (const_int -1) - (if_then_else (gt (match_dup 3) - (const_int 0)) - (const_int 1) - (const_int 0))))] - "TARGET_P9_MISC" -{ - operands[3] = gen_reg_rtx (CCmode); -}) - -;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx -;; represents a byte whose value is ignored in this context and -;; vv, the least significant byte, holds the byte value that is to -;; be tested for membership within the range specified by operand 2. -;; The bytes of operand 2 are organized as xx:xx:hi:lo. -;; -;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if -;; lo <= vv and vv <= hi. Otherwise, set the GT bit to 0. The other -;; 3 bits of the target CR register are all set to 0. -(define_insn "*cmprb_internal" - [(set (match_operand:CC 0 "cc_reg_operand" "=y") - (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "gpc_reg_operand" "r")] - UNSPEC_CMPRB))] - "TARGET_P9_MISC" - "cmprb %0,0,%1,%2" - [(set_attr "type" "logical")]) - -;; Set operand 0 register to -1 if the LT bit (0x8) of condition -;; register operand 1 is on. Otherwise, set operand 0 register to 1 -;; if the GT bit (0x4) of condition register operand 1 is on. -;; Otherwise, set operand 0 to 0. Note that the result stored into -;; register operand 0 is non-zero iff either the LT or GT bits are on -;; within condition register operand 1. -(define_insn "setb_signed" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y") - (const_int 0)) - (const_int -1) - (if_then_else (gt (match_dup 1) - (const_int 0)) - (const_int 1) - (const_int 0))))] - "TARGET_P9_MISC" - "setb %0,%1" - [(set_attr "type" "logical")]) - -(define_insn "setb_unsigned" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y") - (const_int 0)) - (const_int -1) - (if_then_else (gtu (match_dup 1) - (const_int 0)) - (const_int 1) - (const_int 0))))] - "TARGET_P9_MISC" - "setb %0,%1" - [(set_attr "type" "logical")]) - -;; Test byte within two ranges. -;; -;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx -;; represents a byte whose value is ignored in this context and -;; vv, the least significant byte, holds the byte value that is to -;; be tested for membership within the range specified by operand 2. -;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2. -;; -;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and -;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). Otherwise, set register -;; operand 0 to 0. -;; -;; Though the instructions to which this expansion maps operate on -;; 64-bit registers, the current implementation only operates on -;; SI-mode operands as the high-order bits provide no information -;; that is not already available in the low-order bits. To avoid the -;; costs of data widening operations, future enhancements might allow -;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. -(define_expand "cmprb2" - [(set (match_dup 3) - (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "gpc_reg_operand" "r")] - UNSPEC_CMPRB2)) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (if_then_else:SI (lt (match_dup 3) - (const_int 0)) - (const_int -1) - (if_then_else (gt (match_dup 3) - (const_int 0)) - (const_int 1) - (const_int 0))))] - "TARGET_P9_MISC" -{ - operands[3] = gen_reg_rtx (CCmode); -}) - -;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx -;; represents a byte whose value is ignored in this context and -;; vv, the least significant byte, holds the byte value that is to -;; be tested for membership within the ranges specified by operand 2. -;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2. -;; -;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if -;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). -;; Otherwise, set the GT bit to 0. The other 3 bits of the target -;; CR register are all set to 0. -(define_insn "*cmprb2_internal" - [(set (match_operand:CC 0 "cc_reg_operand" "=y") - (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "gpc_reg_operand" "r")] - UNSPEC_CMPRB2))] - "TARGET_P9_MISC" - "cmprb %0,1,%1,%2" - [(set_attr "type" "logical")]) - -;; Test byte membership within set of 8 bytes. -;; -;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx -;; represents a byte whose value is ignored in this context and -;; vv, the least significant byte, holds the byte value that is to -;; be tested for membership within the set specified by operand 2. -;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7. -;; -;; Return in target register operand 0 a value of 1 if vv equals one -;; of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, set -;; register operand 0 to 0. Note that the 8 byte values held within -;; operand 2 need not be unique. -;; -;; Though the instructions to which this expansion maps operate on -;; 64-bit registers, the current implementation requires that operands -;; 0 and 1 have mode SI as the high-order bits provide no information -;; that is not already available in the low-order bits. To avoid the -;; costs of data widening operations, future enhancements might allow -;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. -(define_expand "cmpeqb" - [(set (match_dup 3) - (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "gpc_reg_operand" "r")] - UNSPEC_CMPEQB)) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (if_then_else:SI (lt (match_dup 3) - (const_int 0)) - (const_int -1) - (if_then_else (gt (match_dup 3) - (const_int 0)) - (const_int 1) - (const_int 0))))] - "TARGET_P9_MISC && TARGET_64BIT" -{ - operands[3] = gen_reg_rtx (CCmode); -}) - -;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx -;; represents a byte whose value is ignored in this context and -;; vv, the least significant byte, holds the byte value that is to -;; be tested for membership within the set specified by operand 2. -;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7. -;; -;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv -;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, -;; set the GT bit to zero. The other 3 bits of the target CR register -;; are all set to 0. -(define_insn "*cmpeqb_internal" - [(set (match_operand:CC 0 "cc_reg_operand" "=y") - (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "gpc_reg_operand" "r")] - UNSPEC_CMPEQB))] - "TARGET_P9_MISC && TARGET_64BIT" - "cmpeqb %0,%1,%2" - [(set_attr "type" "logical")]) - (define_expand "bcd_" [(parallel [(set (reg:CCFP CR6_REGNO) (compare:CCFP diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 9a7a1da..68cdf68 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -134,6 +134,12 @@ UNSPEC_LSQ UNSPEC_FUSION_GPR UNSPEC_STACK_CHECK + UNSPEC_DARN + UNSPEC_DARN_32 + UNSPEC_DARN_RAW + UNSPEC_CMPRB + UNSPEC_CMPRB2 + UNSPEC_CMPEQB UNSPEC_ADD_ROUND_TO_ODD UNSPEC_SUB_ROUND_TO_ODD UNSPEC_MUL_ROUND_TO_ODD @@ -14376,7 +14382,225 @@ "xscmpuqp %0,%1,%2" [(set_attr "type" "veccmp") (set_attr "size" "128")]) + +;; Miscellaneous ISA 3.0 (power9) instructions + +(define_insn "darn_32" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec:SI [(const_int 0)] UNSPEC_DARN_32))] + "TARGET_P9_MISC" + "darn %0,0" + [(set_attr "type" "integer")]) + +(define_insn "darn_raw" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(const_int 0)] UNSPEC_DARN_RAW))] + "TARGET_P9_MISC && TARGET_64BIT" + "darn %0,2" + [(set_attr "type" "integer")]) + +(define_insn "darn" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(const_int 0)] UNSPEC_DARN))] + "TARGET_P9_MISC && TARGET_64BIT" + "darn %0,1" + [(set_attr "type" "integer")]) + +;; Test byte within range. +;; +;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx +;; represents a byte whose value is ignored in this context and +;; vv, the least significant byte, holds the byte value that is to +;; be tested for membership within the range specified by operand 2. +;; The bytes of operand 2 are organized as xx:xx:hi:lo. +;; +;; Return in target register operand 0 a value of 1 if lo <= vv and +;; vv <= hi. Otherwise, set register operand 0 to 0. +;; +;; Though the instructions to which this expansion maps operate on +;; 64-bit registers, the current implementation only operates on +;; SI-mode operands as the high-order bits provide no information +;; that is not already available in the low-order bits. To avoid the +;; costs of data widening operations, future enhancements might allow +;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. +(define_expand "cmprb" + [(set (match_dup 3) + (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "gpc_reg_operand" "r")] + UNSPEC_CMPRB)) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (if_then_else:SI (lt (match_dup 3) + (const_int 0)) + (const_int -1) + (if_then_else (gt (match_dup 3) + (const_int 0)) + (const_int 1) + (const_int 0))))] + "TARGET_P9_MISC" +{ + operands[3] = gen_reg_rtx (CCmode); +}) + +;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx +;; represents a byte whose value is ignored in this context and +;; vv, the least significant byte, holds the byte value that is to +;; be tested for membership within the range specified by operand 2. +;; The bytes of operand 2 are organized as xx:xx:hi:lo. +;; +;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if +;; lo <= vv and vv <= hi. Otherwise, set the GT bit to 0. The other +;; 3 bits of the target CR register are all set to 0. +(define_insn "*cmprb_internal" + [(set (match_operand:CC 0 "cc_reg_operand" "=y") + (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "gpc_reg_operand" "r")] + UNSPEC_CMPRB))] + "TARGET_P9_MISC" + "cmprb %0,0,%1,%2" + [(set_attr "type" "logical")]) + +;; Set operand 0 register to -1 if the LT bit (0x8) of condition +;; register operand 1 is on. Otherwise, set operand 0 register to 1 +;; if the GT bit (0x4) of condition register operand 1 is on. +;; Otherwise, set operand 0 to 0. Note that the result stored into +;; register operand 0 is non-zero iff either the LT or GT bits are on +;; within condition register operand 1. +(define_insn "setb_signed" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y") + (const_int 0)) + (const_int -1) + (if_then_else (gt (match_dup 1) + (const_int 0)) + (const_int 1) + (const_int 0))))] + "TARGET_P9_MISC" + "setb %0,%1" + [(set_attr "type" "logical")]) +(define_insn "setb_unsigned" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y") + (const_int 0)) + (const_int -1) + (if_then_else (gtu (match_dup 1) + (const_int 0)) + (const_int 1) + (const_int 0))))] + "TARGET_P9_MISC" + "setb %0,%1" + [(set_attr "type" "logical")]) + +;; Test byte within two ranges. +;; +;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx +;; represents a byte whose value is ignored in this context and +;; vv, the least significant byte, holds the byte value that is to +;; be tested for membership within the range specified by operand 2. +;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2. +;; +;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and +;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). Otherwise, set register +;; operand 0 to 0. +;; +;; Though the instructions to which this expansion maps operate on +;; 64-bit registers, the current implementation only operates on +;; SI-mode operands as the high-order bits provide no information +;; that is not already available in the low-order bits. To avoid the +;; costs of data widening operations, future enhancements might allow +;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. +(define_expand "cmprb2" + [(set (match_dup 3) + (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "gpc_reg_operand" "r")] + UNSPEC_CMPRB2)) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (if_then_else:SI (lt (match_dup 3) + (const_int 0)) + (const_int -1) + (if_then_else (gt (match_dup 3) + (const_int 0)) + (const_int 1) + (const_int 0))))] + "TARGET_P9_MISC" +{ + operands[3] = gen_reg_rtx (CCmode); +}) + +;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx +;; represents a byte whose value is ignored in this context and +;; vv, the least significant byte, holds the byte value that is to +;; be tested for membership within the ranges specified by operand 2. +;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2. +;; +;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if +;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). +;; Otherwise, set the GT bit to 0. The other 3 bits of the target +;; CR register are all set to 0. +(define_insn "*cmprb2_internal" + [(set (match_operand:CC 0 "cc_reg_operand" "=y") + (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "gpc_reg_operand" "r")] + UNSPEC_CMPRB2))] + "TARGET_P9_MISC" + "cmprb %0,1,%1,%2" + [(set_attr "type" "logical")]) + +;; Test byte membership within set of 8 bytes. +;; +;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx +;; represents a byte whose value is ignored in this context and +;; vv, the least significant byte, holds the byte value that is to +;; be tested for membership within the set specified by operand 2. +;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7. +;; +;; Return in target register operand 0 a value of 1 if vv equals one +;; of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, set +;; register operand 0 to 0. Note that the 8 byte values held within +;; operand 2 need not be unique. +;; +;; Though the instructions to which this expansion maps operate on +;; 64-bit registers, the current implementation requires that operands +;; 0 and 1 have mode SI as the high-order bits provide no information +;; that is not already available in the low-order bits. To avoid the +;; costs of data widening operations, future enhancements might allow +;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. +(define_expand "cmpeqb" + [(set (match_dup 3) + (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") + (match_operand:DI 2 "gpc_reg_operand" "r")] + UNSPEC_CMPEQB)) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (if_then_else:SI (lt (match_dup 3) + (const_int 0)) + (const_int -1) + (if_then_else (gt (match_dup 3) + (const_int 0)) + (const_int 1) + (const_int 0))))] + "TARGET_P9_MISC && TARGET_64BIT" +{ + operands[3] = gen_reg_rtx (CCmode); +}) + +;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx +;; represents a byte whose value is ignored in this context and +;; vv, the least significant byte, holds the byte value that is to +;; be tested for membership within the set specified by operand 2. +;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7. +;; +;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv +;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, +;; set the GT bit to zero. The other 3 bits of the target CR register +;; are all set to 0. +(define_insn "*cmpeqb_internal" + [(set (match_operand:CC 0 "cc_reg_operand" "=y") + (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") + (match_operand:DI 2 "gpc_reg_operand" "r")] + UNSPEC_CMPEQB))] + "TARGET_P9_MISC && TARGET_64BIT" + "cmpeqb %0,%1,%2" + [(set_attr "type" "logical")]) (include "sync.md") -- cgit v1.1 From e99bfdd2a8db732ea84cf0a6486707e5e821ad7e Mon Sep 17 00:00:00 2001 From: Segher Boessenkool Date: Thu, 22 Aug 2019 21:36:21 +0200 Subject: rs6000: Use unspec_volatile for darn (PR91481) Every call to darn should deliver a *new* random number; such calls should not be CSEd together. So they should be unspec_volatile, not plain unspec. PR target/91481 * config/rs6000/rs6000.md (unspec): Delete UNSPEC_DARN, UNSPEC_DARN_32, and UNSPEC_DARN_RAW. (unspecv): New enumerator values UNSPECV_DARN, UNSPECV_DARN_32, and UNSPECV_DARN_RAW. (darn_32): Use an unspec_volatile, and UNSPECV_DARN_32. (darn_raw): Use an unspec_volatile, and UNSPECV_DARN_RAW. (darn): Use an unspec_volatile, and UNSPECV_DARN. From-SVN: r274835 --- gcc/ChangeLog | 11 +++++++++++ gcc/config/rs6000/rs6000.md | 12 ++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a9e5668..3ef76ce 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,16 @@ 2019-08-22 Segher Boessenkool + PR target/91481 + * config/rs6000/rs6000.md (unspec): Delete UNSPEC_DARN, UNSPEC_DARN_32, + and UNSPEC_DARN_RAW. + (unspecv): New enumerator values UNSPECV_DARN, UNSPECV_DARN_32, and + UNSPECV_DARN_RAW. + (darn_32): Use an unspec_volatile, and UNSPECV_DARN_32. + (darn_raw): Use an unspec_volatile, and UNSPECV_DARN_RAW. + (darn): Use an unspec_volatile, and UNSPECV_DARN. + +2019-08-22 Segher Boessenkool + * config/rs6000/altivec.md (unspec): Delete UNSPEC_DARN, UNSPEC_DARN_32, UNSPEC_DARN_RAW, UNSPEC_CMPRB, UNSPEC_CMPRB2, UNSPEC_CMPEQB; move to... * config/rs6000/rs6000.md (unspec): ... here. diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 68cdf68..b0aea23 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -134,9 +134,6 @@ UNSPEC_LSQ UNSPEC_FUSION_GPR UNSPEC_STACK_CHECK - UNSPEC_DARN - UNSPEC_DARN_32 - UNSPEC_DARN_RAW UNSPEC_CMPRB UNSPEC_CMPRB2 UNSPEC_CMPEQB @@ -168,6 +165,9 @@ UNSPECV_EH_RR ; eh_reg_restore UNSPECV_ISYNC ; isync instruction UNSPECV_MFTB ; move from time base + UNSPECV_DARN ; darn 1 (deliver a random number) + UNSPECV_DARN_32 ; darn 2 + UNSPECV_DARN_RAW ; darn 0 UNSPECV_NLGR ; non-local goto receiver UNSPECV_MFFS ; Move from FPSCR UNSPECV_MFFSL ; Move from FPSCR light instruction version @@ -14387,21 +14387,21 @@ (define_insn "darn_32" [(set (match_operand:SI 0 "register_operand" "=r") - (unspec:SI [(const_int 0)] UNSPEC_DARN_32))] + (unspec_volatile:SI [(const_int 0)] UNSPECV_DARN_32))] "TARGET_P9_MISC" "darn %0,0" [(set_attr "type" "integer")]) (define_insn "darn_raw" [(set (match_operand:DI 0 "register_operand" "=r") - (unspec:DI [(const_int 0)] UNSPEC_DARN_RAW))] + (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN_RAW))] "TARGET_P9_MISC && TARGET_64BIT" "darn %0,2" [(set_attr "type" "integer")]) (define_insn "darn" [(set (match_operand:DI 0 "register_operand" "=r") - (unspec:DI [(const_int 0)] UNSPEC_DARN))] + (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN))] "TARGET_P9_MISC && TARGET_64BIT" "darn %0,1" [(set_attr "type" "integer")]) -- cgit v1.1 From 1b1e13dbde7f3eef0f8356af05c5de1fb46cb31b Mon Sep 17 00:00:00 2001 From: Rainer Orth Date: Thu, 22 Aug 2019 21:55:19 +0000 Subject: Fix gcc.target/i386/minmax-4.c etc. on 32-bit Solaris/x86 * gcc.target/i386/minmax-4.c: Add -mno-stackrealign to dg-options. * gcc.target/i386/minmax-5.c: Likewise. * gcc.target/i386/minmax-6.c: Likewise. * gcc.target/i386/minmax-7.c: Likewise. * gcc.target/i386/pr91154.c: Likewise. From-SVN: r274836 --- gcc/testsuite/ChangeLog | 8 ++++++++ gcc/testsuite/gcc.target/i386/minmax-4.c | 2 +- gcc/testsuite/gcc.target/i386/minmax-5.c | 2 +- gcc/testsuite/gcc.target/i386/minmax-6.c | 2 +- gcc/testsuite/gcc.target/i386/minmax-7.c | 2 +- gcc/testsuite/gcc.target/i386/pr91154.c | 2 +- 6 files changed, 13 insertions(+), 5 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f8a8065..67ff3dc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2019-08-22 Rainer Orth + + * gcc.target/i386/minmax-4.c: Add -mno-stackrealign to dg-options. + * gcc.target/i386/minmax-5.c: Likewise. + * gcc.target/i386/minmax-6.c: Likewise. + * gcc.target/i386/minmax-7.c: Likewise. + * gcc.target/i386/pr91154.c: Likewise. + 2019-08-22 Eric Botcazou * c-c++-common/dump-ada-spec-15.c: Check that the parameters are named. diff --git a/gcc/testsuite/gcc.target/i386/minmax-4.c b/gcc/testsuite/gcc.target/i386/minmax-4.c index 9d8ed18..4b4d436 100644 --- a/gcc/testsuite/gcc.target/i386/minmax-4.c +++ b/gcc/testsuite/gcc.target/i386/minmax-4.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -mstv -msse4.1" } */ +/* { dg-options "-O2 -mstv -mno-stackrealign -msse4.1" } */ #include "minmax-3.c" diff --git a/gcc/testsuite/gcc.target/i386/minmax-5.c b/gcc/testsuite/gcc.target/i386/minmax-5.c index 1971dbd..c37067c 100644 --- a/gcc/testsuite/gcc.target/i386/minmax-5.c +++ b/gcc/testsuite/gcc.target/i386/minmax-5.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -mstv -mavx512vl" } */ +/* { dg-options "-O2 -mstv -mno-stackrealign -mavx512vl" } */ #include "minmax-3.c" diff --git a/gcc/testsuite/gcc.target/i386/minmax-6.c b/gcc/testsuite/gcc.target/i386/minmax-6.c index b3af8c4..615f919 100644 --- a/gcc/testsuite/gcc.target/i386/minmax-6.c +++ b/gcc/testsuite/gcc.target/i386/minmax-6.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -march=haswell" } */ +/* { dg-options "-O2 -march=haswell -mno-stackrealign" } */ unsigned short UMVLine16Y_11 (short unsigned int * Pic, int y, int width) diff --git a/gcc/testsuite/gcc.target/i386/minmax-7.c b/gcc/testsuite/gcc.target/i386/minmax-7.c index 905f085..619a939 100644 --- a/gcc/testsuite/gcc.target/i386/minmax-7.c +++ b/gcc/testsuite/gcc.target/i386/minmax-7.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -march=haswell" } */ +/* { dg-options "-O2 -march=haswell -mno-stackrealign" } */ extern int numBins; extern int binOffst; diff --git a/gcc/testsuite/gcc.target/i386/pr91154.c b/gcc/testsuite/gcc.target/i386/pr91154.c index 69f2e21..2fea335 100644 --- a/gcc/testsuite/gcc.target/i386/pr91154.c +++ b/gcc/testsuite/gcc.target/i386/pr91154.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -msse4.1 -mstv" } */ +/* { dg-options "-O2 -msse4.1 -mstv -mno-stackrealign" } */ void foo (int *dc, int *mc, int *tpdd, int *tpmd, int M) { -- cgit v1.1 From 14b7950f126f84fa585e3a057940ff10d4c5b3f8 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Thu, 22 Aug 2019 23:09:26 +0000 Subject: PR middle-end/91490 - bogus argument missing terminating nul warning on strlen of a flexible array member gcc/c-family/ChangeLog: PR middle-end/91490 * c-common.c (braced_list_to_string): Add argument and overload. Handle flexible length arrays and unions. gcc/testsuite/ChangeLog: PR middle-end/91490 * c-c++-common/Warray-bounds-7.c: New test. * gcc.dg/Warray-bounds-39.c: Expect either -Warray-bounds or -Wstringop-overflow. * gcc.dg/strlenopt-78.c: New test. gcc/ChangeLog: PR middle-end/91490 * builtins.c (c_strlen): Rename argument and introduce new local. Set no-warning bit on original argument. * expr.c (string_constant): Pass argument type to fold_ctor_reference. Fold empty and zero constructors into empty strings. * gimple-fold.c (fold_nonarray_ctor_reference): Return a STRING_CST for missing initializers. * tree.c (build_string_literal): Handle optional argument. * tree.h (build_string_literal): Add defaulted argument. * gimple-ssa-warn-restrict.c (maybe_diag_access_bounds): Check no-warning bit on original expression. From-SVN: r274837 --- gcc/ChangeLog | 14 +++ gcc/builtins.c | 17 ++- gcc/c-family/ChangeLog | 6 + gcc/c-family/c-common.c | 54 ++++++--- gcc/expr.c | 64 ++++++++--- gcc/gimple-fold.c | 21 ++-- gcc/gimple-ssa-warn-restrict.c | 3 +- gcc/testsuite/ChangeLog | 8 ++ gcc/testsuite/c-c++-common/Warray-bounds-7.c | 107 +++++++++++++++++ gcc/testsuite/gcc.dg/Warray-bounds-39.c | 46 ++++---- gcc/testsuite/gcc.dg/strlenopt-78.c | 166 +++++++++++++++++++++++++++ gcc/tree.c | 17 ++- gcc/tree.h | 3 +- 13 files changed, 450 insertions(+), 76 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/Warray-bounds-7.c create mode 100644 gcc/testsuite/gcc.dg/strlenopt-78.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3ef76ce..2651ce2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2019-08-22 Martin Sebor + + PR middle-end/91490 + * builtins.c (c_strlen): Rename argument and introduce new local. + Set no-warning bit on original argument. + * expr.c (string_constant): Pass argument type to fold_ctor_reference. + Fold empty and zero constructors into empty strings. + * gimple-fold.c (fold_nonarray_ctor_reference): Return a STRING_CST + for missing initializers. + * tree.c (build_string_literal): Handle optional argument. + * tree.h (build_string_literal): Add defaulted argument. + * gimple-ssa-warn-restrict.c (maybe_diag_access_bounds): Check + no-warning bit on original expression. + 2019-08-22 Segher Boessenkool PR target/91481 diff --git a/gcc/builtins.c b/gcc/builtins.c index 9a766e4..073b92a 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -620,7 +620,7 @@ unterminated_array (tree exp, tree *size /* = NULL */, bool *exact /* = NULL */) into the instruction stream and zero if it is going to be expanded. E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3 is returned, otherwise NULL, since - len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not + len = c_strlen (ARG, 1); if (len) expand_expr (len, ...); would not evaluate the side-effects. If ONLY_VALUE is two then we do not emit warnings about out-of-bound @@ -628,7 +628,7 @@ unterminated_array (tree exp, tree *size /* = NULL */, bool *exact /* = NULL */) into the instruction stream. Additional information about the string accessed may be recorded - in DATA. For example, if SRC references an unterminated string, + in DATA. For example, if ARG references an unterminated string, then the declaration will be stored in the DECL field. If the length of the unterminated string can be determined, it'll be stored in the LEN field. Note this length could well be different @@ -640,7 +640,7 @@ unterminated_array (tree exp, tree *size /* = NULL */, bool *exact /* = NULL */) The value returned is of type `ssizetype'. */ tree -c_strlen (tree src, int only_value, c_strlen_data *data, unsigned eltsize) +c_strlen (tree arg, int only_value, c_strlen_data *data, unsigned eltsize) { /* If we were not passed a DATA pointer, then get one to a local structure. That avoids having to check DATA for NULL before @@ -650,7 +650,8 @@ c_strlen (tree src, int only_value, c_strlen_data *data, unsigned eltsize) data = &local_strlen_data; gcc_checking_assert (eltsize == 1 || eltsize == 2 || eltsize == 4); - STRIP_NOPS (src); + + tree src = STRIP_NOPS (arg); if (TREE_CODE (src) == COND_EXPR && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0)))) { @@ -762,11 +763,15 @@ c_strlen (tree src, int only_value, c_strlen_data *data, unsigned eltsize) { /* Suppress multiple warnings for propagated constant strings. */ if (only_value != 2 - && !TREE_NO_WARNING (src) + && !TREE_NO_WARNING (arg) && warning_at (loc, OPT_Warray_bounds, "offset %qwi outside bounds of constant string", eltoff)) - TREE_NO_WARNING (src) = 1; + { + if (decl) + inform (DECL_SOURCE_LOCATION (decl), "%qE declared here", decl); + TREE_NO_WARNING (arg) = 1; + } return NULL_TREE; } diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index c872140..a1a864a 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2019-08-22 Martin Sebor + + PR middle-end/91490 + * c-common.c (braced_list_to_string): Add argument and overload. + Handle flexible length arrays and unions. + 2019-08-21 Eric Botcazou * c-ada-spec.c (dump_ada_function_declaration): Be prepared for broken diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 2810867..0aaa246 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -8747,9 +8747,12 @@ maybe_add_include_fixit (rich_location *richloc, const char *header, the converted string on success or the original ctor on failure. */ static tree -braced_list_to_string (tree type, tree ctor) +braced_list_to_string (tree type, tree ctor, bool member) { - if (!tree_fits_uhwi_p (TYPE_SIZE_UNIT (type))) + /* Ignore non-members with unknown size like arrays with unspecified + bound. */ + tree typesize = TYPE_SIZE_UNIT (type); + if (!member && !tree_fits_uhwi_p (typesize)) return ctor; /* If the array has an explicit bound, use it to constrain the size @@ -8757,10 +8760,17 @@ braced_list_to_string (tree type, tree ctor) as long as implied by the index of the last zero specified via a designator, as in: const char a[] = { [7] = 0 }; */ - unsigned HOST_WIDE_INT maxelts = tree_to_uhwi (TYPE_SIZE_UNIT (type)); - maxelts /= tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (type))); + unsigned HOST_WIDE_INT maxelts; + if (typesize) + { + maxelts = tree_to_uhwi (typesize); + maxelts /= tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (type))); + } + else + maxelts = HOST_WIDE_INT_M1U; - /* Avoid converting initializers for zero-length arrays. */ + /* Avoid converting initializers for zero-length arrays (but do + create them for flexible array members). */ if (!maxelts) return ctor; @@ -8818,7 +8828,7 @@ braced_list_to_string (tree type, tree ctor) } /* Append a nul string termination. */ - if (str.length () < maxelts) + if (maxelts != HOST_WIDE_INT_M1U && str.length () < maxelts) str.safe_push (0); /* Build a STRING_CST with the same type as the array. */ @@ -8827,14 +8837,12 @@ braced_list_to_string (tree type, tree ctor) return res; } -/* Attempt to convert a CTOR containing braced array initializer lists - for array TYPE into one containing STRING_CSTs, for convenience and - efficiency. Recurse for arrays of arrays and member initializers. - Return the converted CTOR or STRING_CST on success or the original - CTOR otherwise. */ +/* Implementation of the two-argument braced_lists_to_string withe + the same arguments plus MEMBER which is set for struct members + to allow initializers for flexible member arrays. */ -tree -braced_lists_to_strings (tree type, tree ctor) +static tree +braced_lists_to_strings (tree type, tree ctor, bool member) { if (TREE_CODE (ctor) != CONSTRUCTOR) return ctor; @@ -8858,17 +8866,19 @@ braced_lists_to_strings (tree type, tree ctor) if ((TREE_CODE (ttp) == ARRAY_TYPE || TREE_CODE (ttp) == INTEGER_TYPE) && TYPE_STRING_FLAG (ttp)) - return braced_list_to_string (type, ctor); + return braced_list_to_string (type, ctor, member); code = TREE_CODE (ttp); - if (code == ARRAY_TYPE || code == RECORD_TYPE) + if (code == ARRAY_TYPE || RECORD_OR_UNION_TYPE_P (ttp)) { + bool rec = RECORD_OR_UNION_TYPE_P (ttp); + /* Handle array of arrays or struct member initializers. */ tree val; unsigned HOST_WIDE_INT idx; FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), idx, val) { - val = braced_lists_to_strings (ttp, val); + val = braced_lists_to_strings (ttp, val, rec); CONSTRUCTOR_ELT (ctor, idx)->value = val; } } @@ -8876,4 +8886,16 @@ braced_lists_to_strings (tree type, tree ctor) return ctor; } +/* Attempt to convert a CTOR containing braced array initializer lists + for array TYPE into one containing STRING_CSTs, for convenience and + efficiency. Recurse for arrays of arrays and member initializers. + Return the converted CTOR or STRING_CST on success or the original + CTOR otherwise. */ + +tree +braced_lists_to_strings (tree type, tree ctor) +{ + return braced_lists_to_strings (type, ctor, false); +} + #include "gt-c-family-c-common.h" diff --git a/gcc/expr.c b/gcc/expr.c index 9297928..5ca0e20 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -11402,6 +11402,15 @@ is_aligning_offset (const_tree offset, const_tree exp) tree string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl) { + tree dummy = NULL_TREE;; + if (!mem_size) + mem_size = &dummy; + + /* Store the type of the original expression before conversions + via NOP_EXPR or POINTER_PLUS_EXPR to other types have been + removed. */ + tree argtype = TREE_TYPE (arg); + tree array; STRIP_NOPS (arg); @@ -11464,7 +11473,7 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl) && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == ARRAY_TYPE && !(decl && !*decl) && !(decl && tree_fits_uhwi_p (DECL_SIZE_UNIT (*decl)) - && mem_size && tree_fits_uhwi_p (*mem_size) + && tree_fits_uhwi_p (*mem_size) && tree_int_cst_equal (*mem_size, DECL_SIZE_UNIT (*decl)))) return NULL_TREE; @@ -11496,7 +11505,7 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl) && TREE_CODE (TREE_TYPE (TREE_TYPE (rhs1))) == ARRAY_TYPE && !(decl && !*decl) && !(decl && tree_fits_uhwi_p (DECL_SIZE_UNIT (*decl)) - && mem_size && tree_fits_uhwi_p (*mem_size) + && tree_fits_uhwi_p (*mem_size) && tree_int_cst_equal (*mem_size, DECL_SIZE_UNIT (*decl)))) return NULL_TREE; @@ -11530,8 +11539,7 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl) if (TREE_CODE (array) == STRING_CST) { *ptr_offset = fold_convert (sizetype, offset); - if (mem_size) - *mem_size = TYPE_SIZE_UNIT (TREE_TYPE (array)); + *mem_size = TYPE_SIZE_UNIT (TREE_TYPE (array)); if (decl) *decl = NULL_TREE; gcc_checking_assert (tree_to_shwi (TYPE_SIZE_UNIT (TREE_TYPE (array))) @@ -11561,7 +11569,7 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl) base_off = wioff.to_uhwi (); unsigned HOST_WIDE_INT fieldoff = 0; - init = fold_ctor_reference (NULL_TREE, init, base_off, 0, array, + init = fold_ctor_reference (TREE_TYPE (arg), init, base_off, 0, array, &fieldoff); HOST_WIDE_INT cstoff; if (!base_off.is_constant (&cstoff)) @@ -11580,17 +11588,11 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl) *ptr_offset = offset; - tree eltype = TREE_TYPE (init); - tree initsize = TYPE_SIZE_UNIT (eltype); - if (mem_size) - *mem_size = initsize; - - if (decl) - *decl = array; + tree inittype = TREE_TYPE (init); if (TREE_CODE (init) == INTEGER_CST && (TREE_CODE (TREE_TYPE (array)) == INTEGER_TYPE - || TYPE_MAIN_VARIANT (eltype) == char_type_node)) + || TYPE_MAIN_VARIANT (inittype) == char_type_node)) { /* For a reference to (address of) a single constant character, store the native representation of the character in CHARBUF. @@ -11602,17 +11604,49 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl) int len = native_encode_expr (init, charbuf, sizeof charbuf, 0); if (len > 0) { - /* Construct a string literal with elements of ELTYPE and + /* Construct a string literal with elements of INITTYPE and the representation above. Then strip the ADDR_EXPR (ARRAY_REF (...)) around the STRING_CST. */ - init = build_string_literal (len, (char *)charbuf, eltype); + init = build_string_literal (len, (char *)charbuf, inittype); init = TREE_OPERAND (TREE_OPERAND (init, 0), 0); } } + tree initsize = TYPE_SIZE_UNIT (inittype); + + if (TREE_CODE (init) == CONSTRUCTOR && initializer_zerop (init)) + { + /* Fold an empty/zero constructor for an implicitly initialized + object or subobject into the empty string. */ + + /* Determine the character type from that of the original + expression. */ + tree chartype = argtype; + if (POINTER_TYPE_P (chartype)) + chartype = TREE_TYPE (chartype); + while (TREE_CODE (chartype) == ARRAY_TYPE) + chartype = TREE_TYPE (chartype); + /* Convert a char array to an empty STRING_CST having an array + of the expected type. */ + if (!initsize) + initsize = integer_zero_node; + + unsigned HOST_WIDE_INT size = tree_to_uhwi (initsize); + init = build_string_literal (size ? 1 : 0, "", chartype, size); + init = TREE_OPERAND (init, 0); + init = TREE_OPERAND (init, 0); + + *ptr_offset = integer_zero_node; + } + + if (decl) + *decl = array; + if (TREE_CODE (init) != STRING_CST) return NULL_TREE; + *mem_size = initsize; + gcc_checking_assert (tree_to_shwi (initsize) >= TREE_STRING_LENGTH (init)); return init; diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index d576b08..fcffb98 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -759,11 +759,13 @@ gimple_fold_builtin_memory_op (gimple_stmt_iterator *gsi, dest_align = get_pointer_alignment (dest); if (tree_fits_uhwi_p (len) && compare_tree_int (len, MOVE_MAX) <= 0 - /* ??? Don't transform copies from strings with known length this - confuses the tree-ssa-strlen.c. This doesn't handle - the case in gcc.dg/strlenopt-8.c which is XFAILed for that - reason. */ - && !c_strlen (src, 2) + /* FIXME: Don't transform copies from strings with known length. + Until GCC 9 this prevented a case in gcc.dg/strlenopt-8.c + from being handled, and the case was XFAILed for that reason. + Now that it is handled and the XFAIL removed, as soon as other + strlenopt tests that rely on it for passing are adjusted, this + hack can be removed. */ + && !c_strlen (src, 1) && !((tmp_str = c_getstr (src, &tmp_len)) != NULL && memchr (tmp_str, 0, tmp_len) == NULL)) { @@ -6969,12 +6971,15 @@ fold_nonarray_ctor_reference (tree type, tree ctor, from_decl, suboff); } } - /* Memory not explicitly mentioned in constructor is 0. */ - return type ? build_zero_cst (type) : NULL_TREE; + + if (!type) + return NULL_TREE; + + return build_zero_cst (type); } /* CTOR is value initializing memory. Fold a reference of TYPE and - bit size POLY_SIZE to the memory at bit POLY_OFFSET. When SIZE + bit size POLY_SIZE to the memory at bit POLY_OFFSET. When POLY_SIZE is zero, attempt to fold a reference to the entire subobject which OFFSET refers to. This is used when folding accesses to string members of aggregates. When non-null, set *SUBOFF to diff --git a/gcc/gimple-ssa-warn-restrict.c b/gcc/gimple-ssa-warn-restrict.c index 64175f2..cbfc478 100644 --- a/gcc/gimple-ssa-warn-restrict.c +++ b/gcc/gimple-ssa-warn-restrict.c @@ -1678,7 +1678,8 @@ maybe_diag_access_bounds (location_t loc, gimple *call, tree func, int strict, if (!warn_array_bounds) return false; - if (ref.ref && TREE_NO_WARNING (ref.ref)) + if (TREE_NO_WARNING (ref.ptr) + || (ref.ref && TREE_NO_WARNING (ref.ref))) return false; if (EXPR_HAS_LOCATION (ref.ptr)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 67ff3dc..a7c4ec3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2019-08-22 Martin Sebor + + PR middle-end/91490 + * c-c++-common/Warray-bounds-7.c: New test. + * gcc.dg/Warray-bounds-39.c: Expect either -Warray-bounds or + -Wstringop-overflow. + * gcc.dg/strlenopt-78.c: New test. + 2019-08-22 Rainer Orth * gcc.target/i386/minmax-4.c: Add -mno-stackrealign to dg-options. diff --git a/gcc/testsuite/c-c++-common/Warray-bounds-7.c b/gcc/testsuite/c-c++-common/Warray-bounds-7.c new file mode 100644 index 0000000..668e809 --- /dev/null +++ b/gcc/testsuite/c-c++-common/Warray-bounds-7.c @@ -0,0 +1,107 @@ +/* PR middle-end/91490 - bogus argument missing terminating nul warning + on strlen of a flexible array member + { dg-do compile } + { dg-options "-Wall -ftrack-macro-expansion=0" } */ + +#define INT_MAX __INT_MAX__ +#define PTRDIFF_MAX __PTRDIFF_MAX__ +#define SIZE_MAX __SIZE_MAX__ + +struct A0 { char n, a[0]; }; +struct A1 { char n, a[1]; }; +struct Ax { char n, a[]; }; + +const struct A0 a0 = { }; +const struct A0 a0_0 = { 0 }; +const struct A0 a0_0_ = { 0, { } }; + +const struct A0 a1 = { }; +const struct A0 a1_0 = { 0 }; +const struct A0 a1_0_ = { 0, { } }; + +const struct Ax ax= { }; +const struct Ax ax_0 = { 0 }; +const struct Ax ax_0_ = { 0, { } }; + +void sink (unsigned); + +#define T(x) sink (__builtin_strlen (x)) + +void test_zero_length_array (void) +{ + T (a0.a); // { dg-warning "\\\[-Warray-bounds" } + T (a0.a - 1); // { dg-warning "\\\[-Warray-bounds" } + T (a0.a + 1); // { dg-warning "\\\[-Warray-bounds" } + T (a0.a + 9); // { dg-warning "\\\[-Warray-bounds" } + T (a0.a + INT_MAX); // { dg-warning "\\\[-Warray-bounds" } + T (a0.a + PTRDIFF_MAX); // { dg-warning "\\\[-Warray-bounds" } + T (a0.a + SIZE_MAX); // { dg-warning "\\\[-Warray-bounds" } + + T (a0_0.a); // { dg-warning "\\\[-Warray-bounds" } + T (a0_0.a - 1); // { dg-warning "\\\[-Warray-bounds" } + T (a0_0.a + 1); // { dg-warning "\\\[-Warray-bounds" } + T (a0_0.a + 9); // { dg-warning "\\\[-Warray-bounds" } + T (a0_0.a + INT_MAX); // { dg-warning "\\\[-Warray-bounds" } + T (a0_0.a + PTRDIFF_MAX); // { dg-warning "\\\[-Warray-bounds" } + T (a0_0.a + SIZE_MAX); // { dg-warning "\\\[-Warray-bounds" } + + T (a0_0_.a); // { dg-warning "\\\[-Warray-bounds" } + T (a0_0_.a - 1); // { dg-warning "\\\[-Warray-bounds" } + T (a0_0_.a + 1); // { dg-warning "\\\[-Warray-bounds" } + T (a0_0_.a + 9); // { dg-warning "\\\[-Warray-bounds" } + T (a0_0_.a + INT_MAX); // { dg-warning "\\\[-Warray-bounds" } + T (a0_0_.a + PTRDIFF_MAX); // { dg-warning "\\\[-Warray-bounds" } + T (a0_0_.a + SIZE_MAX); // { dg-warning "\\\[-Warray-bounds" } +} + +void test_one_element_array (void) +{ + T (a1.a - 1); // { dg-warning "\\\[-Warray-bounds" } + T (a1.a + 1); // { dg-warning "\\\[-Warray-bounds" } + T (a1.a + 9); // { dg-warning "\\\[-Warray-bounds" } + T (a1.a + INT_MAX); // { dg-warning "\\\[-Warray-bounds" } + T (a1.a + PTRDIFF_MAX); // { dg-warning "\\\[-Warray-bounds" } + T (a1.a + SIZE_MAX); // { dg-warning "\\\[-Warray-bounds" } + + T (a1_0.a - 1); // { dg-warning "\\\[-Warray-bounds" } + T (a1_0.a + 1); // { dg-warning "\\\[-Warray-bounds" } + T (a1_0.a + 9); // { dg-warning "\\\[-Warray-bounds" } + T (a1_0.a + INT_MAX); // { dg-warning "\\\[-Warray-bounds" } + T (a1_0.a + PTRDIFF_MAX); // { dg-warning "\\\[-Warray-bounds" } + T (a1_0.a + SIZE_MAX); // { dg-warning "\\\[-Warray-bounds" } + + T (a1_0_.a - 1); // { dg-warning "\\\[-Warray-bounds" } + T (a1_0_.a + 1); // { dg-warning "\\\[-Warray-bounds" } + T (a1_0_.a + 9); // { dg-warning "\\\[-Warray-bounds" } + T (a1_0_.a + INT_MAX); // { dg-warning "\\\[-Warray-bounds" } + T (a1_0_.a + PTRDIFF_MAX); // { dg-warning "\\\[-Warray-bounds" } + T (a1_0_.a + SIZE_MAX); // { dg-warning "\\\[-Warray-bounds" } +} + +void test_flexible_array_member (void) +{ + T (ax.a); // { dg-warning "\\\[-Warray-bounds" } + T (ax.a - 1); // { dg-warning "\\\[-Warray-bounds" } + T (ax.a + 1); // { dg-warning "\\\[-Warray-bounds" } + T (ax.a + 9); // { dg-warning "\\\[-Warray-bounds" } + T (ax.a + INT_MAX); // { dg-warning "\\\[-Warray-bounds" } + T (ax.a + PTRDIFF_MAX); // { dg-warning "\\\[-Warray-bounds" } + T (ax.a + SIZE_MAX); // { dg-warning "\\\[-Warray-bounds" } + + T (ax_0.a); // { dg-warning "\\\[-Warray-bounds" } + T (ax_0.a - 1); // { dg-warning "\\\[-Warray-bounds" } + T (ax_0.a + 1); // { dg-warning "\\\[-Warray-bounds" } + T (ax_0.a + 9); // { dg-warning "\\\[-Warray-bounds" } + T (ax_0.a + INT_MAX); // { dg-warning "\\\[-Warray-bounds" } + T (ax_0.a + PTRDIFF_MAX); // { dg-warning "\\\[-Warray-bounds" } + T (ax_0.a + SIZE_MAX); // { dg-warning "\\\[-Warray-bounds" } + + T (ax_0_.a); // { dg-warning "\\\[-Warray-bounds" } + T (ax_0_.a - 1); // { dg-warning "\\\[-Warray-bounds" } + T (ax_0_.a + 1); // { dg-warning "\\\[-Warray-bounds" } + T (ax_0_.a + 9); // { dg-warning "\\\[-Warray-bounds" } + T (ax_0_.a + INT_MAX); // { dg-warning "\\\[-Warray-bounds" } + T (ax_0_.a + PTRDIFF_MAX); // { dg-warning "\\\[-Warray-bounds" } + T (ax_0_.a + SIZE_MAX); // { dg-warning "\\\[-Warray-bounds" } +} + diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-39.c b/gcc/testsuite/gcc.dg/Warray-bounds-39.c index 6a441c7..ca42af8 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-39.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-39.c @@ -21,65 +21,65 @@ char d[4]; void* test_memcpy_s0_1 (void *d) { - return memcpy (d, s0, 1); /* { dg-warning "\\\[-Warray-bounds" } */ + return memcpy (d, s0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ } void* test_memcpy_s0_2 (void *d) { - return memcpy (d, s0, 2); /* { dg-warning "\\\[-Warray-bounds" } */ + return memcpy (d, s0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ } void* test_memcpy_s0_0_1 (void *d) { - return memcpy (d, s0_0, 1); /* { dg-warning "\\\[-Warray-bounds" } */ + return memcpy (d, s0_0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ } void* test_memcpy_s0_0_2 (void *d) { - return memcpy (d, s0_0, 2); /* { dg-warning "\\\[-Warray-bounds" } */ + return memcpy (d, s0_0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ } void* test_memcpy_s0_1_1 (void *d) { - return memcpy (d, s0_1, 1); /* { dg-warning "\\\[-Warray-bounds" } */ + return memcpy (d, s0_1, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ } void* test_memcpy_s0_1_2 (void *d) { - return memcpy (d, s0_1, 2); /* { dg-warning "\\\[-Warray-bounds" } */ + return memcpy (d, s0_1, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ } void* test_memcpy_s1_0_1 (void *d) { - return memcpy (d, s1_0, 1); /* { dg-warning "\\\[-Warray-bounds" } */ + return memcpy (d, s1_0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ } void* test_memcpy_s1_0_2 (void *d) { - return memcpy (d, s1_0, 2); /* { dg-warning "\\\[-Warray-bounds" } */ + return memcpy (d, s1_0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ } void* test_memmove_s0_1 (void *d) { - return memmove (d, s0, 1); /* { dg-warning "\\\[-Warray-bounds" } */ + return memmove (d, s0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ } void* test_memmove_s0_2 (void *d) { - return memmove (d, s0, 2); /* { dg-warning "\\\[-Warray-bounds" } */ + return memmove (d, s0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ } void* test_memmove_s0_0_1 (void *d) { - return memmove (d, s0_0, 1); /* { dg-warning "\\\[-Warray-bounds" } */ + return memmove (d, s0_0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ } void* test_memmove_s0_0_2 (void *d) { - return memmove (d, s0_0, 2); /* { dg-warning "\\\[-Warray-bounds" } */ + return memmove (d, s0_0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ } @@ -92,57 +92,57 @@ const struct Empty e1_0[1][0] = { }; void* test_memcpy_e_1 (void *d) { - return memcpy (d, &e, 1); /* { dg-warning "\\\[-Warray-bounds" } */ + return memcpy (d, &e, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ } void* test_memcpy_e0_1 (void *d) { - return memcpy (d, e0, 1); /* { dg-warning "\\\[-Warray-bounds" } */ + return memcpy (d, e0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ } void* test_memcpy_e0_0_1 (void *d) { - return memcpy (d, e0_0, 1); /* { dg-warning "\\\[-Warray-bounds" } */ + return memcpy (d, e0_0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ } void* test_memcpy_e0_1_1 (void *d) { - return memcpy (d, e0_1, 1); /* { dg-warning "\\\[-Warray-bounds" } */ + return memcpy (d, e0_1, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ } void* test_memcpy_e1_0_1 (void *d) { - return memcpy (d, e1_0, 1); /* { dg-warning "\\\[-Warray-bounds" } */ + return memcpy (d, e1_0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ } char* test_strcpy_s0 (char *d) { - return strcpy (d, s0); /* { dg-warning "\\\[-Warray-bounds" "pr88991" { xfail *-*-* } } */ + return strcpy (d, s0); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ } char* test_strcpy_s0_0 (char *d) { - return strcpy (d, s0_0[0]); /* { dg-warning "\\\[-Warray-bounds" "pr88991" { xfail *-*-* } } */ + return strcpy (d, s0_0[0]); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr88991" { xfail *-*-* } } */ } char* test_strncpy_s0_1 (char *d) { - return strncpy (d, s0, 1); /* { dg-warning "\\\[-Warray-bounds" "pr88991" { xfail *-*-* } } */ + return strncpy (d, s0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ } char* test_strncpy_s0_2 (char *d) { - return strncpy (d, s0, 2); /* { dg-warning "\\\[-Warray-bounds" "pr88991" { xfail *-*-* } } */ + return strncpy (d, s0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */ } char* test_strncpy_s0_0_1 (char *d) { - return strncpy (d, s0_0[0], 1); /* { dg-warning "\\\[-Warray-bounds" "pr88991" { xfail *-*-* } } */ + return strncpy (d, s0_0[0], 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr88991" { xfail *-*-* } } */ } char* test_strncpy_s0_0_2 (char *d) { - return strncpy (d, s0_0[0], 2); /* { dg-warning "\\\[-Warray-bounds" "pr88991" { xfail *-*-* } } */ + return strncpy (d, s0_0[0], 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr88991" { xfail *-*-* } } */ } diff --git a/gcc/testsuite/gcc.dg/strlenopt-78.c b/gcc/testsuite/gcc.dg/strlenopt-78.c new file mode 100644 index 0000000..c028723 --- /dev/null +++ b/gcc/testsuite/gcc.dg/strlenopt-78.c @@ -0,0 +1,166 @@ +/* PR middle-end/91490 - bogus argument missing terminating nul warning + on strlen of a flexible array member + Verify that strlen calls with a flexible array member (and its common + forms) of declaraed objects are folded. + { dg-do compile } + { dg-options "-Wall -fdump-tree-gimple" } */ + +#include "strlenopt.h" + +extern void* memchr (const void*, int, size_t); + +struct A1 { char n, a[1]; }; +struct A2 { char n, a[2]; }; +struct A3 { char n, a[3]; }; +struct Ax { char n, a[]; }; + +const struct A1 a1_0 = { 0 }; +const struct A1 a1_0_ = { 0, { } }; +const struct A1 a1_0_0 = { 0, { 0 } }; + +const struct A2 a2_1_ = { 1, { } }; +const struct A2 a2_1_1 = { 1, { 1 } }; +const struct A2 a2_1_1_0 = { 1, { 1, 0 } }; + +const struct A3 aa3_1_[2] = { { 1 } }; + +const struct Ax ax = { 3, { 3, 2, 1, 0 } }; + +struct BxA1 { int n; struct A1 a[]; }; +struct BxA2 { int n; struct A2 a[]; }; + +const struct BxA2 bx = { 2, { { 2, { 2, 1 } }, { 2, { 1, 0 } } } }; + +#if 0 + +// Not implemented yet. + +int mchr1, mchr1__, mchr1_0, mchr2_1, mchr2, mchr2_1_0, mchrax, mchrbx; + +void test_memchr_flexarray (void) +{ + mchr1 = 0 != memchr (&a1_0, '1', sizeof a1_0); + mchr1__ = 0 != memchr (&a1_0_, '2', sizeof a1_0_); + mchr1_0 = 0 != memchr (&a1_0_0, '3', sizeof a1_0_0); + + mchr2 = 0 != memchr (&a2_1_, '4', sizeof a2_1_); + mchr2_1 = 0 != memchr (&a2_1_1, '\001', sizeof a2_1_1); + mchr2_1_0 = 0 != memchr (&a2_1_1_0, '\001', sizeof a2_1_1_0); + + mchrax = (const char*)&ax + sizeof ax - 1 == memchr (&ax, '\001', sizeof ax); + mchrbx = (const char*)&bx + sizeof bx - 1 == memchr (&bx, '\001', sizeof bx); +} + +#endif + + +int schr1, schr1__, schr1_0, schr2_1, schr2, schr2_1_0, schrax, schrbx; + +void test_strchr_flexarray (void) +{ + schr1 = 0 != strchr (a1_0.a, '1'); + schr1__ = 0 != strchr (a1_0_.a, '2'); + schr1_0 = 0 != strchr (a1_0_0.a, '3'); + + schr2 = 0 != strchr (a2_1_.a, '4'); + schr2_1 = 0 != strchr (a2_1_1.a, '\001'); + schr2_1_0 = 0 != strchr (a2_1_1_0.a, '\001'); + + schrax = 0 != strchr (ax.a, '\001'); + schrbx = 0 != strchr (bx.a[1].a, '\0'); + + /* { dg-final { scan-tree-dump "schr1 = 0;" "gimple" } } + { dg-final { scan-tree-dump "schr1__ = 0;" "gimple" } } + { dg-final { scan-tree-dump "schr1_0 = 0;" "gimple" } } + { dg-final { scan-tree-dump "schr2 = 0;" "gimple" } } + { dg-final { scan-tree-dump "schr2_1 = 1;" "gimple" } } + { dg-final { scan-tree-dump "schr2_1_0 = 1;" "gimple" } } + { dg-final { scan-tree-dump "schrax = 1;" "gimple" } } + { dg-final { scan-tree-dump "schrbx = 1;" "gimple" } } */ +} + + +int scmp1, scmp1__, scmp1_0, scmp2_1, scmp2, scmp2_1_0, scmpax, scmpbx; + +void test_strcmp_flexarray (void) +{ + scmp1 = 0 == strcmp (a1_0.a, "1"); + scmp1__ = 0 == strcmp (a1_0_.a, "2"); + scmp1_0 = 0 == strcmp (a1_0_0.a, "3"); + + scmp2 = 0 == strcmp (a2_1_.a, "4"); + scmp2_1 = 0 == strcmp (a2_1_1.a, "\001"); + scmp2_1_0 = 0 == strcmp (a2_1_1_0.a, "\001"); + + scmpax = 0 == strcmp (ax.a, "\003\002\001"); + scmpbx = 0 == strcmp (bx.a[1].a, "\001"); + + /* { dg-final { scan-tree-dump "scmp1 = 0;" "gimple" } } + { dg-final { scan-tree-dump "scmp1__ = 0;" "gimple" } } + { dg-final { scan-tree-dump "scmp1_0 = 0;" "gimple" } } + { dg-final { scan-tree-dump "scmp2 = 0;" "gimple" } } + { dg-final { scan-tree-dump "scmp2_1 = 1;" "gimple" } } + { dg-final { scan-tree-dump "scmp2_1_0 = 1;" "gimple" } } + { dg-final { scan-tree-dump "scmpax = 1;" "gimple" } } + { dg-final { scan-tree-dump "scmpbx = 1;" "gimple" } } */ +} + + +int len1, len1__, len1_0, len2_1, len2, len2_1_0, lenax, lenbx; + +void test_strlen_flexarray (void) +{ + len1 = strlen (a1_0.a); + len1__ = strlen (a1_0_.a); + len1_0 = strlen (a1_0_0.a); + + len2 = strlen (a2_1_.a); + len2_1 = strlen (a2_1_1.a); + len2_1_0 = strlen (a2_1_1_0.a); + + lenax = strlen (ax.a); + lenbx = strlen (bx.a[1].a); + + /* { dg-final { scan-tree-dump "len1 = 0;" "gimple" } } + { dg-final { scan-tree-dump "len1__ = 0;" "gimple" } } + { dg-final { scan-tree-dump "len1_0 = 0;" "gimple" } } + { dg-final { scan-tree-dump "len2 = 0;" "gimple" } } + { dg-final { scan-tree-dump "len2_1 = 1;" "gimple" } } + { dg-final { scan-tree-dump "len2_1_0 = 1;" "gimple" } } + { dg-final { scan-tree-dump "lenax = 3;" "gimple" } } + { dg-final { scan-tree-dump "lenbx = 1;" "gimple" } } */ +} + + +int schraa3, scmpaa3, lenaa3; + +void test_trailing_array_empty_init (void) +{ + schraa3 = ((aa3_1_[0].a == strchr (aa3_1_[0].a, 0)) + + (aa3_1_[1].a == strchr (aa3_1_[1].a, 0))); + + scmpaa3 = strcmp (aa3_1_[0].a, aa3_1_[1].a); + lenaa3 = strlen (aa3_1_[0].a) + strlen (aa3_1_[1].a); + + /* { dg-final { scan-tree-dump "schraa3 = 2;" "gimple" } } + { dg-final { scan-tree-dump "scmpaa3 = 0;" "gimple" } } + { dg-final { scan-tree-dump "lenaa3 = 0;" "gimple" } } */ +} + +union U4 { char a[4]; int i; }; +const union U4 u4[2] = { { "123" } }; + +int ulen0, ulen1; + +void test_union_init (void) +{ + ulen0 = strlen (u4[0].a); + ulen1 = strlen (u4[1].a); + + /* { dg-final { scan-tree-dump "ulen0 = 3;" "gimple" } } + { dg-final { scan-tree-dump "ulen1 = 0;" "gimple" } } */ +} + +/* { dg-final { scan-tree-dump-not "strchr *\\(" "gimple" } } + { dg-final { scan-tree-dump-not "strcmp *\\(" "gimple" } } + { dg-final { scan-tree-dump-not "strlen *\\(" "gimple" } } */ diff --git a/gcc/tree.c b/gcc/tree.c index ae29228..613efa5 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -11872,18 +11872,23 @@ build_alloca_call_expr (tree size, unsigned int align, HOST_WIDE_INT max_size) } } -/* Create a new constant string literal consisting of elements of type - ELTYPE and return a tree node representing char* pointer to it as - an ADDR_EXPR (ARRAY_REF (ELTYPE, ...)). The STRING_CST value is - the LEN bytes at STR (the representation of the string, which may +/* Create a new constant string literal of type ELTYPE[SIZE] (or LEN + if SIZE == -1) and return a tree node representing char* pointer to + it as an ADDR_EXPR (ARRAY_REF (ELTYPE, ...)). The STRING_CST value + is the LEN bytes at STR (the representation of the string, which may be wide). */ tree build_string_literal (int len, const char *str, - tree eltype /* = char_type_node */) + tree eltype /* = char_type_node */, + unsigned HOST_WIDE_INT size /* = -1 */) { tree t = build_string (len, str); - tree index = build_index_type (size_int (len - 1)); + /* Set the maximum valid index based on the string length or SIZE. */ + unsigned HOST_WIDE_INT maxidx + = (size == HOST_WIDE_INT_M1U ? len : size) - 1; + + tree index = build_index_type (size_int (maxidx)); eltype = build_type_variant (eltype, 1, 0); tree type = build_array_type (eltype, index); TREE_TYPE (t) = type; diff --git a/gcc/tree.h b/gcc/tree.h index 37f6d57..fc85572 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -4418,7 +4418,8 @@ extern tree build_call_expr_internal_loc_array (location_t, enum internal_fn, extern tree maybe_build_call_expr_loc (location_t, combined_fn, tree, int, ...); extern tree build_alloca_call_expr (tree, unsigned int, HOST_WIDE_INT); -extern tree build_string_literal (int, const char *, tree = char_type_node); +extern tree build_string_literal (int, const char *, tree = char_type_node, + unsigned HOST_WIDE_INT = HOST_WIDE_INT_M1U); /* Construct various nodes representing data types. */ -- cgit v1.1 From f99aba156210eba620b6e774543d3e0adfdf09c2 Mon Sep 17 00:00:00 2001 From: "Steven G. Kargl" Date: Thu, 22 Aug 2019 23:50:57 +0000 Subject: intrinsic.c (add_subroutines): ERRMSG is INTENT(INOUT) in co_broadcast, co_max, co_min, co_reduce, and co_sum. 2019-08-22 Steven G. Kargl * intrinsic.c (add_subroutines): ERRMSG is INTENT(INOUT) in co_broadcast, co_max, co_min, co_reduce, and co_sum. From-SVN: r274838 --- gcc/fortran/ChangeLog | 5 +++++ gcc/fortran/intrinsic.c | 10 +++++----- 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 3eca99e..69ec726 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,8 @@ +2019-08-22 Steven G. Kargl + + * intrinsic.c (add_subroutines): ERRMSG is INTENT(INOUT) in + co_broadcast, co_max, co_min, co_reduce, and co_sum. + 2019-08-20 Mark Eggleston PR fortran/89236 diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c index c35ea73..1b6eeda 100644 --- a/gcc/fortran/intrinsic.c +++ b/gcc/fortran/intrinsic.c @@ -3691,7 +3691,7 @@ add_subroutines (void) a, BT_REAL, dr, REQUIRED, INTENT_INOUT, "source_image", BT_INTEGER, di, REQUIRED, INTENT_IN, stat, BT_INTEGER, di, OPTIONAL, INTENT_OUT, - errmsg, BT_CHARACTER, dc, OPTIONAL, INTENT_OUT); + errmsg, BT_CHARACTER, dc, OPTIONAL, INTENT_INOUT); add_sym_4s ("co_max", GFC_ISYM_CO_MAX, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_F2018, @@ -3699,7 +3699,7 @@ add_subroutines (void) a, BT_REAL, dr, REQUIRED, INTENT_INOUT, result_image, BT_INTEGER, di, OPTIONAL, INTENT_IN, stat, BT_INTEGER, di, OPTIONAL, INTENT_OUT, - errmsg, BT_CHARACTER, dc, OPTIONAL, INTENT_OUT); + errmsg, BT_CHARACTER, dc, OPTIONAL, INTENT_INOUT); add_sym_4s ("co_min", GFC_ISYM_CO_MIN, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_F2018, @@ -3707,7 +3707,7 @@ add_subroutines (void) a, BT_REAL, dr, REQUIRED, INTENT_INOUT, result_image, BT_INTEGER, di, OPTIONAL, INTENT_IN, stat, BT_INTEGER, di, OPTIONAL, INTENT_OUT, - errmsg, BT_CHARACTER, dc, OPTIONAL, INTENT_OUT); + errmsg, BT_CHARACTER, dc, OPTIONAL, INTENT_INOUT); add_sym_4s ("co_sum", GFC_ISYM_CO_SUM, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_F2018, @@ -3715,7 +3715,7 @@ add_subroutines (void) a, BT_REAL, dr, REQUIRED, INTENT_INOUT, result_image, BT_INTEGER, di, OPTIONAL, INTENT_IN, stat, BT_INTEGER, di, OPTIONAL, INTENT_OUT, - errmsg, BT_CHARACTER, dc, OPTIONAL, INTENT_OUT); + errmsg, BT_CHARACTER, dc, OPTIONAL, INTENT_INOUT); add_sym_5s ("co_reduce", GFC_ISYM_CO_REDUCE, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_F2018, @@ -3724,7 +3724,7 @@ add_subroutines (void) "operator", BT_INTEGER, di, REQUIRED, INTENT_IN, result_image, BT_INTEGER, di, OPTIONAL, INTENT_IN, stat, BT_INTEGER, di, OPTIONAL, INTENT_OUT, - errmsg, BT_CHARACTER, dc, OPTIONAL, INTENT_OUT); + errmsg, BT_CHARACTER, dc, OPTIONAL, INTENT_INOUT); /* The following subroutine is internally used for coarray libray functions. -- cgit v1.1 From ab3dd132a12c33815912a236c961a5c0d40d1818 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Fri, 23 Aug 2019 00:06:25 +0000 Subject: PR c++/91304 - prefix attributes ignored in condition. * parser.c (cp_parser_condition): Handle prefix attributes. * g++.dg/cpp0x/gen-attrs-70.C: New test. From-SVN: r274839 --- gcc/cp/ChangeLog | 5 +++++ gcc/cp/parser.c | 6 +++++- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/cpp0x/gen-attrs-70.C | 13 +++++++++++++ 4 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/gen-attrs-70.C (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d47c2f7..d2b9623 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2019-08-22 Marek Polacek + + PR c++/91304 - prefix attributes ignored in condition. + * parser.c (cp_parser_condition): Handle prefix attributes. + 2019-08-21 Richard Sandiford PR c++/91505 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index dbbfe1d..b410a6c 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -12066,6 +12066,10 @@ cp_parser_condition (cp_parser* parser) /* Restore the saved message. */ parser->type_definition_forbidden_message = saved_message; + /* Gather the attributes that were provided with the + decl-specifiers. */ + tree prefix_attributes = type_specifiers.attributes; + cp_parser_maybe_commit_to_declaration (parser, type_specifiers.any_specifiers_p); @@ -12116,7 +12120,7 @@ cp_parser_condition (cp_parser* parser) /* Create the declaration. */ decl = start_decl (declarator, &type_specifiers, /*initialized_p=*/true, - attributes, /*prefix_attributes=*/NULL_TREE, + attributes, prefix_attributes, &pushed_scope); /* Parse the initializer. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a7c4ec3..ad5aa69 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-08-22 Marek Polacek + + PR c++/91304 - prefix attributes ignored in condition. + * g++.dg/cpp0x/gen-attrs-70.C: New test. + 2019-08-22 Martin Sebor PR middle-end/91490 diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-70.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-70.C new file mode 100644 index 0000000..90a2e97 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-70.C @@ -0,0 +1,13 @@ +// PR c++/91304 - prefix attributes ignored in condition. +// { dg-do compile { target c++11 } } +// { dg-additional-options "-Wall -Wextra" } + +int f(); + +void g() +{ + if ([[maybe_unused]] int i = f()) { } + if ([[deprecated]] int i = f()) { i = 10; } // { dg-warning ".i. is deprecated" } + if (int i [[maybe_unused]] = f()) { } + if (int i [[deprecated]] = f()) { i = 10; } // { dg-warning ".i. is deprecated" } +} -- cgit v1.1 From 1783e319bffa198a14675c34b45272f13c55b3c5 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Fri, 23 Aug 2019 00:16:54 +0000 Subject: Daily bump. From-SVN: r274843 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 63ca370..c2ad9278 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20190822 +20190823 -- cgit v1.1 From 1628b2faf0011322be6ea4ad7b2484f720c595bf Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Fri, 23 Aug 2019 09:48:34 +0200 Subject: Clean up value-prof.c a bit. 2019-08-23 Martin Liska * profile.c (instrument_values): Do not set 0 as last argument. * tree-profile.c (gimple_gen_interval_profiler): Remove last argument. (gimple_gen_pow2_profiler): Likewise. (gimple_gen_topn_values_profiler): Likewise. (gimple_gen_ic_profiler): Likewise. (gimple_gen_time_profiler): Likewise. (gimple_gen_average_profiler): Likewise. (gimple_gen_ior_profiler): Likewise. * value-prof.c (dump_histogram_value): Use default in switch statement instead of HIST_TYPE_MAX. (stream_in_histogram_value): Likewise. (gimple_duplicate_stmt_histograms): Do not use NULL for implicitly set arguments. (gimple_divmod_values_to_profile): Do not use reserve+quick_push. (gimple_indirect_call_to_profile): Likewise. (gimple_find_values_to_profile): Use implicit function call arguments. * value-prof.h (gimple_alloc_histogram_value): Set default values. (gimple_gen_interval_profiler): Remove last argument. (gimple_gen_pow2_profiler): Likewise. (gimple_gen_topn_values_profiler): Likewise. (gimple_gen_ic_profiler): Likewise. (gimple_gen_time_profiler): Likewise. (gimple_gen_average_profiler): Likewise. (gimple_gen_ior_profiler): Likewise. From-SVN: r274844 --- gcc/ChangeLog | 32 ++++++++++++++++++++++++++++++++ gcc/profile.c | 14 +++++++------- gcc/tree-profile.c | 36 +++++++++++++++++------------------- gcc/value-prof.c | 36 ++++++++++++++++-------------------- gcc/value-prof.h | 18 +++++++++--------- 5 files changed, 81 insertions(+), 55 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2651ce2..8e7ab45 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,35 @@ +2019-08-23 Martin Liska + + * profile.c (instrument_values): Do not set + 0 as last argument. + * tree-profile.c (gimple_gen_interval_profiler): Remove + last argument. + (gimple_gen_pow2_profiler): Likewise. + (gimple_gen_topn_values_profiler): Likewise. + (gimple_gen_ic_profiler): Likewise. + (gimple_gen_time_profiler): Likewise. + (gimple_gen_average_profiler): Likewise. + (gimple_gen_ior_profiler): Likewise. + * value-prof.c (dump_histogram_value): Use default + in switch statement instead of HIST_TYPE_MAX. + (stream_in_histogram_value): Likewise. + (gimple_duplicate_stmt_histograms): Do not + use NULL for implicitly set arguments. + (gimple_divmod_values_to_profile): Do not use + reserve+quick_push. + (gimple_indirect_call_to_profile): Likewise. + (gimple_find_values_to_profile): Use implicit + function call arguments. + * value-prof.h (gimple_alloc_histogram_value): + Set default values. + (gimple_gen_interval_profiler): Remove last argument. + (gimple_gen_pow2_profiler): Likewise. + (gimple_gen_topn_values_profiler): Likewise. + (gimple_gen_ic_profiler): Likewise. + (gimple_gen_time_profiler): Likewise. + (gimple_gen_average_profiler): Likewise. + (gimple_gen_ior_profiler): Likewise. + 2019-08-22 Martin Sebor PR middle-end/91490 diff --git a/gcc/profile.c b/gcc/profile.c index 6c8127a..8d39a7d 100644 --- a/gcc/profile.c +++ b/gcc/profile.c @@ -160,31 +160,31 @@ instrument_values (histogram_values values) switch (hist->type) { case HIST_TYPE_INTERVAL: - gimple_gen_interval_profiler (hist, t, 0); + gimple_gen_interval_profiler (hist, t); break; case HIST_TYPE_POW2: - gimple_gen_pow2_profiler (hist, t, 0); + gimple_gen_pow2_profiler (hist, t); break; case HIST_TYPE_TOPN_VALUES: - gimple_gen_topn_values_profiler (hist, t, 0); + gimple_gen_topn_values_profiler (hist, t); break; case HIST_TYPE_INDIR_CALL: - gimple_gen_ic_profiler (hist, t, 0); + gimple_gen_ic_profiler (hist, t); break; case HIST_TYPE_AVERAGE: - gimple_gen_average_profiler (hist, t, 0); + gimple_gen_average_profiler (hist, t); break; case HIST_TYPE_IOR: - gimple_gen_ior_profiler (hist, t, 0); + gimple_gen_ior_profiler (hist, t); break; case HIST_TYPE_TIME_PROFILE: - gimple_gen_time_profiler (t, 0); + gimple_gen_time_profiler (t); break; default: diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c index 554a8c9..4c1ead5 100644 --- a/gcc/tree-profile.c +++ b/gcc/tree-profile.c @@ -293,11 +293,11 @@ prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value) tag of the section for counters, BASE is offset of the counter position. */ void -gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base) +gimple_gen_interval_profiler (histogram_value value, unsigned tag) { gimple *stmt = value->hvalue.stmt; gimple_stmt_iterator gsi = gsi_for_stmt (stmt); - tree ref = tree_coverage_counter_ref (tag, base), ref_ptr; + tree ref = tree_coverage_counter_ref (tag, 0), ref_ptr; gcall *call; tree val; tree start = build_int_cst_type (integer_type_node, @@ -316,14 +316,14 @@ gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base /* Output instructions as GIMPLE trees to increment the power of two histogram counter. VALUE is the expression whose value is profiled. TAG is the tag - of the section for counters, BASE is offset of the counter position. */ + of the section for counters. */ void -gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base) +gimple_gen_pow2_profiler (histogram_value value, unsigned tag) { gimple *stmt = value->hvalue.stmt; gimple_stmt_iterator gsi = gsi_for_stmt (stmt); - tree ref_ptr = tree_coverage_counter_addr (tag, base); + tree ref_ptr = tree_coverage_counter_addr (tag, 0); gcall *call; tree val; @@ -336,15 +336,14 @@ gimple_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base) /* Output instructions as GIMPLE trees for code to find the most N common values. VALUE is the expression whose value is profiled. TAG is the tag - of the section for counters, BASE is offset of the counter position. */ + of the section for counters. */ void -gimple_gen_topn_values_profiler (histogram_value value, unsigned tag, - unsigned base) +gimple_gen_topn_values_profiler (histogram_value value, unsigned tag) { gimple *stmt = value->hvalue.stmt; gimple_stmt_iterator gsi = gsi_for_stmt (stmt); - tree ref_ptr = tree_coverage_counter_addr (tag, base); + tree ref_ptr = tree_coverage_counter_addr (tag, 0); gcall *call; tree val; @@ -359,17 +358,16 @@ gimple_gen_topn_values_profiler (histogram_value value, unsigned tag, /* Output instructions as GIMPLE trees for code to find the most common called function in indirect call. VALUE is the call expression whose indirect callee is profiled. - TAG is the tag of the section for counters, BASE is offset of the - counter position. */ + TAG is the tag of the section for counters. */ void -gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base) +gimple_gen_ic_profiler (histogram_value value, unsigned tag) { tree tmp1; gassign *stmt1, *stmt2, *stmt3; gimple *stmt = value->hvalue.stmt; gimple_stmt_iterator gsi = gsi_for_stmt (stmt); - tree ref_ptr = tree_coverage_counter_addr (tag, base); + tree ref_ptr = tree_coverage_counter_addr (tag, 0); ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr, true, NULL_TREE, true, GSI_SAME_STMT); @@ -485,7 +483,7 @@ gimple_gen_ic_func_profiler (void) counter position and GSI is the iterator we place the counter. */ void -gimple_gen_time_profiler (unsigned tag, unsigned base) +gimple_gen_time_profiler (unsigned tag) { tree type = get_gcov_type (); basic_block entry = ENTRY_BLOCK_PTR_FOR_FN (cfun); @@ -504,7 +502,7 @@ gimple_gen_time_profiler (unsigned tag, unsigned base) e->probability = true_edge->probability.invert (); gimple_stmt_iterator gsi = gsi_start_bb (cond_bb); - tree original_ref = tree_coverage_counter_ref (tag, base); + tree original_ref = tree_coverage_counter_ref (tag, 0); tree ref = force_gimple_operand_gsi (&gsi, original_ref, true, NULL_TREE, true, GSI_SAME_STMT); tree one = build_int_cst (type, 1); @@ -564,11 +562,11 @@ gimple_gen_time_profiler (unsigned tag, unsigned base) tag of the section for counters, BASE is offset of the counter position. */ void -gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base) +gimple_gen_average_profiler (histogram_value value, unsigned tag) { gimple *stmt = value->hvalue.stmt; gimple_stmt_iterator gsi = gsi_for_stmt (stmt); - tree ref_ptr = tree_coverage_counter_addr (tag, base); + tree ref_ptr = tree_coverage_counter_addr (tag, 0); gcall *call; tree val; @@ -585,11 +583,11 @@ gimple_gen_average_profiler (histogram_value value, unsigned tag, unsigned base) tag of the section for counters, BASE is offset of the counter position. */ void -gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base) +gimple_gen_ior_profiler (histogram_value value, unsigned tag) { gimple *stmt = value->hvalue.stmt; gimple_stmt_iterator gsi = gsi_for_stmt (stmt); - tree ref_ptr = tree_coverage_counter_addr (tag, base); + tree ref_ptr = tree_coverage_counter_addr (tag, 0); gcall *call; tree val; diff --git a/gcc/value-prof.c b/gcc/value-prof.c index 00ede8d..55ea097 100644 --- a/gcc/value-prof.c +++ b/gcc/value-prof.c @@ -300,7 +300,7 @@ dump_histogram_value (FILE *dump_file, histogram_value hist) fprintf (dump_file, "Time profile time:%" PRId64 ".\n", (int64_t) hist->hvalue.counters[0]); break; - case HIST_TYPE_MAX: + default: gcc_unreachable (); } } @@ -360,7 +360,7 @@ stream_in_histogram_value (class lto_input_block *ib, gimple *stmt) bp = streamer_read_bitpack (ib); type = bp_unpack_enum (&bp, hist_type, HIST_TYPE_MAX); next = bp_unpack_value (&bp, 1); - new_val = gimple_alloc_histogram_value (cfun, type, stmt, NULL); + new_val = gimple_alloc_histogram_value (cfun, type, stmt); switch (type) { case HIST_TYPE_INTERVAL: @@ -384,7 +384,7 @@ stream_in_histogram_value (class lto_input_block *ib, gimple *stmt) ncounters = 1; break; - case HIST_TYPE_MAX: + default: gcc_unreachable (); } new_val->hvalue.counters = XNEWVAR (gcov_type, sizeof (*new_val->hvalue.counters) * ncounters); @@ -429,7 +429,7 @@ gimple_duplicate_stmt_histograms (struct function *fun, gimple *stmt, histogram_value val; for (val = gimple_histogram_value (ofun, ostmt); val != NULL; val = val->hvalue.next) { - histogram_value new_val = gimple_alloc_histogram_value (fun, val->type, NULL, NULL); + histogram_value new_val = gimple_alloc_histogram_value (fun, val->type); memcpy (new_val, val, sizeof (*val)); new_val->hvalue.stmt = stmt; new_val->hvalue.counters = XNEWVAR (gcov_type, sizeof (*new_val->hvalue.counters) * new_val->n_counters); @@ -1791,14 +1791,12 @@ gimple_divmod_values_to_profile (gimple *stmt, histogram_values *values) divisor = gimple_assign_rhs2 (stmt); op0 = gimple_assign_rhs1 (stmt); - values->reserve (3); - if (TREE_CODE (divisor) == SSA_NAME) /* Check for the case where the divisor is the same value most of the time. */ - values->quick_push (gimple_alloc_histogram_value (cfun, - HIST_TYPE_TOPN_VALUES, - stmt, divisor)); + values->safe_push (gimple_alloc_histogram_value (cfun, + HIST_TYPE_TOPN_VALUES, + stmt, divisor)); /* For mod, check whether it is not often a noop (or replaceable by a few subtractions). */ @@ -1808,16 +1806,15 @@ gimple_divmod_values_to_profile (gimple *stmt, histogram_values *values) { tree val; /* Check for a special case where the divisor is power of 2. */ - values->quick_push (gimple_alloc_histogram_value (cfun, - HIST_TYPE_POW2, - stmt, divisor)); - + values->safe_push (gimple_alloc_histogram_value (cfun, + HIST_TYPE_POW2, + stmt, divisor)); val = build2 (TRUNC_DIV_EXPR, type, op0, divisor); hist = gimple_alloc_histogram_value (cfun, HIST_TYPE_INTERVAL, stmt, val); hist->hdata.intvl.int_start = 0; hist->hdata.intvl.steps = 2; - values->quick_push (hist); + values->safe_push (hist); } return; @@ -1840,11 +1837,9 @@ gimple_indirect_call_to_profile (gimple *stmt, histogram_values *values) return; callee = gimple_call_fn (stmt); - - values->reserve (3); - - values->quick_push (gimple_alloc_histogram_value (cfun, HIST_TYPE_INDIR_CALL, - stmt, callee)); + histogram_value v = gimple_alloc_histogram_value (cfun, HIST_TYPE_INDIR_CALL, + stmt, callee); + values->safe_push (v); return; } @@ -1911,7 +1906,8 @@ gimple_find_values_to_profile (histogram_values *values) for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) gimple_values_to_profile (gsi_stmt (gsi), values); - values->safe_push (gimple_alloc_histogram_value (cfun, HIST_TYPE_TIME_PROFILE, 0, 0)); + values->safe_push (gimple_alloc_histogram_value (cfun, + HIST_TYPE_TIME_PROFILE)); FOR_EACH_VEC_ELT (*values, i, hist) { diff --git a/gcc/value-prof.h b/gcc/value-prof.h index 1078722..77c06f6 100644 --- a/gcc/value-prof.h +++ b/gcc/value-prof.h @@ -73,7 +73,8 @@ extern void gimple_find_values_to_profile (histogram_values *); extern bool gimple_value_profile_transformations (void); histogram_value gimple_alloc_histogram_value (struct function *, enum hist_type, - gimple *stmt, tree); + gimple *stmt = NULL, + tree value = NULL_TREE); histogram_value gimple_histogram_value (struct function *, gimple *); histogram_value gimple_histogram_value_of_type (struct function *, gimple *, enum hist_type); @@ -97,15 +98,14 @@ bool get_nth_most_common_value (gimple *stmt, const char *counter_type, /* In tree-profile.c. */ extern void gimple_init_gcov_profiler (void); extern void gimple_gen_edge_profiler (int, edge); -extern void gimple_gen_interval_profiler (histogram_value, unsigned, unsigned); -extern void gimple_gen_pow2_profiler (histogram_value, unsigned, unsigned); -extern void gimple_gen_topn_values_profiler (histogram_value, unsigned, - unsigned); -extern void gimple_gen_ic_profiler (histogram_value, unsigned, unsigned); +extern void gimple_gen_interval_profiler (histogram_value, unsigned); +extern void gimple_gen_pow2_profiler (histogram_value, unsigned); +extern void gimple_gen_topn_values_profiler (histogram_value, unsigned); +extern void gimple_gen_ic_profiler (histogram_value, unsigned); extern void gimple_gen_ic_func_profiler (void); -extern void gimple_gen_time_profiler (unsigned, unsigned); -extern void gimple_gen_average_profiler (histogram_value, unsigned, unsigned); -extern void gimple_gen_ior_profiler (histogram_value, unsigned, unsigned); +extern void gimple_gen_time_profiler (unsigned); +extern void gimple_gen_average_profiler (histogram_value, unsigned); +extern void gimple_gen_ior_profiler (histogram_value, unsigned); extern void stream_out_histogram_value (struct output_block *, histogram_value); extern void stream_in_histogram_value (class lto_input_block *, gimple *); extern struct cgraph_node* find_func_by_profile_id (int func_id); -- cgit v1.1 From a50f4236956cbcfff1fe7c8c0ca9c8db43e3bcd5 Mon Sep 17 00:00:00 2001 From: Dennis Zhang Date: Fri, 23 Aug 2019 08:25:44 +0000 Subject: [Arm] Add support for missing CPUs This patch adds '-mcpu' options for following CPUs: Cortex-M35P, Cortex-A77, Cortex-A76AE. Related specifications are as following: https://developer.arm.com/ip-products/processors/cortex-m https://developer.arm.com/ip-products/processors/cortex-a 2019-08-23 Dennis Zhang * config/arm/arm-cpus.in (cortex-m35p): New entry. (cortex-a76ae): Likewise. (cortex-a77): Likewise * config/arm/arm-tables.opt: Regenerate. * config/arm/arm-tune.md: Likewise. * doc/invoke.texi (ARM Options): Document cortex-m35p, cortx-a76ae, cortex-a77 CPU options. From-SVN: r274845 --- gcc/ChangeLog | 10 ++++++++++ gcc/config/arm/arm-cpus.in | 31 +++++++++++++++++++++++++++++++ gcc/config/arm/arm-tables.opt | 9 +++++++++ gcc/config/arm/arm-tune.md | 5 +++-- gcc/doc/invoke.texi | 8 +++++--- 5 files changed, 58 insertions(+), 5 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8e7ab45..bd47b77 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2019-08-23 Dennis Zhang + + * config/arm/arm-cpus.in (cortex-m35p): New entry. + (cortex-a76ae): Likewise. + (cortex-a77): Likewise + * config/arm/arm-tables.opt: Regenerate. + * config/arm/arm-tune.md: Likewise. + * doc/invoke.texi (ARM Options): Document cortex-m35p, cortx-a76ae, + cortex-a77 CPU options. + 2019-08-23 Martin Liska * profile.c (instrument_values): Do not set diff --git a/gcc/config/arm/arm-cpus.in b/gcc/config/arm/arm-cpus.in index 3a55f6a..f8a3b3d 100644 --- a/gcc/config/arm/arm-cpus.in +++ b/gcc/config/arm/arm-cpus.in @@ -1331,6 +1331,28 @@ begin cpu cortex-a76 part d0b end cpu cortex-a76 +begin cpu cortex-a76ae + cname cortexa76ae + tune for cortex-a57 + tune flags LDSCHED + architecture armv8.2-a+fp16+dotprod+simd + option crypto add FP_ARMv8 CRYPTO + costs cortex_a57 + vendor 41 + part d0e +end cpu cortex-a76ae + +begin cpu cortex-a77 + cname cortexa77 + tune for cortex-a57 + tune flags LDSCHED + architecture armv8.2-a+fp16+dotprod+simd + option crypto add FP_ARMv8 CRYPTO + costs cortex_a57 + vendor 41 + part d0d +end cpu cortex-a77 + begin cpu neoverse-n1 cname neoversen1 alias !ares @@ -1379,6 +1401,15 @@ begin cpu cortex-m33 costs v7m end cpu cortex-m33 +begin cpu cortex-m35p + cname cortexm35p + tune flags LDSCHED + architecture armv8-m.main+dsp+fp + option nofp remove ALL_FP + option nodsp remove armv7em + costs v7m +end cpu cortex-m35p + # V8 R-profile implementations. begin cpu cortex-r52 cname cortexr52 diff --git a/gcc/config/arm/arm-tables.opt b/gcc/config/arm/arm-tables.opt index bba54ae..aeb5b3f 100644 --- a/gcc/config/arm/arm-tables.opt +++ b/gcc/config/arm/arm-tables.opt @@ -235,6 +235,12 @@ EnumValue Enum(processor_type) String(cortex-a76) Value( TARGET_CPU_cortexa76) EnumValue +Enum(processor_type) String(cortex-a76ae) Value( TARGET_CPU_cortexa76ae) + +EnumValue +Enum(processor_type) String(cortex-a77) Value( TARGET_CPU_cortexa77) + +EnumValue Enum(processor_type) String(neoverse-n1) Value( TARGET_CPU_neoversen1) EnumValue @@ -250,6 +256,9 @@ EnumValue Enum(processor_type) String(cortex-m33) Value( TARGET_CPU_cortexm33) EnumValue +Enum(processor_type) String(cortex-m35p) Value( TARGET_CPU_cortexm35p) + +EnumValue Enum(processor_type) String(cortex-r52) Value( TARGET_CPU_cortexr52) Enum diff --git a/gcc/config/arm/arm-tune.md b/gcc/config/arm/arm-tune.md index b9dfb66..6fa5bb2 100644 --- a/gcc/config/arm/arm-tune.md +++ b/gcc/config/arm/arm-tune.md @@ -44,7 +44,8 @@ cortexa73,exynosm1,xgene1, cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35, cortexa73cortexa53,cortexa55,cortexa75, - cortexa76,neoversen1,cortexa75cortexa55, - cortexa76cortexa55,cortexm23,cortexm33, + cortexa76,cortexa76ae,cortexa77, + neoversen1,cortexa75cortexa55,cortexa76cortexa55, + cortexm23,cortexm33,cortexm35p, cortexr52" (const (symbol_ref "((enum attr_tune) arm_tune)"))) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 08e6b52..7a35684 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -17650,10 +17650,12 @@ Permissible names are: @samp{arm7tdmi}, @samp{arm7tdmi-s}, @samp{arm710t}, @samp{cortex-a9}, @samp{cortex-a12}, @samp{cortex-a15}, @samp{cortex-a17}, @samp{cortex-a32}, @samp{cortex-a35}, @samp{cortex-a53}, @samp{cortex-a55}, @samp{cortex-a57}, @samp{cortex-a72}, @samp{cortex-a73}, @samp{cortex-a75}, -@samp{cortex-a76}, @samp{ares}, @samp{cortex-r4}, @samp{cortex-r4f}, +@samp{cortex-a76}, @samp{cortex-a76ae}, @samp{cortex-a77}, +@samp{ares}, @samp{cortex-r4}, @samp{cortex-r4f}, @samp{cortex-r5}, @samp{cortex-r7}, @samp{cortex-r8}, @samp{cortex-r52}, @samp{cortex-m0}, @samp{cortex-m0plus}, @samp{cortex-m1}, @samp{cortex-m3}, @samp{cortex-m4}, @samp{cortex-m7}, @samp{cortex-m23}, @samp{cortex-m33}, +@samp{cortex-m35p}, @samp{cortex-m1.small-multiply}, @samp{cortex-m0.small-multiply}, @samp{cortex-m0plus.small-multiply}, @samp{exynos-m1}, @samp{marvell-pj4}, @samp{neoverse-n1}, @samp{xscale}, @samp{iwmmxt}, @samp{iwmmxt2}, @@ -17717,14 +17719,14 @@ The following extension options are common to the listed CPUs: @table @samp @item +nodsp -Disable the DSP instructions on @samp{cortex-m33}. +Disable the DSP instructions on @samp{cortex-m33}, @samp{cortex-m35p}. @item +nofp Disables the floating-point instructions on @samp{arm9e}, @samp{arm946e-s}, @samp{arm966e-s}, @samp{arm968e-s}, @samp{arm10e}, @samp{arm1020e}, @samp{arm1022e}, @samp{arm926ej-s}, @samp{arm1026ej-s}, @samp{cortex-r5}, @samp{cortex-r7}, @samp{cortex-r8}, -@samp{cortex-m4}, @samp{cortex-m7} and @samp{cortex-m33}. +@samp{cortex-m4}, @samp{cortex-m7}, @samp{cortex-m33} and @samp{cortex-m35p}. Disables the floating-point and SIMD instructions on @samp{generic-armv7-a}, @samp{cortex-a5}, @samp{cortex-a7}, @samp{cortex-a8}, @samp{cortex-a9}, @samp{cortex-a12}, -- cgit v1.1 From f3bb4623f40228d8ea4e03ee4e6495cb17bbf710 Mon Sep 17 00:00:00 2001 From: Mark Eggleston Date: Fri, 23 Aug 2019 09:31:48 +0000 Subject: ABS Documentation fix The specific intrinsics ZABS and CDABS return REAL(8) not COMPLEX(8). From-SVN: r274847 --- gcc/fortran/ChangeLog | 4 ++++ gcc/fortran/intrinsic.texi | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 69ec726..2beb71b 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,7 @@ +2019-08-23 Mark Eggleston + + * intrinsics.text: Correct the return types for ZABS and CDABS. + 2019-08-22 Steven G. Kargl * intrinsic.c (add_subroutines): ERRMSG is INTENT(INOUT) in diff --git a/gcc/fortran/intrinsic.texi b/gcc/fortran/intrinsic.texi index 31b97c4..c026726 100644 --- a/gcc/fortran/intrinsic.texi +++ b/gcc/fortran/intrinsic.texi @@ -470,8 +470,8 @@ end program test_abs @item @code{IIABS(A)} @tab @code{INTEGER(2) A} @tab @code{INTEGER(2)} @tab GNU extension @item @code{JIABS(A)} @tab @code{INTEGER(4) A} @tab @code{INTEGER(4)} @tab GNU extension @item @code{KIABS(A)} @tab @code{INTEGER(8) A} @tab @code{INTEGER(8)} @tab GNU extension -@item @code{ZABS(A)} @tab @code{COMPLEX(8) A} @tab @code{COMPLEX(8)} @tab GNU extension -@item @code{CDABS(A)} @tab @code{COMPLEX(8) A} @tab @code{COMPLEX(8)} @tab GNU extension +@item @code{ZABS(A)} @tab @code{COMPLEX(8) A} @tab @code{REAL(8)} @tab GNU extension +@item @code{CDABS(A)} @tab @code{COMPLEX(8) A} @tab @code{REAL(8)} @tab GNU extension @end multitable @end table -- cgit v1.1 From 3fa7e353eccc2694ce55780012d6ea57f025be1b Mon Sep 17 00:00:00 2001 From: Mark Eggleston Date: Fri, 23 Aug 2019 10:16:47 +0000 Subject: Intrinsic documentation layout changes. Documentation of all intrinsics now have their sections in a consistent order. Empty sections have been removed. Stray words have been removed. Text in a wrong section has been moved. A missing standard was inserted. From-SVN: r274848 --- gcc/fortran/ChangeLog | 7 +++++++ gcc/fortran/intrinsic.texi | 42 ++++++++++++++++-------------------------- 2 files changed, 23 insertions(+), 26 deletions(-) (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 2beb71b..ea81f10 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,5 +1,12 @@ 2019-08-23 Mark Eggleston + * intrinsics.text: Removed empty sections. The order of + sections for each intrinsic is now consistent throughout. + Stray words removed. Text in the wrong section moved. + Missing standard statement inserted. + +2019-08-23 Mark Eggleston + * intrinsics.text: Correct the return types for ZABS and CDABS. 2019-08-22 Steven G. Kargl diff --git a/gcc/fortran/intrinsic.texi b/gcc/fortran/intrinsic.texi index c026726..849c7e8 100644 --- a/gcc/fortran/intrinsic.texi +++ b/gcc/fortran/intrinsic.texi @@ -529,9 +529,6 @@ program access_test print *, trim(file2),' is readable, writable and executable' end program access_test @end smallexample -@item @emph{Specific names}: -@item @emph{See also}: - @end table @@ -8065,7 +8062,7 @@ Inquiry function. @item @emph{Syntax}: @code{RESULT = IMAGE_INDEX(COARRAY, SUB)} -@item @emph{Arguments}: None. +@item @emph{Arguments}: @multitable @columnfractions .15 .70 @item @var{COARRAY} @tab Coarray of any type. @item @var{SUB} @tab default integer rank-1 array of a size equal to @@ -8839,12 +8836,13 @@ end program test_itime @table @asis @item @emph{Description}: -@item @emph{Standard}: Sends the signal specified by @var{SIG} to the process @var{PID}. See @code{kill(2)}. This intrinsic is provided in both subroutine and function forms; however, only one form can be used in any given program unit. +@item @emph{Standard}: +GNU extension @item @emph{Class}: Subroutine, function @@ -10002,8 +10000,6 @@ equal to the last (or only) dimension of @var{MATRIX_A}. The matrix product of @var{MATRIX_A} and @var{MATRIX_B}. The type and kind of the result follow the usual type and kind promotion rules, as for the @code{*} or @code{.AND.} operators. - -@item @emph{See also}: @end table @@ -11407,9 +11403,6 @@ Elemental function The return value is of type @code{INTEGER} and of the default integer kind. -@item @emph{See also}: -@ref{POPPAR}, @ref{LEADZ}, @ref{TRAILZ} - @item @emph{Example}: @smallexample program test_population @@ -11418,6 +11411,9 @@ program test_population print *, popcnt(huge(0_8)), poppar(huge(0_8)) end program test_population @end smallexample +@item @emph{See also}: +@ref{POPPAR}, @ref{LEADZ}, @ref{TRAILZ} + @end table @@ -11452,9 +11448,6 @@ Elemental function The return value is of type @code{INTEGER} and of the default integer kind. -@item @emph{See also}: -@ref{POPCNT}, @ref{LEADZ}, @ref{TRAILZ} - @item @emph{Example}: @smallexample program test_population @@ -11463,6 +11456,8 @@ program test_population print *, popcnt(huge(0_8)), poppar(huge(0_8)) end program test_population @end smallexample +@item @emph{See also}: +@ref{POPCNT}, @ref{LEADZ}, @ref{TRAILZ} @end table @@ -11495,9 +11490,6 @@ Inquiry function The return value is of type @code{INTEGER} and of the default integer kind. -@item @emph{See also}: -@ref{SELECTED_REAL_KIND}, @ref{RANGE} - @item @emph{Example}: @smallexample program prec_and_range @@ -11508,6 +11500,8 @@ program prec_and_range print *, precision(y), range(y) end program prec_and_range @end smallexample +@item @emph{See also}: +@ref{SELECTED_REAL_KIND}, @ref{RANGE} @end table @@ -11643,9 +11637,6 @@ Inquiry function The return value is a scalar of type @code{INTEGER} and of the default integer kind. -@item @emph{See also}: -@ref{SELECTED_REAL_KIND} - @item @emph{Example}: @smallexample program test_radix @@ -11653,7 +11644,8 @@ program test_radix print *, "The radix for the default real kind is", radix(0.0) end program test_radix @end smallexample - +@item @emph{See also}: +@ref{SELECTED_REAL_KIND} @end table @@ -11936,11 +11928,10 @@ or @code{COMPLEX}. The return value is of type @code{INTEGER} and of the default integer kind. -@item @emph{See also}: -@ref{SELECTED_REAL_KIND}, @ref{PRECISION} - @item @emph{Example}: See @code{PRECISION} for an example. +@item @emph{See also}: +@ref{SELECTED_REAL_KIND}, @ref{PRECISION} @end table @@ -12665,9 +12656,6 @@ are fulfillable @item -5 if there is no real type with the given @code{RADIX} @end table -@item @emph{See also}: -@ref{PRECISION}, @ref{RANGE}, @ref{RADIX} - @item @emph{Example}: @smallexample program real_kinds @@ -12683,6 +12671,8 @@ program real_kinds print *, precision(z), range(z) end program real_kinds @end smallexample +@item @emph{See also}: +@ref{PRECISION}, @ref{RANGE}, @ref{RADIX} @end table -- cgit v1.1 From 19566bdda5762ddc769fc848dcad5e1e4abf8d0d Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Fri, 23 Aug 2019 13:27:12 +0200 Subject: Make -flto=jobserver parallel again. 2019-08-23 Martin Liska * lto-wrapper.c (run_gcc): When setting jobserver set also parallel to 1. This was done so before r273908. From-SVN: r274849 --- gcc/ChangeLog | 5 +++++ gcc/lto-wrapper.c | 12 +++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bd47b77..df4d621 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-08-23 Martin Liska + + * lto-wrapper.c (run_gcc): When setting jobserver + set also parallel to 1. This was done so before r273908. + 2019-08-23 Dennis Zhang * config/arm/arm-cpus.in (cortex-m35p): New entry. diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c index 68f63da..75ed289 100644 --- a/gcc/lto-wrapper.c +++ b/gcc/lto-wrapper.c @@ -1374,7 +1374,10 @@ run_gcc (unsigned argc, char *argv[]) case OPT_flto_: if (strcmp (option->arg, "jobserver") == 0) - jobserver = 1; + { + parallel = 1; + jobserver = 1; + } else if (strcmp (option->arg, "auto") == 0) { parallel = 1; @@ -1423,8 +1426,11 @@ run_gcc (unsigned argc, char *argv[]) auto_parallel = 0; parallel = 0; } - else if (!jobserver) - jobserver = jobserver_active_p (); + else if (!jobserver && jobserver_active_p ()) + { + parallel = 1; + jobserver = 1; + } if (linker_output) { -- cgit v1.1 From df375b0321f9a5360fd04435ee5832c253aa4175 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 23 Aug 2019 13:37:29 +0200 Subject: re PR middle-end/91283 (gcc.dg/torture/c99-contract-1.c FAILs) PR middle-end/91283 * common.opt (fexcess-precision=): Add Optimization flag. Use flag_excess_precision variable instead of flag_excess_precision_cmdline. * flags.h (class target_flag_state): Remove x_flag_excess_precision member. (flag_excess_precision): Don't define. * langhooks.c (lhd_post_options): Set flag_excess_precision instead of flag_excess_precision_cmdline. Remove comment. * opts.c (set_fast_math_flags): Use frontend_set_flag_excess_precision and x_flag_excess_precision instead of frontend_set_flag_excess_precision_cmdline and x_flag_excess_precision_cmdline. (fast_math_flags_set_p): Use x_flag_excess_precision instead of x_flag_excess_precision_cmdline. * toplev.c (init_excess_precision): Remove. (lang_dependent_init_target): Don't call it. ada/ * gcc-interface/misc.c (gnat_post_options): Set flag_excess_precision instead of flag_excess_precision_cmdline. brig/ * brig-lang.c (brig_langhook_post_options): Set flag_excess_precision instead of flag_excess_precision_cmdline. c-family/ * c-common.c (c_ts18661_flt_eval_method): Use flag_excess_precision instead of flag_excess_precision_cmdline. * c-cppbuiltin.c (c_cpp_flt_eval_method_iec_559): Likewise. * c-opts.c (c_common_post_options): Likewise. d/ * d-lang.cc (d_post_options): Set flag_excess_precision instead of flag_excess_precision_cmdline. fortran/ * options.c (gfc_post_options): Set flag_excess_precision instead of flag_excess_precision_cmdline. Remove comment. go/ * go-lang.c (go_langhook_post_options): Set flag_excess_precision instead of flag_excess_precision_cmdline. lto/ * lto-lang.c (lto_post_options): Set flag_excess_precision instead of flag_excess_precision_cmdline. Remove comment. From-SVN: r274850 --- gcc/ChangeLog | 20 ++++++++++++++++++++ gcc/ada/ChangeLog | 6 ++++++ gcc/ada/gcc-interface/misc.c | 4 ++-- gcc/brig/ChangeLog | 6 ++++++ gcc/brig/brig-lang.c | 4 ++-- gcc/c-family/ChangeLog | 8 ++++++++ gcc/c-family/c-common.c | 2 +- gcc/c-family/c-cppbuiltin.c | 2 +- gcc/c-family/c-opts.c | 11 +++++------ gcc/common.opt | 2 +- gcc/d/ChangeLog | 6 ++++++ gcc/d/d-lang.cc | 4 ++-- gcc/flags.h | 9 --------- gcc/fortran/ChangeLog | 6 ++++++ gcc/fortran/options.c | 4 ++-- gcc/go/ChangeLog | 6 ++++++ gcc/go/go-lang.c | 4 ++-- gcc/langhooks.c | 2 +- gcc/lto/ChangeLog | 6 ++++++ gcc/lto/lto-lang.c | 3 ++- gcc/opts.c | 8 +++----- gcc/toplev.c | 16 ---------------- 22 files changed, 88 insertions(+), 51 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index df4d621..62aebf2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +2019-08-23 Jakub Jelinek + + PR middle-end/91283 + * common.opt (fexcess-precision=): Add Optimization flag. Use + flag_excess_precision variable instead of + flag_excess_precision_cmdline. + * flags.h (class target_flag_state): Remove x_flag_excess_precision + member. + (flag_excess_precision): Don't define. + * langhooks.c (lhd_post_options): Set flag_excess_precision instead of + flag_excess_precision_cmdline. Remove comment. + * opts.c (set_fast_math_flags): Use frontend_set_flag_excess_precision + and x_flag_excess_precision instead of + frontend_set_flag_excess_precision_cmdline and + x_flag_excess_precision_cmdline. + (fast_math_flags_set_p): Use x_flag_excess_precision instead of + x_flag_excess_precision_cmdline. + * toplev.c (init_excess_precision): Remove. + (lang_dependent_init_target): Don't call it. + 2019-08-23 Martin Liska * lto-wrapper.c (run_gcc): When setting jobserver diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 53ecd1a..b5c0b1f 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,9 @@ +2019-08-23 Jakub Jelinek + + PR middle-end/91283 + * gcc-interface/misc.c (gnat_post_options): Set flag_excess_precision + instead of flag_excess_precision_cmdline. + 2019-08-21 Vadim Godunko * libgnat/g-expect.adb (Expect_Internal): Attempt to read diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c index c5822f6..a576b7e 100644 --- a/gcc/ada/gcc-interface/misc.c +++ b/gcc/ada/gcc-interface/misc.c @@ -256,9 +256,9 @@ static bool gnat_post_options (const char **pfilename ATTRIBUTE_UNUSED) { /* Excess precision other than "fast" requires front-end support. */ - if (flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD) + if (flag_excess_precision == EXCESS_PRECISION_STANDARD) sorry ("%<-fexcess-precision=standard%> for Ada"); - flag_excess_precision_cmdline = EXCESS_PRECISION_FAST; + flag_excess_precision = EXCESS_PRECISION_FAST; /* No psABI change warnings for Ada. */ warn_psabi = 0; diff --git a/gcc/brig/ChangeLog b/gcc/brig/ChangeLog index a5c3b9b..462cbab 100644 --- a/gcc/brig/ChangeLog +++ b/gcc/brig/ChangeLog @@ -1,3 +1,9 @@ +2019-08-23 Jakub Jelinek + + PR middle-end/91283 + * brig-lang.c (brig_langhook_post_options): Set flag_excess_precision + instead of flag_excess_precision_cmdline. + 2019-06-25 Jozef Lawrynowicz * brig-lang.c (brig_build_c_type_nodes): Accept "__intN__" diff --git a/gcc/brig/brig-lang.c b/gcc/brig/brig-lang.c index 1c3a3b0..96c6c57 100644 --- a/gcc/brig/brig-lang.c +++ b/gcc/brig/brig-lang.c @@ -166,8 +166,8 @@ brig_langhook_handle_option static bool brig_langhook_post_options (const char **pfilename ATTRIBUTE_UNUSED) { - if (flag_excess_precision_cmdline == EXCESS_PRECISION_DEFAULT) - flag_excess_precision_cmdline = EXCESS_PRECISION_STANDARD; + if (flag_excess_precision == EXCESS_PRECISION_DEFAULT) + flag_excess_precision = EXCESS_PRECISION_STANDARD; /* gccbrig casts pointers around like crazy, TBAA might produce broken code if not disabling it by default. Some PRM conformance tests such diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index a1a864a..b8920f1c 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,11 @@ +2019-08-23 Jakub Jelinek + + PR middle-end/91283 + * c-common.c (c_ts18661_flt_eval_method): Use flag_excess_precision + instead of flag_excess_precision_cmdline. + * c-cppbuiltin.c (c_cpp_flt_eval_method_iec_559): Likewise. + * c-opts.c (c_common_post_options): Likewise. + 2019-08-22 Martin Sebor PR middle-end/91490 diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 0aaa246..d516dea 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -8345,7 +8345,7 @@ c_ts18661_flt_eval_method (void) = targetm.c.excess_precision (EXCESS_PRECISION_TYPE_IMPLICIT); enum excess_precision_type flag_type - = (flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD + = (flag_excess_precision == EXCESS_PRECISION_STANDARD ? EXCESS_PRECISION_TYPE_STANDARD : EXCESS_PRECISION_TYPE_FAST); diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c index d389f8c..6006e95 100644 --- a/gcc/c-family/c-cppbuiltin.c +++ b/gcc/c-family/c-cppbuiltin.c @@ -746,7 +746,7 @@ static bool c_cpp_flt_eval_method_iec_559 (void) { enum excess_precision_type front_end_ept - = (flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD + = (flag_excess_precision == EXCESS_PRECISION_STANDARD ? EXCESS_PRECISION_TYPE_STANDARD : EXCESS_PRECISION_TYPE_FAST); diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c index 2d4af63..da783e4 100644 --- a/gcc/c-family/c-opts.c +++ b/gcc/c-family/c-opts.c @@ -800,14 +800,13 @@ c_common_post_options (const char **pfilename) support. */ if (c_dialect_cxx ()) { - if (flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD) + if (flag_excess_precision == EXCESS_PRECISION_STANDARD) sorry ("%<-fexcess-precision=standard%> for C++"); - flag_excess_precision_cmdline = EXCESS_PRECISION_FAST; + flag_excess_precision = EXCESS_PRECISION_FAST; } - else if (flag_excess_precision_cmdline == EXCESS_PRECISION_DEFAULT) - flag_excess_precision_cmdline = (flag_iso - ? EXCESS_PRECISION_STANDARD - : EXCESS_PRECISION_FAST); + else if (flag_excess_precision == EXCESS_PRECISION_DEFAULT) + flag_excess_precision = (flag_iso ? EXCESS_PRECISION_STANDARD + : EXCESS_PRECISION_FAST); /* ISO C restricts floating-point expression contraction to within source-language expressions (-ffp-contract=on, currently an alias diff --git a/gcc/common.opt b/gcc/common.opt index c160538..f2214ed 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -1399,7 +1399,7 @@ Common Report Var(flag_expensive_optimizations) Optimization Perform a number of minor, expensive optimizations. fexcess-precision= -Common Joined RejectNegative Enum(excess_precision) Var(flag_excess_precision_cmdline) Init(EXCESS_PRECISION_DEFAULT) SetByCombined +Common Joined RejectNegative Enum(excess_precision) Var(flag_excess_precision) Init(EXCESS_PRECISION_DEFAULT) Optimization SetByCombined -fexcess-precision=[fast|standard] Specify handling of excess floating-point precision. Enum diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog index a7821c2..1013c08 100644 --- a/gcc/d/ChangeLog +++ b/gcc/d/ChangeLog @@ -1,3 +1,9 @@ +2019-08-23 Jakub Jelinek + + PR middle-end/91283 + * d-lang.cc (d_post_options): Set flag_excess_precision instead of + flag_excess_precision_cmdline. + 2019-08-20 Iain Buclaw PR d/88722 diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc index db0db0e..5cdb896 100644 --- a/gcc/d/d-lang.cc +++ b/gcc/d/d-lang.cc @@ -772,8 +772,8 @@ d_post_options (const char ** fn) if (global_options_set.x_flag_max_errors) global.errorLimit = flag_max_errors; - if (flag_excess_precision_cmdline == EXCESS_PRECISION_DEFAULT) - flag_excess_precision_cmdline = EXCESS_PRECISION_STANDARD; + if (flag_excess_precision == EXCESS_PRECISION_DEFAULT) + flag_excess_precision = EXCESS_PRECISION_STANDARD; if (global.params.useUnitTests) global.params.useAssert = true; diff --git a/gcc/flags.h b/gcc/flags.h index 0b9cd12..5bf9b49 100644 --- a/gcc/flags.h +++ b/gcc/flags.h @@ -51,9 +51,6 @@ public: align_flags x_align_jumps; align_flags x_align_labels; align_flags x_align_functions; - - /* The excess precision currently in effect. */ - enum excess_precision x_flag_excess_precision; }; extern class target_flag_state default_target_flag_state; @@ -68,12 +65,6 @@ extern class target_flag_state *this_target_flag_state; #define align_labels (this_target_flag_state->x_align_labels) #define align_functions (this_target_flag_state->x_align_functions) -/* String representaions of the above options are available in - const char *str_align_foo. NULL if not set. */ - -#define flag_excess_precision \ - (this_target_flag_state->x_flag_excess_precision) - /* Returns TRUE if generated code should match ABI version N or greater is in use. */ diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index ea81f10..e454bd2 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,9 @@ +2019-08-23 Jakub Jelinek + + PR middle-end/91283 + * options.c (gfc_post_options): Set flag_excess_precision instead of + flag_excess_precision_cmdline. Remove comment. + 2019-08-23 Mark Eggleston * intrinsics.text: Removed empty sections. The order of diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c index 146be2f..771c10e 100644 --- a/gcc/fortran/options.c +++ b/gcc/fortran/options.c @@ -264,9 +264,9 @@ gfc_post_options (const char **pfilename) /* Excess precision other than "fast" requires front-end support. */ - if (flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD) + if (flag_excess_precision == EXCESS_PRECISION_STANDARD) sorry ("%<-fexcess-precision=standard%> for Fortran"); - flag_excess_precision_cmdline = EXCESS_PRECISION_FAST; + flag_excess_precision = EXCESS_PRECISION_FAST; /* Fortran allows associative math - but we cannot reassociate if we want traps or signed zeros. Cf. also flag_protect_parens. */ diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index 9413c20..47400e2 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,9 @@ +2019-08-23 Jakub Jelinek + + PR middle-end/91283 + * go-lang.c (go_langhook_post_options): Set flag_excess_precision + instead of flag_excess_precision_cmdline. + 2019-07-02 Cherry Zhang * go-gcc.cc (Gcc_backend::Gcc_backend): Define __builtin_memset. diff --git a/gcc/go/go-lang.c b/gcc/go/go-lang.c index 94f2cb2..a6bda93 100644 --- a/gcc/go/go-lang.c +++ b/gcc/go/go-lang.c @@ -293,8 +293,8 @@ go_langhook_post_options (const char **pfilename ATTRIBUTE_UNUSED) go_add_search_path (dir); go_search_dirs.release (); - if (flag_excess_precision_cmdline == EXCESS_PRECISION_DEFAULT) - flag_excess_precision_cmdline = EXCESS_PRECISION_STANDARD; + if (flag_excess_precision == EXCESS_PRECISION_DEFAULT) + flag_excess_precision = EXCESS_PRECISION_STANDARD; /* Tail call optimizations can confuse uses of runtime.Callers. */ if (!global_options_set.x_flag_optimize_sibling_calls) diff --git a/gcc/langhooks.c b/gcc/langhooks.c index 22ace13..89fb5bc 100644 --- a/gcc/langhooks.c +++ b/gcc/langhooks.c @@ -97,7 +97,7 @@ lhd_post_options (const char ** ARG_UNUSED (pfilename)) { /* Excess precision other than "fast" requires front-end support. */ - flag_excess_precision_cmdline = EXCESS_PRECISION_FAST; + flag_excess_precision = EXCESS_PRECISION_FAST; return false; } diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index 2467d78..4e68fbf 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,9 @@ +2019-08-23 Jakub Jelinek + + PR middle-end/91283 + * lto-lang.c (lto_post_options): Set flag_excess_precision instead of + flag_excess_precision_cmdline. Remove comment. + 2019-08-13 Richard Sandiford PR middle-end/91421 diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c index cc44afc..414eaf2 100644 --- a/gcc/lto/lto-lang.c +++ b/gcc/lto/lto-lang.c @@ -927,7 +927,8 @@ lto_post_options (const char **pfilename ATTRIBUTE_UNUSED) /* Excess precision other than "fast" requires front-end support. */ - flag_excess_precision_cmdline = EXCESS_PRECISION_FAST; + if (flag_excess_precision == EXCESS_PRECISION_DEFAULT) + flag_excess_precision = EXCESS_PRECISION_FAST; /* When partitioning, we can tear appart STRING_CSTs uses from the same TU into multiple partitions. Without constant merging the constants diff --git a/gcc/opts.c b/gcc/opts.c index bb0d8b5..1417dba 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -2971,9 +2971,8 @@ set_fast_math_flags (struct gcc_options *opts, int set) opts->x_flag_errno_math = !set; if (set) { - if (opts->frontend_set_flag_excess_precision_cmdline - == EXCESS_PRECISION_DEFAULT) - opts->x_flag_excess_precision_cmdline + if (opts->frontend_set_flag_excess_precision == EXCESS_PRECISION_DEFAULT) + opts->x_flag_excess_precision = set ? EXCESS_PRECISION_FAST : EXCESS_PRECISION_DEFAULT; if (!opts->frontend_set_flag_signaling_nans) opts->x_flag_signaling_nans = 0; @@ -3008,8 +3007,7 @@ fast_math_flags_set_p (const struct gcc_options *opts) && opts->x_flag_finite_math_only && !opts->x_flag_signed_zeros && !opts->x_flag_errno_math - && opts->x_flag_excess_precision_cmdline - == EXCESS_PRECISION_FAST); + && opts->x_flag_excess_precision == EXCESS_PRECISION_FAST); } /* Return true iff flags are set as if -ffast-math but using the flags stored diff --git a/gcc/toplev.c b/gcc/toplev.c index ddbb8b4..d741a66 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1841,27 +1841,11 @@ backend_init (void) init_regs (); } -/* Initialize excess precision settings. - - We have no need to modify anything here, just keep track of what the - user requested. We'll figure out any appropriate relaxations - later. */ - -static void -init_excess_precision (void) -{ - gcc_assert (flag_excess_precision_cmdline != EXCESS_PRECISION_DEFAULT); - flag_excess_precision = flag_excess_precision_cmdline; -} - /* Initialize things that are both lang-dependent and target-dependent. This function can be called more than once if target parameters change. */ static void lang_dependent_init_target (void) { - /* This determines excess precision settings. */ - init_excess_precision (); - /* This creates various _DECL nodes, so needs to be called after the front end is initialized. It also depends on the HAVE_xxx macros generated from the target machine description. */ -- cgit v1.1 From 22f8849d06019e925eb8669274a03daf02e71cc6 Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Fri, 23 Aug 2019 12:41:39 +0000 Subject: [PATCH, c-family] Fix a PCH thinko (and thus PR61250). When we are parsing a source file, the very first token might be a PRAGMA_GCC_PCH_PREPROCESS. This indicates that we are going read in a PCH file (named as the value of the pragma). If we don't see this pragma, then we know that it's OK to release any resources that the host might have set aside for the PCH file. This fixes a thinko in the current implementation, in that the decision to release resources was happening unconditionally right after the first token is extracted but before it's been checked or acted upon. This leads to the pch bug (seen on Darwin), because we actually do release resources - which are subsequently (reasonably) assumed to be available when reading a PCH file. We then get random crashes or hangs depending on the interaction between unmmap and malloc. The bug is present everywhere but doesn't show on (say) Linux, since the release of PCH resources is a NOP there. This effects all the c-family front ends, because they all use c_lex_with_flags () to implement this. The solution is to check for the PRAGMA_GCC_PCH_PREPROCESS and only call c_common_no_more_pch () when that is not the first token. A secondary effect of the collection is that the name of the PCH file can be collected during the ggc_pch_read() reset of state. Therefore we should issue any diagnostic that might name the file before the collections are triggered. gcc/c-family/ 2019-08-23 Iain Sandoe PR pch/61250 * c-lex.c (c_lex_with_flags): Don't call c_common_no_more_pch () from here. gcc/c/ 2019-08-23 Iain Sandoe PR pch/61250 * c-parser.c (c_parse_file): Call c_common_no_more_pch () after determining that the first token is not PRAGMA_GCC_PCH_PREPROCESS. gcc/cp/ 2019-08-23 Iain Sandoe PR pch/61250 * parser.c (cp_parser_initial_pragma): Call c_common_no_more_pch () after determining that the first token is not PRAGMA_GCC_PCH_PREPROCESS. gcc/ 2019-08-23 Iain Sandoe PR pch/61250 * ggc-page.c (ggc_pch_read): Read the ggc_pch_ondisk structure and issue any diagnostics needed before collecting the pre-PCH state. From-SVN: r274856 --- gcc/ChangeLog | 7 +++++++ gcc/c-family/ChangeLog | 6 ++++++ gcc/c-family/c-lex.c | 7 ------- gcc/c/ChangeLog | 7 +++++++ gcc/c/c-parser.c | 2 ++ gcc/cp/ChangeLog | 7 +++++++ gcc/cp/parser.c | 5 ++++- gcc/ggc-page.c | 5 +++-- 8 files changed, 36 insertions(+), 10 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 62aebf2..86669dd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2019-08-23 Iain Sandoe + + PR pch/61250 + * ggc-page.c (ggc_pch_read): Read the ggc_pch_ondisk structure + and issue any diagnostics needed before collecting the pre-PCH + state. + 2019-08-23 Jakub Jelinek PR middle-end/91283 diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index b8920f1c..2ab1c98 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2019-08-23 Iain Sandoe + + PR pch/61250 + * c-lex.c (c_lex_with_flags): Don't call + c_common_no_more_pch () from here. + 2019-08-23 Jakub Jelinek PR middle-end/91283 diff --git a/gcc/c-family/c-lex.c b/gcc/c-family/c-lex.c index 851fd70..e3c602f 100644 --- a/gcc/c-family/c-lex.c +++ b/gcc/c-family/c-lex.c @@ -394,7 +394,6 @@ enum cpp_ttype c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags, int lex_flags) { - static bool no_more_pch; const cpp_token *tok; enum cpp_ttype type; unsigned char add_flags = 0; @@ -628,12 +627,6 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags, if (cpp_flags) *cpp_flags = tok->flags | add_flags; - if (!no_more_pch) - { - no_more_pch = true; - c_common_no_more_pch (); - } - timevar_pop (TV_CPP); return type; diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 0b3dc74..b7b45f5 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,10 @@ +2019-08-23 Iain Sandoe + + PR pch/61250 + * c-parser.c (c_parse_file): Call c_common_no_more_pch () + after determining that the first token is not + PRAGMA_GCC_PCH_PREPROCESS. + 2019-08-22 Eric Botcazou * c-parser.c (c_parser_declaration_or_fndef): Set DECL_ARGUMENTS of a diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 7397f53..6070502 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -20263,6 +20263,8 @@ c_parse_file (void) if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS) c_parser_pragma_pch_preprocess (&tparser); + else + c_common_no_more_pch (); the_parser = ggc_alloc (); *the_parser = tparser; diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d2b9623..f014423 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2019-08-23 Iain Sandoe + + PR pch/61250 + * parser.c (cp_parser_initial_pragma): Call c_common_no_more_pch () + after determining that the first token is not + PRAGMA_GCC_PCH_PREPROCESS. + 2019-08-22 Marek Polacek PR c++/91304 - prefix attributes ignored in condition. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index b410a6c..504f77a 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -41357,7 +41357,10 @@ cp_parser_initial_pragma (cp_token *first_token) cp_lexer_get_preprocessor_token (NULL, first_token); if (cp_parser_pragma_kind (first_token) != PRAGMA_GCC_PCH_PREPROCESS) - return; + { + c_common_no_more_pch (); + return; + } cp_lexer_get_preprocessor_token (NULL, first_token); if (first_token->type == CPP_STRING) diff --git a/gcc/ggc-page.c b/gcc/ggc-page.c index a2736bc..220f20c 100644 --- a/gcc/ggc-page.c +++ b/gcc/ggc-page.c @@ -2556,6 +2556,9 @@ ggc_pch_read (FILE *f, void *addr) count_old_page_tables = G.by_depth_in_use; + if (fread (&d, sizeof (d), 1, f) != 1) + fatal_error (input_location, "cannot read PCH file: %m"); + /* We've just read in a PCH file. So, every object that used to be allocated is now free. */ clear_marks (); @@ -2584,8 +2587,6 @@ ggc_pch_read (FILE *f, void *addr) /* Allocate the appropriate page-table entries for the pages read from the PCH file. */ - if (fread (&d, sizeof (d), 1, f) != 1) - fatal_error (input_location, "cannot read PCH file: %m"); for (i = 0; i < NUM_ORDERS; i++) { -- cgit v1.1 From 35a114dae14de7db983aba7e709dcad96405c14a Mon Sep 17 00:00:00 2001 From: Mark Eggleston Date: Fri, 23 Aug 2019 13:03:26 +0000 Subject: PDF Layout Prevent lines overlapping the right hand margin, this occurred for references in the "See also:" section, it is prevented by placing references on their own lines. Two example programs overlapped the right hand margin: fixed by adjusting the position and of the comments. Some tables had overlapping colums: the column widths were adjusted accordingly. From-SVN: r274857 --- gcc/fortran/ChangeLog | 8 + gcc/fortran/intrinsic.texi | 769 +++++++++++++++++++++++++++++++-------------- 2 files changed, 538 insertions(+), 239 deletions(-) (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index e454bd2..4bd9291 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,11 @@ +2019-08-23 Mark Eggleston + + * intrinsics.text: References in 'See also:' are now on + separate lines to ensure that they always fit in the margins of + a PDF page. The column widths of tables have been adjusted + where necessary to prevent overlapping text. All program + examples now fit within the margins of a PDF page. + 2019-08-23 Jakub Jelinek PR middle-end/91283 diff --git a/gcc/fortran/intrinsic.texi b/gcc/fortran/intrinsic.texi index 849c7e8..61f533e 100644 --- a/gcc/fortran/intrinsic.texi +++ b/gcc/fortran/intrinsic.texi @@ -403,8 +403,9 @@ end program test_abort @end smallexample @item @emph{See also}: -@ref{EXIT}, @ref{KILL}, @ref{BACKTRACE} - +@ref{EXIT}, @gol +@ref{KILL}, @gol +@ref{BACKTRACE} @end table @@ -578,8 +579,9 @@ See @ref{ICHAR} for a discussion of converting between numerical values and formatted string representations. @item @emph{See also}: -@ref{CHAR}, @ref{IACHAR}, @ref{ICHAR} - +@ref{CHAR}, @gol +@ref{IACHAR}, @gol +@ref{ICHAR} @end table @@ -631,9 +633,10 @@ end program test_acos @end multitable @item @emph{See also}: -Inverse function: @ref{COS} -Degrees function: @ref{ACOSD} - +Inverse function: @gol +@ref{COS} @gol +Degrees function: @gol +@ref{ACOSD} @end table @@ -689,9 +692,10 @@ end program test_acosd @end multitable @item @emph{See also}: -Inverse function: @ref{COSD} -Radians function: @ref{ACOS} - +Inverse function: @gol +@ref{COSD} @gol +Radians function: @gol +@ref{ACOS} @gol @end table @@ -743,7 +747,8 @@ END PROGRAM @end multitable @item @emph{See also}: -Inverse function: @ref{COSH} +Inverse function: @gol +@ref{COSH} @end table @@ -788,7 +793,8 @@ end program test_adjustl @end smallexample @item @emph{See also}: -@ref{ADJUSTR}, @ref{TRIM} +@ref{ADJUSTR}, @gol +@ref{TRIM} @end table @@ -833,7 +839,8 @@ end program test_adjustr @end smallexample @item @emph{See also}: -@ref{ADJUSTL}, @ref{TRIM} +@ref{ADJUSTL}, @gol +@ref{TRIM} @end table @@ -1170,7 +1177,8 @@ END PROGRAM @end smallexample @item @emph{See also}: -Fortran 95 elemental function: @ref{IAND} +Fortran 95 elemental function: @gol +@ref{IAND} @end table @@ -1345,9 +1353,10 @@ end program test_asin @end multitable @item @emph{See also}: -Inverse function: @ref{SIN} -Degrees function: @ref{ASIND} - +Inverse function: @gol +@ref{SIN} @gol +Degrees function: @gol +@ref{ASIND} @end table @@ -1403,9 +1412,10 @@ end program test_asind @end multitable @item @emph{See also}: -Inverse function: @ref{SIND} -Radians function: @ref{ASIN} - +Inverse function: @gol +@ref{SIND} @gol +Radians function: @gol +@ref{ASIN} @end table @@ -1457,7 +1467,8 @@ END PROGRAM @end multitable @item @emph{See also}: -Inverse function: @ref{SINH} +Inverse function: @gol +@ref{SINH} @end table @@ -1593,9 +1604,10 @@ end program test_atan @end multitable @item @emph{See also}: -Inverse function: @ref{TAN} -Degrees function: @ref{ATAND} - +Inverse function: @gol +@ref{TAN} @gol +Degrees function: @gol +@ref{ATAND} @end table @@ -1657,9 +1669,10 @@ end program test_atand @end multitable @item @emph{See also}: -Inverse function: @ref{TAND} -Radians function: @ref{ATAN} - +Inverse function: @gol +@ref{TAND} @gol +Radians function: @gol +@ref{ATAN} @end table @@ -1721,8 +1734,10 @@ end program test_atan2 @end multitable @item @emph{See also}: -Alias: @ref{ATAN} -Degrees function: @ref{ATAN2D} +Alias: @gol +@ref{ATAN} @gol +Degrees function: @gol +@ref{ATAN2D} @end table @@ -1788,9 +1803,10 @@ end program test_atan2d @end multitable @item @emph{See also}: -Alias: @ref{ATAND} -Radians function: @ref{ATAN2} - +Alias: @gol +@ref{ATAND} @gol +Radians function: @gol +@ref{ATAN2} @end table @@ -1842,7 +1858,8 @@ END PROGRAM @end multitable @item @emph{See also}: -Inverse function: @ref{TANH} +Inverse function: @gol +@ref{TANH} @end table @@ -1890,8 +1907,12 @@ end program atomic @end smallexample @item @emph{See also}: -@ref{ATOMIC_DEFINE}, @ref{ATOMIC_FETCH_ADD}, @ref{ISO_FORTRAN_ENV}, -@ref{ATOMIC_AND}, @ref{ATOMIC_OR}, @ref{ATOMIC_XOR} +@ref{ATOMIC_DEFINE}, @gol +@ref{ATOMIC_FETCH_ADD}, @gol +@ref{ISO_FORTRAN_ENV}, @gol +@ref{ATOMIC_AND}, @gol +@ref{ATOMIC_OR}, @gol +@ref{ATOMIC_XOR} @end table @@ -1940,8 +1961,12 @@ end program atomic @end smallexample @item @emph{See also}: -@ref{ATOMIC_DEFINE}, @ref{ATOMIC_FETCH_AND}, @ref{ISO_FORTRAN_ENV}, -@ref{ATOMIC_ADD}, @ref{ATOMIC_OR}, @ref{ATOMIC_XOR} +@ref{ATOMIC_DEFINE}, @gol +@ref{ATOMIC_FETCH_AND}, @gol +@ref{ISO_FORTRAN_ENV}, @gol +@ref{ATOMIC_ADD}, @gol +@ref{ATOMIC_OR}, @gol +@ref{ATOMIC_XOR} @end table @@ -1995,7 +2020,9 @@ end program atomic @end smallexample @item @emph{See also}: -@ref{ATOMIC_DEFINE}, @ref{ATOMIC_REF}, @ref{ISO_FORTRAN_ENV} +@ref{ATOMIC_DEFINE}, @gol +@ref{ATOMIC_REF}, @gol +@ref{ISO_FORTRAN_ENV} @end table @@ -2045,8 +2072,13 @@ end program atomic @end smallexample @item @emph{See also}: -@ref{ATOMIC_REF}, @ref{ATOMIC_CAS}, @ref{ISO_FORTRAN_ENV}, -@ref{ATOMIC_ADD}, @ref{ATOMIC_AND}, @ref{ATOMIC_OR}, @ref{ATOMIC_XOR} +@ref{ATOMIC_REF}, @gol +@ref{ATOMIC_CAS}, @gol +@ref{ISO_FORTRAN_ENV}, @gol +@ref{ATOMIC_ADD}, @gol +@ref{ATOMIC_AND}, @gol +@ref{ATOMIC_OR}, @gol +@ref{ATOMIC_XOR} @end table @@ -2098,8 +2130,12 @@ end program atomic @end smallexample @item @emph{See also}: -@ref{ATOMIC_DEFINE}, @ref{ATOMIC_ADD}, @ref{ISO_FORTRAN_ENV}, -@ref{ATOMIC_FETCH_AND}, @ref{ATOMIC_FETCH_OR}, @ref{ATOMIC_FETCH_XOR} +@ref{ATOMIC_DEFINE}, @gol +@ref{ATOMIC_ADD}, @gol +@ref{ISO_FORTRAN_ENV}, @gol +@ref{ATOMIC_FETCH_AND}, @gol +@ref{ATOMIC_FETCH_OR}, @gol +@ref{ATOMIC_FETCH_XOR} @end table @@ -2149,8 +2185,12 @@ end program atomic @end smallexample @item @emph{See also}: -@ref{ATOMIC_DEFINE}, @ref{ATOMIC_AND}, @ref{ISO_FORTRAN_ENV}, -@ref{ATOMIC_FETCH_ADD}, @ref{ATOMIC_FETCH_OR}, @ref{ATOMIC_FETCH_XOR} +@ref{ATOMIC_DEFINE}, @gol +@ref{ATOMIC_AND}, @gol +@ref{ISO_FORTRAN_ENV}, @gol +@ref{ATOMIC_FETCH_ADD}, @gol +@ref{ATOMIC_FETCH_OR}, @gol +@ref{ATOMIC_FETCH_XOR} @end table @@ -2200,8 +2240,12 @@ end program atomic @end smallexample @item @emph{See also}: -@ref{ATOMIC_DEFINE}, @ref{ATOMIC_OR}, @ref{ISO_FORTRAN_ENV}, -@ref{ATOMIC_FETCH_ADD}, @ref{ATOMIC_FETCH_AND}, @ref{ATOMIC_FETCH_XOR} +@ref{ATOMIC_DEFINE}, @gol +@ref{ATOMIC_OR}, @gol +@ref{ISO_FORTRAN_ENV}, @gol +@ref{ATOMIC_FETCH_ADD}, @gol +@ref{ATOMIC_FETCH_AND}, @gol +@ref{ATOMIC_FETCH_XOR} @end table @@ -2251,8 +2295,12 @@ end program atomic @end smallexample @item @emph{See also}: -@ref{ATOMIC_DEFINE}, @ref{ATOMIC_XOR}, @ref{ISO_FORTRAN_ENV}, -@ref{ATOMIC_FETCH_ADD}, @ref{ATOMIC_FETCH_AND}, @ref{ATOMIC_FETCH_OR} +@ref{ATOMIC_DEFINE}, @gol +@ref{ATOMIC_XOR}, @gol +@ref{ISO_FORTRAN_ENV}, @gol +@ref{ATOMIC_FETCH_ADD}, @gol +@ref{ATOMIC_FETCH_AND}, @gol +@ref{ATOMIC_FETCH_OR} @end table @@ -2300,8 +2348,12 @@ end program atomic @end smallexample @item @emph{See also}: -@ref{ATOMIC_DEFINE}, @ref{ATOMIC_FETCH_OR}, @ref{ISO_FORTRAN_ENV}, -@ref{ATOMIC_ADD}, @ref{ATOMIC_OR}, @ref{ATOMIC_XOR} +@ref{ATOMIC_DEFINE}, @gol +@ref{ATOMIC_FETCH_OR}, @gol +@ref{ISO_FORTRAN_ENV}, @gol +@ref{ATOMIC_ADD}, @gol +@ref{ATOMIC_OR}, @gol +@ref{ATOMIC_XOR} @end table @@ -2357,8 +2409,12 @@ end program atomic @end smallexample @item @emph{See also}: -@ref{ATOMIC_DEFINE}, @ref{ATOMIC_CAS}, @ref{ISO_FORTRAN_ENV}, -@ref{ATOMIC_FETCH_ADD}, @ref{ATOMIC_FETCH_AND}, @ref{ATOMIC_FETCH_OR}, +@ref{ATOMIC_DEFINE}, @gol +@ref{ATOMIC_CAS}, @gol +@ref{ISO_FORTRAN_ENV}, @gol +@ref{ATOMIC_FETCH_ADD}, @gol +@ref{ATOMIC_FETCH_AND}, @gol +@ref{ATOMIC_FETCH_OR}, @gol @ref{ATOMIC_FETCH_XOR} @end table @@ -2406,8 +2462,12 @@ end program atomic @end smallexample @item @emph{See also}: -@ref{ATOMIC_DEFINE}, @ref{ATOMIC_FETCH_XOR}, @ref{ISO_FORTRAN_ENV}, -@ref{ATOMIC_ADD}, @ref{ATOMIC_OR}, @ref{ATOMIC_XOR} +@ref{ATOMIC_DEFINE}, @gol +@ref{ATOMIC_FETCH_XOR}, @gol +@ref{ISO_FORTRAN_ENV}, @gol +@ref{ATOMIC_ADD}, @gol +@ref{ATOMIC_OR}, @gol +@ref{ATOMIC_XOR} @end table @@ -2794,7 +2854,9 @@ as @var{I}. The return value is of type @code{LOGICAL} and of the default kind. @item @emph{See also}: -@ref{BGT}, @ref{BLE}, @ref{BLT} +@ref{BGT}, @gol +@ref{BLE}, @gol +@ref{BLT} @end table @@ -2828,7 +2890,9 @@ as @var{I}. The return value is of type @code{LOGICAL} and of the default kind. @item @emph{See also}: -@ref{BGE}, @ref{BLE}, @ref{BLT} +@ref{BGE}, @gol +@ref{BLE}, @gol +@ref{BLT} @end table @@ -2905,7 +2969,9 @@ as @var{I}. The return value is of type @code{LOGICAL} and of the default kind. @item @emph{See also}: -@ref{BGT}, @ref{BGE}, @ref{BLT} +@ref{BGT}, @gol +@ref{BGE}, @gol +@ref{BLT} @end table @@ -2939,7 +3005,9 @@ as @var{I}. The return value is of type @code{LOGICAL} and of the default kind. @item @emph{See also}: -@ref{BGE}, @ref{BGT}, @ref{BLE} +@ref{BGE}, @gol +@ref{BGT}, @gol +@ref{BLE} @end table @@ -3044,7 +3112,8 @@ end subroutine association_test @end smallexample @item @emph{See also}: -@ref{C_LOC}, @ref{C_FUNLOC} +@ref{C_LOC}, @gol +@ref{C_FUNLOC} @end table @@ -3098,7 +3167,8 @@ end program main @end smallexample @item @emph{See also}: -@ref{C_LOC}, @ref{C_F_PROCPOINTER} +@ref{C_LOC}, @gol +@ref{C_F_PROCPOINTER} @end table @@ -3155,7 +3225,8 @@ end program main @end smallexample @item @emph{See also}: -@ref{C_LOC}, @ref{C_F_POINTER} +@ref{C_LOC}, @gol +@ref{C_F_POINTER} @end table @@ -3212,7 +3283,10 @@ end program main @end smallexample @item @emph{See also}: -@ref{C_ASSOCIATED}, @ref{C_LOC}, @ref{C_F_POINTER}, @ref{C_F_PROCPOINTER} +@ref{C_ASSOCIATED}, @gol +@ref{C_LOC}, @gol +@ref{C_F_POINTER}, @gol +@ref{C_F_PROCPOINTER} @end table @@ -3257,7 +3331,10 @@ end subroutine association_test @end smallexample @item @emph{See also}: -@ref{C_ASSOCIATED}, @ref{C_FUNLOC}, @ref{C_F_POINTER}, @ref{C_F_PROCPOINTER} +@ref{C_ASSOCIATED}, @gol +@ref{C_FUNLOC}, @gol +@ref{C_F_POINTER}, @gol +@ref{C_F_PROCPOINTER} @end table @@ -3307,7 +3384,8 @@ The example will print @code{.TRUE.} unless you are using a platform where default @code{REAL} variables are unusually padded. @item @emph{See also}: -@ref{SIZEOF}, @ref{STORAGE_SIZE} +@ref{SIZEOF}, @gol +@ref{STORAGE_SIZE} @end table @@ -3352,8 +3430,8 @@ end program test_ceiling @end smallexample @item @emph{See also}: -@ref{FLOOR}, @ref{NINT} - +@ref{FLOOR}, @gol +@ref{NINT} @end table @@ -3397,7 +3475,7 @@ end program test_char @end smallexample @item @emph{Specific names}: -@multitable @columnfractions .20 .20 .20 .25 +@multitable @columnfractions .18 .18 .24 .25 @item Name @tab Argument @tab Return type @tab Standard @item @code{CHAR(I)} @tab @code{INTEGER I} @tab @code{CHARACTER(LEN=1)} @tab F77 and later @end multitable @@ -3407,7 +3485,9 @@ See @ref{ICHAR} for a discussion of converting between numerical values and formatted string representations. @item @emph{See also}: -@ref{ACHAR}, @ref{IACHAR}, @ref{ICHAR} +@ref{ACHAR}, @gol +@ref{IACHAR}, @gol +@ref{ICHAR} @end table @@ -3612,7 +3692,7 @@ Collective subroutine @code{CALL CO_BROADCAST(A, SOURCE_IMAGE [, STAT, ERRMSG])} @item @emph{Arguments}: -@multitable @columnfractions .15 .70 +@multitable @columnfractions .20 .65 @item @var{A} @tab INTENT(INOUT) argument; shall have the same dynamic type and type paramters on all images of the current team. If it is an array, it shall have the same shape on all images. @@ -3636,7 +3716,10 @@ end program test @end smallexample @item @emph{See also}: -@ref{CO_MAX}, @ref{CO_MIN}, @ref{CO_SUM}, @ref{CO_REDUCE} +@ref{CO_MAX}, @gol +@ref{CO_MIN}, @gol +@ref{CO_SUM}, @gol +@ref{CO_REDUCE} @end table @@ -3667,7 +3750,7 @@ Collective subroutine @code{CALL CO_MAX(A [, RESULT_IMAGE, STAT, ERRMSG])} @item @emph{Arguments}: -@multitable @columnfractions .15 .70 +@multitable @columnfractions .20 .65 @item @var{A} @tab shall be an integer, real or character variable, which has the same type and type parameters on all images of the team. @item @var{RESULT_IMAGE} @tab (optional) a scalar integer expression; if @@ -3690,7 +3773,10 @@ end program test @end smallexample @item @emph{See also}: -@ref{CO_MIN}, @ref{CO_SUM}, @ref{CO_REDUCE}, @ref{CO_BROADCAST} +@ref{CO_MIN}, @gol +@ref{CO_SUM}, @gol +@ref{CO_REDUCE}, @gol +@ref{CO_BROADCAST} @end table @@ -3721,7 +3807,7 @@ Collective subroutine @code{CALL CO_MIN(A [, RESULT_IMAGE, STAT, ERRMSG])} @item @emph{Arguments}: -@multitable @columnfractions .15 .70 +@multitable @columnfractions .20 .65 @item @var{A} @tab shall be an integer, real or character variable, which has the same type and type parameters on all images of the team. @item @var{RESULT_IMAGE} @tab (optional) a scalar integer expression; if @@ -3744,7 +3830,10 @@ end program test @end smallexample @item @emph{See also}: -@ref{CO_MAX}, @ref{CO_SUM}, @ref{CO_REDUCE}, @ref{CO_BROADCAST} +@ref{CO_MAX}, @gol +@ref{CO_SUM}, @gol +@ref{CO_REDUCE}, @gol +@ref{CO_BROADCAST} @end table @@ -3779,7 +3868,7 @@ Collective subroutine @code{CALL CO_REDUCE(A, OPERATOR, [, RESULT_IMAGE, STAT, ERRMSG])} @item @emph{Arguments}: -@multitable @columnfractions .15 .70 +@multitable @columnfractions .20 .65 @item @var{A} @tab is an @code{INTENT(INOUT)} argument and shall be nonpolymorphic. If it is allocatable, it shall be allocated; if it is a pointer, it shall be associated. @var{A} shall have the same type and type parameters on @@ -3824,7 +3913,10 @@ function, which takes two arguments of the same type and returning that type as result. @item @emph{See also}: -@ref{CO_MIN}, @ref{CO_MAX}, @ref{CO_SUM}, @ref{CO_BROADCAST} +@ref{CO_MIN}, @gol +@ref{CO_MAX}, @gol +@ref{CO_SUM}, @gol +@ref{CO_BROADCAST} @end table @@ -3855,7 +3947,7 @@ Collective subroutine @code{CALL CO_MIN(A [, RESULT_IMAGE, STAT, ERRMSG])} @item @emph{Arguments}: -@multitable @columnfractions .15 .70 +@multitable @columnfractions .20 .65 @item @var{A} @tab shall be an integer, real or complex variable, which has the same type and type parameters on all images of the team. @item @var{RESULT_IMAGE} @tab (optional) a scalar integer expression; if @@ -3872,13 +3964,17 @@ program test val = this_image () call co_sum (val, result_image=1) if (this_image() == 1) then - write(*,*) "The sum is ", val ! prints (n**2 + n)/2, with n = num_images() + write(*,*) "The sum is ", val ! prints (n**2 + n)/2, + ! with n = num_images() end if end program test @end smallexample @item @emph{See also}: -@ref{CO_MAX}, @ref{CO_MIN}, @ref{CO_REDUCE}, @ref{CO_BROADCAST} +@ref{CO_MAX}, @gol +@ref{CO_MIN}, @gol +@ref{CO_REDUCE}, @gol +@ref{CO_BROADCAST} @end table @@ -3922,7 +4018,8 @@ end program test_command_argument_count @end smallexample @item @emph{See also}: -@ref{GET_COMMAND}, @ref{GET_COMMAND_ARGUMENT} +@ref{GET_COMMAND}, @gol +@ref{GET_COMMAND_ARGUMENT} @end table @@ -3966,7 +4063,8 @@ the @code{COMPILER_OPTIONS} intrinsic. @end smallexample @item @emph{See also}: -@ref{COMPILER_VERSION}, @ref{ISO_FORTRAN_ENV} +@ref{COMPILER_VERSION}, @gol +@ref{ISO_FORTRAN_ENV} @end table @@ -4008,7 +4106,8 @@ It contains the name of the compiler and its version number. @end smallexample @item @emph{See also}: -@ref{COMPILER_OPTIONS}, @ref{ISO_FORTRAN_ENV} +@ref{COMPILER_OPTIONS}, @gol +@ref{ISO_FORTRAN_ENV} @end table @@ -4167,9 +4266,10 @@ end program test_cos @end multitable @item @emph{See also}: -Inverse function: @ref{ACOS} -Degrees function: @ref{COSD} - +Inverse function: @gol +@ref{ACOS} @gol +Degrees function: @gol +@ref{COSD} @end table @@ -4230,9 +4330,10 @@ end program test_cosd @end multitable @item @emph{See also}: -Inverse function: @ref{ACOSD} -Radians function: @ref{COS} - +Inverse function: @gol +@ref{ACOSD} @gol +Radians function: @gol +@ref{COS} @end table @@ -4285,8 +4386,8 @@ end program test_cosh @end multitable @item @emph{See also}: -Inverse function: @ref{ACOSH} - +Inverse function: @gol +@ref{ACOSH} @end table @@ -4339,8 +4440,10 @@ end program test_cotan @end multitable @item @emph{See also}: -Converse function: @ref{TAN} -Degrees function: @ref{COTAND} +Converse function: @gol +@ref{TAN} @gol +Degrees function: @gol +@ref{COTAND} @end table @@ -4393,9 +4496,10 @@ end program test_cotand @end multitable @item @emph{See also}: -Converse function: @ref{TAND} -Radians function: @ref{COTAN} - +Converse function: @gol +@ref{TAND} @gol +Radians function: @gol +@ref{COTAN} @end table @@ -4518,7 +4622,8 @@ end program test_cpu_time @end smallexample @item @emph{See also}: -@ref{SYSTEM_CLOCK}, @ref{DATE_AND_TIME} +@ref{SYSTEM_CLOCK}, @gol +@ref{DATE_AND_TIME} @end table @@ -4633,7 +4738,11 @@ end program test_ctime @end smallexample @item @emph{See Also}: -@ref{DATE_AND_TIME}, @ref{GMTIME}, @ref{LTIME}, @ref{TIME}, @ref{TIME8} +@ref{DATE_AND_TIME}, @gol +@ref{GMTIME}, @gol +@ref{LTIME}, @gol +@ref{TIME}, @gol +@ref{TIME8} @end table @@ -4709,7 +4818,8 @@ end program test_time_and_date @end smallexample @item @emph{See also}: -@ref{CPU_TIME}, @ref{SYSTEM_CLOCK} +@ref{CPU_TIME}, @gol +@ref{SYSTEM_CLOCK} @end table @@ -5707,7 +5817,8 @@ end program test_exit @end smallexample @item @emph{See also}: -@ref{ABORT}, @ref{KILL} +@ref{ABORT}, @gol +@ref{KILL} @end table @@ -5899,7 +6010,8 @@ end program test_fdate @end smallexample @item @emph{See also}: -@ref{DATE_AND_TIME}, @ref{CTIME} +@ref{DATE_AND_TIME}, @gol +@ref{CTIME} @end table @@ -5963,7 +6075,9 @@ END PROGRAM @end smallexample @item @emph{See also}: -@ref{FGETC}, @ref{FPUT}, @ref{FPUTC} +@ref{FGETC}, @gol +@ref{FPUT}, @gol +@ref{FPUTC} @end table @@ -6028,7 +6142,9 @@ END PROGRAM @end smallexample @item @emph{See also}: -@ref{FGET}, @ref{FPUT}, @ref{FPUTC} +@ref{FGET}, @gol +@ref{FPUT}, @gol +@ref{FPUTC} @end table @node FINDLOC @@ -6089,7 +6205,8 @@ is present, the result is an integer of kind @var{KIND}, otherwise it is of default kind. @item @emph{See also}: -@ref{MAXLOC}, @ref{MINLOC} +@ref{MAXLOC}, @gol +@ref{MINLOC} @end table @@ -6134,8 +6251,8 @@ end program test_floor @end smallexample @item @emph{See also}: -@ref{CEILING}, @ref{NINT} - +@ref{CEILING}, @gol +@ref{NINT} @end table @@ -6305,7 +6422,9 @@ END PROGRAM @end smallexample @item @emph{See also}: -@ref{FPUTC}, @ref{FGET}, @ref{FGETC} +@ref{FPUTC}, @gol +@ref{FGET}, @gol +@ref{FGETC} @end table @@ -6368,7 +6487,9 @@ END PROGRAM @end smallexample @item @emph{See also}: -@ref{FPUT}, @ref{FGET}, @ref{FGETC} +@ref{FPUT}, @gol +@ref{FGET}, @gol +@ref{FGETC} @end table @@ -6576,7 +6697,10 @@ on success and a system specific error code otherwise. See @ref{STAT} for an example. @item @emph{See also}: -To stat a link: @ref{LSTAT}, to stat a file: @ref{STAT} +To stat a link: @gol +@ref{LSTAT} @gol +To stat a file: @gol +@ref{STAT} @end table @@ -6684,8 +6808,8 @@ end program test_gamma @end multitable @item @emph{See also}: -Logarithm of the Gamma function: @ref{LOG_GAMMA} - +Logarithm of the Gamma function: @gol +@ref{LOG_GAMMA} @end table @@ -6724,7 +6848,8 @@ END PROGRAM @end smallexample @item @emph{See also}: -@ref{IERRNO}, @ref{PERROR} +@ref{IERRNO}, @gol +@ref{PERROR} @end table @@ -6785,10 +6910,12 @@ END PROGRAM @end smallexample @item @emph{See also}: -GNU Fortran 77 compatibility function: @ref{IARGC} - -Fortran 2003 functions and subroutines: @ref{GET_COMMAND}, -@ref{GET_COMMAND_ARGUMENT}, @ref{COMMAND_ARGUMENT_COUNT} +GNU Fortran 77 compatibility function: @gol +@ref{IARGC} @gol +Fortran 2003 functions and subroutines: @gol +@ref{GET_COMMAND}, @gol +@ref{GET_COMMAND_ARGUMENT}, @gol +@ref{COMMAND_ARGUMENT_COUNT} @end table @@ -6839,7 +6966,8 @@ END PROGRAM @end smallexample @item @emph{See also}: -@ref{GET_COMMAND_ARGUMENT}, @ref{COMMAND_ARGUMENT_COUNT} +@ref{GET_COMMAND_ARGUMENT}, @gol +@ref{COMMAND_ARGUMENT_COUNT} @end table @@ -6906,7 +7034,8 @@ END PROGRAM @end smallexample @item @emph{See also}: -@ref{GET_COMMAND}, @ref{COMMAND_ARGUMENT_COUNT} +@ref{GET_COMMAND}, @gol +@ref{COMMAND_ARGUMENT_COUNT} @end table @@ -7099,7 +7228,8 @@ kind. See @code{GETPID} for an example. @item @emph{See also}: -@ref{GETPID}, @ref{GETUID} +@ref{GETPID}, @gol +@ref{GETUID} @end table @@ -7183,7 +7313,8 @@ end program info @end smallexample @item @emph{See also}: -@ref{GETGID}, @ref{GETUID} +@ref{GETGID}, @gol +@ref{GETUID} @end table @@ -7216,7 +7347,8 @@ kind. See @code{GETPID} for an example. @item @emph{See also}: -@ref{GETPID}, @ref{GETLOG} +@ref{GETPID}, @gol +@ref{GETLOG} @end table @@ -7272,8 +7404,11 @@ effect, zero if not, and negative if the information is not available. @end enumerate @item @emph{See also}: -@ref{DATE_AND_TIME}, @ref{CTIME}, @ref{LTIME}, @ref{TIME}, @ref{TIME8} - +@ref{DATE_AND_TIME}, @gol +@ref{CTIME}, @gol +@ref{LTIME}, @gol +@ref{TIME}, @gol +@ref{TIME8} @end table @@ -7441,8 +7576,9 @@ See @ref{ICHAR} for a discussion of converting between numerical values and formatted string representations. @item @emph{See also}: -@ref{ACHAR}, @ref{CHAR}, @ref{ICHAR} - +@ref{ACHAR}, @gol +@ref{CHAR}, @gol +@ref{ICHAR} @end table @@ -7502,7 +7638,9 @@ END PROGRAM @end smallexample @item @emph{See also}: -@ref{IANY}, @ref{IPARITY}, @ref{IAND} +@ref{IANY}, @gol +@ref{IPARITY}, @gol +@ref{IAND} @end table @@ -7564,8 +7702,12 @@ END PROGRAM @end multitable @item @emph{See also}: -@ref{IOR}, @ref{IEOR}, @ref{IBITS}, @ref{IBSET}, @ref{IBCLR}, @ref{NOT} - +@ref{IOR}, @gol +@ref{IEOR}, @gol +@ref{IBITS}, @gol +@ref{IBSET}, @gol +@ref{IBCLR}, @gol +@ref{NOT} @end table @@ -7625,7 +7767,9 @@ END PROGRAM @end smallexample @item @emph{See also}: -@ref{IPARITY}, @ref{IALL}, @ref{IOR} +@ref{IPARITY}, @gol +@ref{IALL}, @gol +@ref{IOR} @end table @@ -7666,10 +7810,12 @@ The number of command line arguments, type @code{INTEGER(4)}. See @ref{GETARG} @item @emph{See also}: -GNU Fortran 77 compatibility subroutine: @ref{GETARG} - -Fortran 2003 functions and subroutines: @ref{GET_COMMAND}, -@ref{GET_COMMAND_ARGUMENT}, @ref{COMMAND_ARGUMENT_COUNT} +GNU Fortran 77 compatibility subroutine: @gol +@ref{GETARG} @gol +Fortran 2003 functions and subroutines: @gol +@ref{GET_COMMAND}, @gol +@ref{GET_COMMAND_ARGUMENT}, @gol +@ref{COMMAND_ARGUMENT_COUNT} @end table @@ -7719,8 +7865,12 @@ The return value is of type @code{INTEGER} and of the same kind as @end multitable @item @emph{See also}: -@ref{IBITS}, @ref{IBSET}, @ref{IAND}, @ref{IOR}, @ref{IEOR}, @ref{MVBITS} - +@ref{IBITS}, @gol +@ref{IBSET}, @gol +@ref{IAND}, @gol +@ref{IOR}, @gol +@ref{IEOR}, @gol +@ref{MVBITS} @end table @@ -7774,7 +7924,12 @@ The return value is of type @code{INTEGER} and of the same kind as @end multitable @item @emph{See also}: -@ref{BIT_SIZE}, @ref{IBCLR}, @ref{IBSET}, @ref{IAND}, @ref{IOR}, @ref{IEOR} +@ref{BIT_SIZE}, @gol +@ref{IBCLR}, @gol +@ref{IBSET}, @gol +@ref{IAND}, @gol +@ref{IOR}, @gol +@ref{IEOR} @end table @@ -7823,8 +7978,12 @@ The return value is of type @code{INTEGER} and of the same kind as @end multitable @item @emph{See also}: -@ref{IBCLR}, @ref{IBITS}, @ref{IAND}, @ref{IOR}, @ref{IEOR}, @ref{MVBITS} - +@ref{IBCLR}, @gol +@ref{IBITS}, @gol +@ref{IAND}, @gol +@ref{IOR}, @gol +@ref{IEOR}, @gol +@ref{MVBITS} @end table @@ -7899,8 +8058,9 @@ end program read_val @end smallexample @item @emph{See also}: -@ref{ACHAR}, @ref{CHAR}, @ref{IACHAR} - +@ref{ACHAR}, @gol +@ref{CHAR}, @gol +@ref{IACHAR} @end table @@ -8006,7 +8166,12 @@ type parameter of the other argument as-if a call to @ref{INT} occurred. @end multitable @item @emph{See also}: -@ref{IOR}, @ref{IAND}, @ref{IBITS}, @ref{IBSET}, @ref{IBCLR}, @ref{NOT} +@ref{IOR}, @gol +@ref{IAND}, @gol +@ref{IBITS}, @gol +@ref{IBSET}, @gol +@ref{IBCLR}, @gol +@ref{NOT} @end table @@ -8082,7 +8247,8 @@ WRITE (*,*) IMAGE_INDEX (array, [2,0,3,1]) @end smallexample @item @emph{See also}: -@ref{THIS_IMAGE}, @ref{NUM_IMAGES} +@ref{THIS_IMAGE}, @gol +@ref{NUM_IMAGES} @end table @@ -8133,7 +8299,8 @@ The return value is of type @code{INTEGER} and of kind @var{KIND}. If @end multitable @item @emph{See also}: -@ref{SCAN}, @ref{VERIFY} +@ref{SCAN}, @gol +@ref{VERIFY} @end table @@ -8236,7 +8403,9 @@ Elemental function The return value is a @code{INTEGER(2)} variable. @item @emph{See also}: -@ref{INT}, @ref{INT8}, @ref{LONG} +@ref{INT}, @gol +@ref{INT8}, @gol +@ref{LONG} @end table @@ -8271,7 +8440,9 @@ Elemental function The return value is a @code{INTEGER(8)} variable. @item @emph{See also}: -@ref{INT}, @ref{INT2}, @ref{LONG} +@ref{INT}, @gol +@ref{INT2}, @gol +@ref{LONG} @end table @@ -8325,7 +8496,12 @@ type parameter of the other argument as-if a call to @ref{INT} occurred. @end multitable @item @emph{See also}: -@ref{IEOR}, @ref{IAND}, @ref{IBITS}, @ref{IBSET}, @ref{IBCLR}, @ref{NOT} +@ref{IEOR}, @gol +@ref{IAND}, @gol +@ref{IBITS}, @gol +@ref{IBSET}, @gol +@ref{IBCLR}, @gol +@ref{NOT} @end table @@ -8386,7 +8562,10 @@ END PROGRAM @end smallexample @item @emph{See also}: -@ref{IANY}, @ref{IALL}, @ref{IEOR}, @ref{PARITY} +@ref{IANY}, @gol +@ref{IALL}, @gol +@ref{IEOR}, @gol +@ref{PARITY} @end table @@ -8866,7 +9045,8 @@ Returns 0 on success; otherwise a system-specific error code is returned. @end multitable @item @emph{See also}: -@ref{ABORT}, @ref{EXIT} +@ref{ABORT}, @gol +@ref{EXIT} @end table @@ -8950,7 +9130,8 @@ structure component, or if it has a zero extent along the relevant dimension, the lower bound is taken to be 1. @item @emph{See also}: -@ref{UBOUND}, @ref{LCOBOUND} +@ref{UBOUND}, @gol +@ref{LCOBOUND} @end table @@ -8989,7 +9170,8 @@ If @var{DIM} is absent, the result is an array of the lower cobounds of corresponding to the lower cobound of the array along that codimension. @item @emph{See also}: -@ref{UCOBOUND}, @ref{LBOUND} +@ref{UCOBOUND}, @gol +@ref{LBOUND} @end table @@ -9030,7 +9212,10 @@ END PROGRAM @end smallexample @item @emph{See also}: -@ref{BIT_SIZE}, @ref{TRAILZ}, @ref{POPCNT}, @ref{POPPAR} +@ref{BIT_SIZE}, @gol +@ref{TRAILZ}, @gol +@ref{POPCNT}, @gol +@ref{POPPAR} @end table @@ -9077,7 +9262,9 @@ The return value is of type @code{INTEGER} and of kind @var{KIND}. If @item @emph{See also}: -@ref{LEN_TRIM}, @ref{ADJUSTL}, @ref{ADJUSTR} +@ref{LEN_TRIM}, @gol +@ref{ADJUSTL}, @gol +@ref{ADJUSTR} @end table @@ -9113,7 +9300,9 @@ The return value is of type @code{INTEGER} and of kind @var{KIND}. If @var{KIND} is absent, the return value is of default integer kind. @item @emph{See also}: -@ref{LEN}, @ref{ADJUSTL}, @ref{ADJUSTR} +@ref{LEN}, @gol +@ref{ADJUSTL}, @gol +@ref{ADJUSTR} @end table @@ -9165,7 +9354,9 @@ otherwise, based on the ASCII ordering. @end multitable @item @emph{See also}: -@ref{LGT}, @ref{LLE}, @ref{LLT} +@ref{LGT}, @gol +@ref{LLE}, @gol +@ref{LLT} @end table @@ -9217,7 +9408,9 @@ otherwise, based on the ASCII ordering. @end multitable @item @emph{See also}: -@ref{LGE}, @ref{LLE}, @ref{LLT} +@ref{LGE}, @gol +@ref{LLE}, @gol +@ref{LLT} @end table @@ -9260,7 +9453,8 @@ Subroutine, function @end multitable @item @emph{See also}: -@ref{SYMLNK}, @ref{UNLINK} +@ref{SYMLNK}, @gol +@ref{UNLINK} @end table @@ -9312,7 +9506,9 @@ otherwise, based on the ASCII ordering. @end multitable @item @emph{See also}: -@ref{LGE}, @ref{LGT}, @ref{LLT} +@ref{LGE}, @gol +@ref{LGT}, @gol +@ref{LLT} @end table @@ -9364,7 +9560,9 @@ otherwise, based on the ASCII ordering. @end multitable @item @emph{See also}: -@ref{LGE}, @ref{LGT}, @ref{LLE} +@ref{LGE}, @gol +@ref{LGT}, @gol +@ref{LLE} @end table @@ -9399,7 +9597,8 @@ with @code{INTENT(IN)} The return value is of @code{INTEGER(kind=4)} type. @item @emph{See also}: -@ref{INDEX intrinsic}, @ref{LEN_TRIM} +@ref{INDEX intrinsic}, @gol +@ref{LEN_TRIM} @end table @@ -9603,8 +9802,8 @@ end program test_log_gamma @end multitable @item @emph{See also}: -Gamma function: @ref{GAMMA} - +Gamma function: @gol +@ref{GAMMA} @end table @@ -9640,7 +9839,9 @@ kind corresponding to @var{KIND}, or of the default logical kind if @var{KIND} is not given. @item @emph{See also}: -@ref{INT}, @ref{REAL}, @ref{CMPLX} +@ref{INT}, @gol +@ref{REAL}, @gol +@ref{CMPLX} @end table @@ -9676,7 +9877,9 @@ Elemental function The return value is a @code{INTEGER(4)} variable. @item @emph{See also}: -@ref{INT}, @ref{INT2}, @ref{INT8} +@ref{INT}, @gol +@ref{INT2}, @gol +@ref{INT8} @end table @@ -9718,9 +9921,12 @@ The return value is of type @code{INTEGER} and of the same kind as @var{I}. @item @emph{See also}: -@ref{ISHFT}, @ref{ISHFTC}, @ref{RSHIFT}, @ref{SHIFTA}, @ref{SHIFTL}, +@ref{ISHFT}, @gol +@ref{ISHFTC}, @gol +@ref{RSHIFT}, @gol +@ref{SHIFTA}, @gol +@ref{SHIFTL}, @gol @ref{SHIFTR} - @end table @@ -9766,7 +9972,10 @@ Returns 0 on success and a system specific error code otherwise. See @ref{STAT} for an example. @item @emph{See also}: -To stat an open file: @ref{FSTAT}, to stat a file: @ref{STAT} +To stat an open file: @gol +@ref{FSTAT} @gol +To stat a file: @gol +@ref{STAT} @end table @@ -9821,8 +10030,11 @@ effect, zero if not, and negative if the information is not available. @end enumerate @item @emph{See also}: -@ref{DATE_AND_TIME}, @ref{CTIME}, @ref{GMTIME}, @ref{TIME}, @ref{TIME8} - +@ref{DATE_AND_TIME}, @gol +@ref{CTIME}, @gol +@ref{GMTIME}, @gol +@ref{TIME}, @gol +@ref{TIME8} @end table @@ -10051,8 +10263,9 @@ and has the same type and kind as the first argument. @end multitable @item @emph{See also}: -@ref{MAXLOC} @ref{MAXVAL}, @ref{MIN} - +@ref{MAXLOC} @gol +@ref{MAXVAL}, @gol +@ref{MIN} @end table @@ -10159,8 +10372,9 @@ is present, the result is an integer of kind @var{KIND}, otherwise it is of default kind. @item @emph{See also}: -@ref{FINDLOC}, @ref{MAX}, @ref{MAXVAL} - +@ref{FINDLOC}, @gol +@ref{MAX}, @gol +@ref{MAXVAL} @end table @@ -10213,7 +10427,8 @@ the size of @var{ARRAY} with the @var{DIM} dimension removed. In all cases, the result is of the same type and kind as @var{ARRAY}. @item @emph{See also}: -@ref{MAX}, @ref{MAXLOC} +@ref{MAX}, @gol +@ref{MAXLOC} @end table @@ -10250,8 +10465,11 @@ number of clock ticks since the start of the process, or @code{-1} if the system does not support @code{clock(3)}. @item @emph{See also}: -@ref{CTIME}, @ref{GMTIME}, @ref{LTIME}, @ref{MCLOCK}, @ref{TIME} - +@ref{CTIME}, @gol +@ref{GMTIME}, @gol +@ref{LTIME}, @gol +@ref{MCLOCK}, @gol +@ref{TIME} @end table @@ -10290,8 +10508,11 @@ number of clock ticks since the start of the process, or @code{-1} if the system does not support @code{clock(3)}. @item @emph{See also}: -@ref{CTIME}, @ref{GMTIME}, @ref{LTIME}, @ref{MCLOCK}, @ref{TIME8} - +@ref{CTIME}, @gol +@ref{GMTIME}, @gol +@ref{LTIME}, @gol +@ref{MCLOCK}, @gol +@ref{TIME8} @end table @@ -10417,7 +10638,9 @@ and has the same type and kind as the first argument. @end multitable @item @emph{See also}: -@ref{MAX}, @ref{MINLOC}, @ref{MINVAL} +@ref{MAX}, @gol +@ref{MINLOC}, @gol +@ref{MINVAL} @end table @@ -10516,8 +10739,9 @@ is present, the result is an integer of kind @var{KIND}, otherwise it is of default kind. @item @emph{See also}: -@ref{FINDLOC}, @ref{MIN}, @ref{MINVAL} - +@ref{FINDLOC}, @gol +@ref{MIN}, @gol +@ref{MINVAL} @end table @@ -10570,8 +10794,8 @@ the size of @var{ARRAY} with the @var{DIM} dimension removed. In all cases, the result is of the same type and kind as @var{ARRAY}. @item @emph{See also}: -@ref{MIN}, @ref{MINLOC} - +@ref{MIN}, @gol +@ref{MINLOC} @end table @@ -10812,7 +11036,12 @@ same kind as @var{FROM}. @end multitable @item @emph{See also}: -@ref{IBCLR}, @ref{IBSET}, @ref{IBITS}, @ref{IAND}, @ref{IOR}, @ref{IEOR} +@ref{IBCLR}, @gol +@ref{IBSET}, @gol +@ref{IBITS}, @gol +@ref{IAND}, @gol +@ref{IOR}, @gol +@ref{IEOR} @end table @@ -10954,8 +11183,8 @@ end program test_nint @end multitable @item @emph{See also}: -@ref{CEILING}, @ref{FLOOR} - +@ref{CEILING}, @gol +@ref{FLOOR} @end table @@ -11055,8 +11284,12 @@ argument. @end multitable @item @emph{See also}: -@ref{IAND}, @ref{IEOR}, @ref{IOR}, @ref{IBITS}, @ref{IBSET}, @ref{IBCLR} - +@ref{IAND}, @gol +@ref{IEOR}, @gol +@ref{IOR}, @gol +@ref{IBITS}, @gol +@ref{IBSET}, @gol +@ref{IBCLR} @end table @@ -11158,7 +11391,8 @@ END IF @end smallexample @item @emph{See also}: -@ref{THIS_IMAGE}, @ref{IMAGE_INDEX} +@ref{THIS_IMAGE}, @gol +@ref{IMAGE_INDEX} @end table @@ -11217,7 +11451,8 @@ END PROGRAM @end smallexample @item @emph{See also}: -Fortran 95 elemental function: @ref{IOR} +Fortran 95 elemental function: @gol +@ref{IOR} @end table @@ -11280,7 +11515,8 @@ Gathering nonzero elements from an array and appending elements from @var{VECTOR PROGRAM test_pack_2 INTEGER :: m(4) m = (/ 1, 0, 0, 2 /) - WRITE(*, FMT="(4(I0, ' '))") pack(m, m /= 0, (/ 0, 0, 3, 4 /)) ! "1 2 3 4" + ! The following results in "1 2 3 4" + WRITE(*, FMT="(4(I0, ' '))") pack(m, m /= 0, (/ 0, 0, 3, 4 /)) END PROGRAM @end smallexample @@ -11412,8 +11648,9 @@ program test_population end program test_population @end smallexample @item @emph{See also}: -@ref{POPPAR}, @ref{LEADZ}, @ref{TRAILZ} - +@ref{POPPAR}, @gol +@ref{LEADZ}, @gol +@ref{TRAILZ} @end table @@ -11457,7 +11694,9 @@ program test_population end program test_population @end smallexample @item @emph{See also}: -@ref{POPCNT}, @ref{LEADZ}, @ref{TRAILZ} +@ref{POPCNT}, @gol +@ref{LEADZ}, @gol +@ref{TRAILZ} @end table @@ -11501,7 +11740,8 @@ program prec_and_range end program prec_and_range @end smallexample @item @emph{See also}: -@ref{SELECTED_REAL_KIND}, @ref{RANGE} +@ref{SELECTED_REAL_KIND}, @gol +@ref{RANGE} @end table @@ -11668,7 +11908,8 @@ GNU extension Function @item @emph{See also}: -@ref{RAND}, @ref{RANDOM_NUMBER} +@ref{RAND}, @gol +@ref{RANDOM_NUMBER} @end table @@ -11720,7 +11961,8 @@ end program test_rand @end smallexample @item @emph{See also}: -@ref{SRAND}, @ref{RANDOM_NUMBER} +@ref{SRAND}, @gol +@ref{RANDOM_NUMBER} @end table @@ -11745,7 +11987,7 @@ Subroutine @code{CALL RANDOM_INIT(REPEATABLE, IMAGE_DISTINCT)} @item @emph{Arguments}: -@multitable @columnfractions .20 .75 +@multitable @columnfractions .25 .70 @item @var{REPEATABLE} @tab Shall be a scalar with a @code{LOGICAL} type, and it is @code{INTENT(IN)}. If it is @code{.true.}, the seed is set to a processor-dependent value that is the same each time @code{RANDOM_INIT} @@ -11776,7 +12018,8 @@ end program test_random_seed @end smallexample @item @emph{See also}: -@ref{RANDOM_NUMBER}, @ref{RANDOM_SEED} +@ref{RANDOM_NUMBER}, @gol +@ref{RANDOM_SEED} @end table @@ -11824,7 +12067,8 @@ end program @end smallexample @item @emph{See also}: -@ref{RANDOM_SEED}, @ref{RANDOM_INIT} +@ref{RANDOM_SEED}, @gol +@ref{RANDOM_INIT} @end table @@ -11894,7 +12138,8 @@ end program test_random_seed @end smallexample @item @emph{See also}: -@ref{RANDOM_NUMBER}, @ref{RANDOM_INIT} +@ref{RANDOM_NUMBER}, @gol +@ref{RANDOM_INIT} @end table @@ -11931,7 +12176,8 @@ kind. @item @emph{Example}: See @code{PRECISION} for an example. @item @emph{See also}: -@ref{SELECTED_REAL_KIND}, @ref{PRECISION} +@ref{SELECTED_REAL_KIND}, @gol +@ref{PRECISION} @end table @@ -12271,7 +12517,11 @@ The return value is of type @code{INTEGER} and of the same kind as @var{I}. @item @emph{See also}: -@ref{ISHFT}, @ref{ISHFTC}, @ref{LSHIFT}, @ref{SHIFTA}, @ref{SHIFTR}, +@ref{ISHFT}, @gol +@ref{ISHFTC}, @gol +@ref{LSHIFT}, @gol +@ref{SHIFTA}, @gol +@ref{SHIFTR}, @gol @ref{SHIFTL} @end table @@ -12404,7 +12654,8 @@ END PROGRAM @end smallexample @item @emph{See also}: -@ref{INDEX intrinsic}, @ref{VERIFY} +@ref{INDEX intrinsic}, @gol +@ref{VERIFY} @end table @@ -12672,7 +12923,9 @@ program real_kinds end program real_kinds @end smallexample @item @emph{See also}: -@ref{PRECISION}, @ref{RANGE}, @ref{RADIX} +@ref{PRECISION}, @gol +@ref{RANGE}, @gol +@ref{RADIX} @end table @@ -12766,7 +13019,8 @@ END PROGRAM @end smallexample @item @emph{See also}: -@ref{RESHAPE}, @ref{SIZE} +@ref{RESHAPE}, @gol +@ref{SIZE} @end table @@ -12807,7 +13061,8 @@ The return value is of type @code{INTEGER} and of the same kind as @var{I}. @item @emph{See also}: -@ref{SHIFTL}, @ref{SHIFTR} +@ref{SHIFTL}, @gol +@ref{SHIFTR} @end table @@ -12846,7 +13101,8 @@ The return value is of type @code{INTEGER} and of the same kind as @var{I}. @item @emph{See also}: -@ref{SHIFTA}, @ref{SHIFTR} +@ref{SHIFTA}, @gol +@ref{SHIFTR} @end table @@ -12885,7 +13141,8 @@ The return value is of type @code{INTEGER} and of the same kind as @var{I}. @item @emph{See also}: -@ref{SHIFTA}, @ref{SHIFTL} +@ref{SHIFTA}, @gol +@ref{SHIFTL} @end table @@ -13054,8 +13311,10 @@ end program test_sin @end multitable @item @emph{See also}: -Inverse function: @ref{ASIN} -Degrees function: @ref{SIND} +Inverse function: @gol +@ref{ASIN} @gol +Degrees function: @gol +@ref{SIND} @end table @@ -13114,9 +13373,10 @@ end program test_sind @end multitable @item @emph{See also}: -Inverse function: @ref{ASIND} -Radians function: @ref{SIN} - +Inverse function: @gol +@ref{ASIND} @gol +Radians function: @gol +@ref{SIN} @gol @end table @@ -13215,7 +13475,8 @@ END PROGRAM @end smallexample @item @emph{See also}: -@ref{SHAPE}, @ref{RESHAPE} +@ref{SHAPE}, @gol +@ref{RESHAPE} @end table @@ -13268,7 +13529,8 @@ The example will print @code{.TRUE.} unless you are using a platform where default @code{REAL} variables are unusually padded. @item @emph{See also}: -@ref{C_SIZEOF}, @ref{STORAGE_SIZE} +@ref{C_SIZEOF}, @gol +@ref{STORAGE_SIZE} @end table @@ -13499,8 +13761,9 @@ Please note that in GNU Fortran, these two sets of intrinsics (@code{RAND}, pseudo-random number generators. @item @emph{See also}: -@ref{RAND}, @ref{RANDOM_SEED}, @ref{RANDOM_NUMBER} - +@ref{RAND}, @gol +@ref{RANDOM_SEED}, @gol +@ref{RANDOM_NUMBER} @end table @@ -13587,7 +13850,10 @@ END PROGRAM @end smallexample @item @emph{See also}: -To stat an open file: @ref{FSTAT}, to stat a link: @ref{LSTAT} +To stat an open file: @gol +@ref{FSTAT} @gol +To stat a link: @gol +@ref{LSTAT} @end table @@ -13620,7 +13886,8 @@ expressed in bits for an element of an array that has the dynamic type and type parameters of A. @item @emph{See also}: -@ref{C_SIZEOF}, @ref{SIZEOF} +@ref{C_SIZEOF}, @gol +@ref{SIZEOF} @end table @@ -13723,8 +13990,8 @@ Subroutine, function @end multitable @item @emph{See also}: -@ref{LINK}, @ref{UNLINK} - +@ref{LINK}, @gol +@ref{UNLINK} @end table @@ -13827,7 +14094,7 @@ Subroutine @code{CALL SYSTEM_CLOCK([COUNT, COUNT_RATE, COUNT_MAX])} @item @emph{Arguments}: -@multitable @columnfractions .15 .70 +@multitable @columnfractions .20 .65 @item @var{COUNT} @tab (Optional) shall be a scalar of type @code{INTEGER} with @code{INTENT(OUT)}. @item @var{COUNT_RATE} @tab (Optional) shall be a scalar of type @@ -13846,7 +14113,8 @@ END PROGRAM @end smallexample @item @emph{See also}: -@ref{DATE_AND_TIME}, @ref{CPU_TIME} +@ref{DATE_AND_TIME}, @gol +@ref{CPU_TIME} @end table @@ -13895,8 +14163,10 @@ end program test_tan @end multitable @item @emph{See also}: -Inverse function: @ref{ATAN} -Degrees function: @ref{TAND} +Inverse function: @gol +@ref{ATAN} @gol +Degrees function: @gol +@ref{TAND} @end table @@ -13948,8 +14218,10 @@ end program test_tand @end multitable @item @emph{See also}: -Inverse function: @ref{ATAND} -Radians function: @ref{TAN} +Inverse function: @gol +@ref{ATAND} @gol +Radians function: @gol +@ref{TAN} @end table @@ -14073,7 +14345,8 @@ IF (THIS_IMAGE(HUGE(1)) /= THIS_IMAGE()) @end smallexample @item @emph{See also}: -@ref{NUM_IMAGES}, @ref{IMAGE_INDEX} +@ref{NUM_IMAGES}, @gol +@ref{IMAGE_INDEX} @end table @@ -14113,8 +14386,12 @@ Function The return value is a scalar of type @code{INTEGER(4)}. @item @emph{See also}: -@ref{DATE_AND_TIME}, @ref{CTIME}, @ref{GMTIME}, @ref{LTIME}, @ref{MCLOCK}, @ref{TIME8} - +@ref{DATE_AND_TIME}, @gol +@ref{CTIME}, @gol +@ref{GMTIME}, @gol +@ref{LTIME}, @gol +@ref{MCLOCK}, @gol +@ref{TIME8} @end table @@ -14152,8 +14429,12 @@ Function The return value is a scalar of type @code{INTEGER(8)}. @item @emph{See also}: -@ref{DATE_AND_TIME}, @ref{CTIME}, @ref{GMTIME}, @ref{LTIME}, @ref{MCLOCK8}, @ref{TIME} - +@ref{DATE_AND_TIME}, @gol +@ref{CTIME}, @gol +@ref{GMTIME}, @gol +@ref{LTIME}, @gol +@ref{MCLOCK8}, @gol +@ref{TIME} @end table @@ -14227,7 +14508,10 @@ END PROGRAM @end smallexample @item @emph{See also}: -@ref{BIT_SIZE}, @ref{LEADZ}, @ref{POPPAR}, @ref{POPCNT} +@ref{BIT_SIZE}, @gol +@ref{LEADZ}, @gol +@ref{POPPAR}, @gol +@ref{POPCNT} @end table @@ -14364,7 +14648,8 @@ END PROGRAM @end smallexample @item @emph{See also}: -@ref{ADJUSTL}, @ref{ADJUSTR} +@ref{ADJUSTL}, @gol +@ref{ADJUSTR} @end table @@ -14454,7 +14739,8 @@ dimension, the upper bound is taken to be the number of elements along the relevant dimension. @item @emph{See also}: -@ref{LBOUND}, @ref{LCOBOUND} +@ref{LBOUND}, @gol +@ref{LCOBOUND} @end table @@ -14493,7 +14779,8 @@ If @var{DIM} is absent, the result is an array of the lower cobounds of corresponding to the lower cobound of the array along that codimension. @item @emph{See also}: -@ref{LCOBOUND}, @ref{LBOUND} +@ref{LCOBOUND}, @gol +@ref{LBOUND} @end table @@ -14567,7 +14854,8 @@ Subroutine, function @end multitable @item @emph{See also}: -@ref{LINK}, @ref{SYMLNK} +@ref{LINK}, @gol +@ref{SYMLNK} @end table @@ -14618,7 +14906,8 @@ END PROGRAM @end smallexample @item @emph{See also}: -@ref{PACK}, @ref{SPREAD} +@ref{PACK}, @gol +@ref{SPREAD} @end table @@ -14673,7 +14962,8 @@ END PROGRAM @end smallexample @item @emph{See also}: -@ref{SCAN}, @ref{INDEX intrinsic} +@ref{SCAN}, @gol +@ref{INDEX intrinsic} @end table @@ -14733,7 +15023,8 @@ END PROGRAM @end smallexample @item @emph{See also}: -Fortran 95 elemental function: @ref{IEOR} +Fortran 95 elemental function: @gol +@ref{IEOR} @end table -- cgit v1.1 From bf1a58e9be6a6a18b348812be19d965ce0111c7d Mon Sep 17 00:00:00 2001 From: Wilco Dijkstra Date: Fri, 23 Aug 2019 14:53:45 +0000 Subject: [ARM] Deprecate -mneon-for-64bits Deprecate -mneon-for-64bits since it no longer has any effect after the DImode codegen improvements. gcc/ * gcc/doc/invoke.texi (mneon-for-64bits): Deprecate option. * gcc/config/arm/arm.opt (mneon-for-64bits): Deprecate option. * gcc/config/arm/arm.h (TARGET_PREFER_NEON_64BITS): Remove. (prefer_neon_for_64bits): Remove. * gcc/config/arm/arm.c (prefer_neon_for_64bits): Remove. (tune_params): Remove PREF_NEON_64_FALSE uses. (arm_option_override): Remove prefer_neon selection code. (arm_print_tune_info): Remove prefer_neon_for_64bits. * gcc/config/arm/arm-protos.h (tune_params): Remove prefer_neon_for_64bits. (prefer_neon_for_64bits): Remove. From-SVN: r274858 --- gcc/ChangeLog | 14 ++++++++++++++ gcc/config/arm/arm-protos.h | 5 ----- gcc/config/arm/arm.c | 37 ------------------------------------- gcc/config/arm/arm.h | 7 ------- gcc/config/arm/arm.opt | 4 ++-- gcc/doc/invoke.texi | 4 +--- 6 files changed, 17 insertions(+), 54 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 86669dd..3fbdb93 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2019-08-23 Wilco Dijkstra + + * gcc/doc/invoke.texi (mneon-for-64bits): Deprecate option. + * gcc/config/arm/arm.opt (mneon-for-64bits): Deprecate option. + * gcc/config/arm/arm.h (TARGET_PREFER_NEON_64BITS): Remove. + (prefer_neon_for_64bits): Remove. + * gcc/config/arm/arm.c (prefer_neon_for_64bits): Remove. + (tune_params): Remove PREF_NEON_64_FALSE uses. + (arm_option_override): Remove prefer_neon selection code. + (arm_print_tune_info): Remove prefer_neon_for_64bits. + * gcc/config/arm/arm-protos.h (tune_params): Remove + prefer_neon_for_64bits. + (prefer_neon_for_64bits): Remove. + 2019-08-23 Iain Sandoe PR pch/61250 diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index bf2bf1c..8386d89 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -327,7 +327,6 @@ struct tune_params /* Prefer 32-bit encoding instead of flag-setting 16-bit encoding. */ enum {DISPARAGE_FLAGS_NEITHER, DISPARAGE_FLAGS_PARTIAL, DISPARAGE_FLAGS_ALL} disparage_flag_setting_t16_encodings: 2; - enum {PREF_NEON_64_FALSE, PREF_NEON_64_TRUE} prefer_neon_for_64bits: 1; /* Prefer to inline string operations like memset by using Neon. */ enum {PREF_NEON_STRINGOPS_FALSE, PREF_NEON_STRINGOPS_TRUE} string_ops_prefer_neon: 1; @@ -472,10 +471,6 @@ extern int arm_arch_thumb_hwdiv; /* Nonzero if chip disallows volatile memory access in IT block. */ extern int arm_arch_no_volatile_ce; -/* Nonzero if we should use Neon to handle 64-bits operations rather - than core registers. */ -extern int prefer_neon_for_64bits; - /* Structure defining the current overall architectural target and tuning. */ struct arm_build_target { diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 3343a7e..a34cb74 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -949,10 +949,6 @@ int arm_arch_thumb_hwdiv; /* Nonzero if chip disallows volatile memory access in IT block. */ int arm_arch_no_volatile_ce; -/* Nonzero if we should use Neon to handle 64-bits operations rather - than core registers. */ -int prefer_neon_for_64bits = 0; - /* Nonzero if we shouldn't use literal pools. */ bool arm_disable_literal_pool = false; @@ -1810,7 +1806,6 @@ const struct tune_params arm_slowmul_tune = tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* Thumb. */ tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* ARM. */ tune_params::DISPARAGE_FLAGS_NEITHER, - tune_params::PREF_NEON_64_FALSE, tune_params::PREF_NEON_STRINGOPS_FALSE, tune_params::FUSE_NOTHING, tune_params::SCHED_AUTOPREF_OFF @@ -1833,7 +1828,6 @@ const struct tune_params arm_fastmul_tune = tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* Thumb. */ tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* ARM. */ tune_params::DISPARAGE_FLAGS_NEITHER, - tune_params::PREF_NEON_64_FALSE, tune_params::PREF_NEON_STRINGOPS_FALSE, tune_params::FUSE_NOTHING, tune_params::SCHED_AUTOPREF_OFF @@ -1859,7 +1853,6 @@ const struct tune_params arm_strongarm_tune = tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* Thumb. */ tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* ARM. */ tune_params::DISPARAGE_FLAGS_NEITHER, - tune_params::PREF_NEON_64_FALSE, tune_params::PREF_NEON_STRINGOPS_FALSE, tune_params::FUSE_NOTHING, tune_params::SCHED_AUTOPREF_OFF @@ -1882,7 +1875,6 @@ const struct tune_params arm_xscale_tune = tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* Thumb. */ tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* ARM. */ tune_params::DISPARAGE_FLAGS_NEITHER, - tune_params::PREF_NEON_64_FALSE, tune_params::PREF_NEON_STRINGOPS_FALSE, tune_params::FUSE_NOTHING, tune_params::SCHED_AUTOPREF_OFF @@ -1905,7 +1897,6 @@ const struct tune_params arm_9e_tune = tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* Thumb. */ tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* ARM. */ tune_params::DISPARAGE_FLAGS_NEITHER, - tune_params::PREF_NEON_64_FALSE, tune_params::PREF_NEON_STRINGOPS_FALSE, tune_params::FUSE_NOTHING, tune_params::SCHED_AUTOPREF_OFF @@ -1928,7 +1919,6 @@ const struct tune_params arm_marvell_pj4_tune = tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* Thumb. */ tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* ARM. */ tune_params::DISPARAGE_FLAGS_NEITHER, - tune_params::PREF_NEON_64_FALSE, tune_params::PREF_NEON_STRINGOPS_FALSE, tune_params::FUSE_NOTHING, tune_params::SCHED_AUTOPREF_OFF @@ -1951,7 +1941,6 @@ const struct tune_params arm_v6t2_tune = tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* Thumb. */ tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* ARM. */ tune_params::DISPARAGE_FLAGS_NEITHER, - tune_params::PREF_NEON_64_FALSE, tune_params::PREF_NEON_STRINGOPS_FALSE, tune_params::FUSE_NOTHING, tune_params::SCHED_AUTOPREF_OFF @@ -1976,7 +1965,6 @@ const struct tune_params arm_cortex_tune = tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* Thumb. */ tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* ARM. */ tune_params::DISPARAGE_FLAGS_NEITHER, - tune_params::PREF_NEON_64_FALSE, tune_params::PREF_NEON_STRINGOPS_FALSE, tune_params::FUSE_NOTHING, tune_params::SCHED_AUTOPREF_OFF @@ -1999,7 +1987,6 @@ const struct tune_params arm_cortex_a8_tune = tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* Thumb. */ tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* ARM. */ tune_params::DISPARAGE_FLAGS_NEITHER, - tune_params::PREF_NEON_64_FALSE, tune_params::PREF_NEON_STRINGOPS_TRUE, tune_params::FUSE_NOTHING, tune_params::SCHED_AUTOPREF_OFF @@ -2022,7 +2009,6 @@ const struct tune_params arm_cortex_a7_tune = tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* Thumb. */ tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* ARM. */ tune_params::DISPARAGE_FLAGS_NEITHER, - tune_params::PREF_NEON_64_FALSE, tune_params::PREF_NEON_STRINGOPS_TRUE, tune_params::FUSE_NOTHING, tune_params::SCHED_AUTOPREF_OFF @@ -2045,7 +2031,6 @@ const struct tune_params arm_cortex_a15_tune = tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* Thumb. */ tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* ARM. */ tune_params::DISPARAGE_FLAGS_ALL, - tune_params::PREF_NEON_64_FALSE, tune_params::PREF_NEON_STRINGOPS_TRUE, tune_params::FUSE_NOTHING, tune_params::SCHED_AUTOPREF_FULL @@ -2068,7 +2053,6 @@ const struct tune_params arm_cortex_a35_tune = tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* Thumb. */ tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* ARM. */ tune_params::DISPARAGE_FLAGS_NEITHER, - tune_params::PREF_NEON_64_FALSE, tune_params::PREF_NEON_STRINGOPS_TRUE, FUSE_OPS (tune_params::FUSE_MOVW_MOVT), tune_params::SCHED_AUTOPREF_OFF @@ -2091,7 +2075,6 @@ const struct tune_params arm_cortex_a53_tune = tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* Thumb. */ tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* ARM. */ tune_params::DISPARAGE_FLAGS_NEITHER, - tune_params::PREF_NEON_64_FALSE, tune_params::PREF_NEON_STRINGOPS_TRUE, FUSE_OPS (tune_params::FUSE_MOVW_MOVT | tune_params::FUSE_AES_AESMC), tune_params::SCHED_AUTOPREF_OFF @@ -2114,7 +2097,6 @@ const struct tune_params arm_cortex_a57_tune = tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* Thumb. */ tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* ARM. */ tune_params::DISPARAGE_FLAGS_ALL, - tune_params::PREF_NEON_64_FALSE, tune_params::PREF_NEON_STRINGOPS_TRUE, FUSE_OPS (tune_params::FUSE_MOVW_MOVT | tune_params::FUSE_AES_AESMC), tune_params::SCHED_AUTOPREF_FULL @@ -2137,7 +2119,6 @@ const struct tune_params arm_exynosm1_tune = tune_params::LOG_OP_NON_SHORT_CIRCUIT_FALSE, /* Thumb. */ tune_params::LOG_OP_NON_SHORT_CIRCUIT_FALSE, /* ARM. */ tune_params::DISPARAGE_FLAGS_ALL, - tune_params::PREF_NEON_64_FALSE, tune_params::PREF_NEON_STRINGOPS_TRUE, tune_params::FUSE_NOTHING, tune_params::SCHED_AUTOPREF_OFF @@ -2160,7 +2141,6 @@ const struct tune_params arm_xgene1_tune = tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* Thumb. */ tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* ARM. */ tune_params::DISPARAGE_FLAGS_ALL, - tune_params::PREF_NEON_64_FALSE, tune_params::PREF_NEON_STRINGOPS_FALSE, tune_params::FUSE_NOTHING, tune_params::SCHED_AUTOPREF_OFF @@ -2186,7 +2166,6 @@ const struct tune_params arm_cortex_a5_tune = tune_params::LOG_OP_NON_SHORT_CIRCUIT_FALSE, /* Thumb. */ tune_params::LOG_OP_NON_SHORT_CIRCUIT_FALSE, /* ARM. */ tune_params::DISPARAGE_FLAGS_NEITHER, - tune_params::PREF_NEON_64_FALSE, tune_params::PREF_NEON_STRINGOPS_TRUE, tune_params::FUSE_NOTHING, tune_params::SCHED_AUTOPREF_OFF @@ -2209,7 +2188,6 @@ const struct tune_params arm_cortex_a9_tune = tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* Thumb. */ tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* ARM. */ tune_params::DISPARAGE_FLAGS_NEITHER, - tune_params::PREF_NEON_64_FALSE, tune_params::PREF_NEON_STRINGOPS_FALSE, tune_params::FUSE_NOTHING, tune_params::SCHED_AUTOPREF_OFF @@ -2232,7 +2210,6 @@ const struct tune_params arm_cortex_a12_tune = tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* Thumb. */ tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* ARM. */ tune_params::DISPARAGE_FLAGS_ALL, - tune_params::PREF_NEON_64_FALSE, tune_params::PREF_NEON_STRINGOPS_TRUE, FUSE_OPS (tune_params::FUSE_MOVW_MOVT), tune_params::SCHED_AUTOPREF_OFF @@ -2255,7 +2232,6 @@ const struct tune_params arm_cortex_a73_tune = tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* Thumb. */ tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* ARM. */ tune_params::DISPARAGE_FLAGS_ALL, - tune_params::PREF_NEON_64_FALSE, tune_params::PREF_NEON_STRINGOPS_TRUE, FUSE_OPS (tune_params::FUSE_AES_AESMC | tune_params::FUSE_MOVW_MOVT), tune_params::SCHED_AUTOPREF_FULL @@ -2285,7 +2261,6 @@ const struct tune_params arm_v7m_tune = tune_params::LOG_OP_NON_SHORT_CIRCUIT_FALSE, /* Thumb. */ tune_params::LOG_OP_NON_SHORT_CIRCUIT_FALSE, /* ARM. */ tune_params::DISPARAGE_FLAGS_NEITHER, - tune_params::PREF_NEON_64_FALSE, tune_params::PREF_NEON_STRINGOPS_FALSE, tune_params::FUSE_NOTHING, tune_params::SCHED_AUTOPREF_OFF @@ -2310,7 +2285,6 @@ const struct tune_params arm_cortex_m7_tune = tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* Thumb. */ tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* ARM. */ tune_params::DISPARAGE_FLAGS_NEITHER, - tune_params::PREF_NEON_64_FALSE, tune_params::PREF_NEON_STRINGOPS_FALSE, tune_params::FUSE_NOTHING, tune_params::SCHED_AUTOPREF_OFF @@ -2336,7 +2310,6 @@ const struct tune_params arm_v6m_tune = tune_params::LOG_OP_NON_SHORT_CIRCUIT_FALSE, /* Thumb. */ tune_params::LOG_OP_NON_SHORT_CIRCUIT_FALSE, /* ARM. */ tune_params::DISPARAGE_FLAGS_NEITHER, - tune_params::PREF_NEON_64_FALSE, tune_params::PREF_NEON_STRINGOPS_FALSE, tune_params::FUSE_NOTHING, tune_params::SCHED_AUTOPREF_OFF @@ -2359,7 +2332,6 @@ const struct tune_params arm_fa726te_tune = tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* Thumb. */ tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* ARM. */ tune_params::DISPARAGE_FLAGS_NEITHER, - tune_params::PREF_NEON_64_FALSE, tune_params::PREF_NEON_STRINGOPS_FALSE, tune_params::FUSE_NOTHING, tune_params::SCHED_AUTOPREF_OFF @@ -3568,12 +3540,6 @@ arm_option_override (void) global_options.x_param_values, global_options_set.x_param_values); - /* Use Neon to perform 64-bits operations rather than core - registers. */ - prefer_neon_for_64bits = current_tune->prefer_neon_for_64bits; - if (use_neon_for_64bits == 1) - prefer_neon_for_64bits = true; - /* Use the alternative scheduling-pressure algorithm by default. */ maybe_set_param_value (PARAM_SCHED_PRESSURE_ALGORITHM, SCHED_PRESSURE_MODEL, global_options.x_param_values, @@ -26521,9 +26487,6 @@ arm_print_tune_info (void) (int) current_tune->logical_op_non_short_circuit_thumb, (int) current_tune->logical_op_non_short_circuit_arm); asm_fprintf (asm_out_file, "\t\t" ASM_COMMENT_START - "prefer_neon_for_64bits:\t%d\n", - (int) current_tune->prefer_neon_for_64bits); - asm_fprintf (asm_out_file, "\t\t" ASM_COMMENT_START "disparage_flag_setting_t16_encodings:\t%d\n", (int) current_tune->disparage_flag_setting_t16_encodings); asm_fprintf (asm_out_file, "\t\t" ASM_COMMENT_START diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 4866e1e..8b92c83 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -313,9 +313,6 @@ emission of floating point pcs attributes. */ /* Nonzero if disallow volatile memory access in IT block. */ #define TARGET_NO_VOLATILE_CE (arm_arch_no_volatile_ce) -/* Should NEON be used for 64-bits bitops. */ -#define TARGET_PREFER_NEON_64BITS (prefer_neon_for_64bits) - /* Should constant I be slplit for OP. */ #define DONT_EARLY_SPLIT_CONSTANT(i, op) \ ((optimize >= 2) \ @@ -509,10 +506,6 @@ extern int arm_arch_thumb_hwdiv; /* Nonzero if chip disallows volatile memory access in IT block. */ extern int arm_arch_no_volatile_ce; -/* Nonzero if we should use Neon to handle 64-bits operations rather - than core registers. */ -extern int prefer_neon_for_64bits; - /* Nonzero if we shouldn't use literal pools. */ #ifndef USED_FOR_TARGET extern bool arm_disable_literal_pool; diff --git a/gcc/config/arm/arm.opt b/gcc/config/arm/arm.opt index 9067d49..5ecc5e5 100644 --- a/gcc/config/arm/arm.opt +++ b/gcc/config/arm/arm.opt @@ -276,8 +276,8 @@ Target Report Var(unaligned_access) Init(2) Save Enable unaligned word and halfword accesses to packed data. mneon-for-64bits -Target Report RejectNegative Var(use_neon_for_64bits) Init(0) -Use Neon to perform 64-bits operations rather than core registers. +Target Deprecated +This option is deprecated and has no effect. mslow-flash-data Target Report Var(target_slow_flash_data) Init(0) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 7a35684..549e043 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -18005,9 +18005,7 @@ defined. @item -mneon-for-64bits @opindex mneon-for-64bits -Enables using Neon to handle scalar 64-bits operations. This is -disabled by default since the cost of moving data from core registers -to Neon is high. +This option is deprecated and has no effect. @item -mslow-flash-data @opindex mslow-flash-data -- cgit v1.1 From 8e7803e8e11fecfae460e7076ac559f4ba35f2b5 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Fri, 23 Aug 2019 15:57:46 +0000 Subject: Warray-bounds-36.c: Make functions static to avoid failures with -fpic. gcc/testsuite/ChangeLog: * gcc.dg/Warray-bounds-36.c: Make functions static to avoid failures with -fpic. * gcc.dg/Warray-bounds-41.c: Same. From-SVN: r274859 --- gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/gcc.dg/Warray-bounds-36.c | 6 +++--- gcc/testsuite/gcc.dg/Warray-bounds-41.c | 3 +-- 3 files changed, 10 insertions(+), 5 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ad5aa69..2bd6d62 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2019-08-23 Martin Sebor + + * gcc.dg/Warray-bounds-36.c: Make functions static to avoid failures + with -fpic. + * gcc.dg/Warray-bounds-41.c: Same. + 2019-08-22 Marek Polacek PR c++/91304 - prefix attributes ignored in condition. diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-36.c b/gcc/testsuite/gcc.dg/Warray-bounds-36.c index 35b3c92..c47d781 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-36.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-36.c @@ -3,15 +3,15 @@ { dg-do compile } { dg-options "-O2 -Wall" } */ -int deref (const int *p, int i) +static int deref (const int *p, int i) { - return p[i]; // { dg-warning "array subscript \\\[3, \[0-9\]+] is outside array bounds of .int\\\[2\\\]." "ilp33" { xfail ilp32 } } + return p[i]; // { dg-warning "array subscript \\\[3, \[0-9\]+] is outside array bounds of .int\\\[2\\\]." "ilp32" { xfail ilp32 } } // There should also be an inlining context here. PR 86650 tracks // its absence. } -int deref_3_plus (const int *p, int i) +static int deref_3_plus (const int *p, int i) { if (i < 3) i = 3; diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-41.c b/gcc/testsuite/gcc.dg/Warray-bounds-41.c index 2ff3692..3b3693f 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-41.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-41.c @@ -3,7 +3,7 @@ { dg-require-effective-target alloca } { dg-options "-O2 -Wall" } */ -void* vptr (void *c) +static void* vptr (void *c) { return c; } @@ -31,4 +31,3 @@ void test_vptr_arith_vla_var (int n) char c[n]; sink (vptr (c) - 1); /* { dg-warning "\\\[-Warray-bounds" "pr82608" { xfail *-*-* } } */ } - -- cgit v1.1 From 0448240b88ceb5bb29d4872f434ddf385a30f1d2 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Fri, 23 Aug 2019 16:16:42 +0000 Subject: pr78973.c: Make functions static to avoid failures with -fpic gcc/testsuite/ChangeLog: * gcc.dg/pr78973.c: Make functions static to avoid failures with -fpic * gcc.dg/pr78973-2.c: Same. From-SVN: r274860 --- gcc/testsuite/ChangeLog | 2 ++ gcc/testsuite/gcc.dg/pr78973-2.c | 2 +- gcc/testsuite/gcc.dg/pr78973.c | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2bd6d62..887496e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -3,6 +3,8 @@ * gcc.dg/Warray-bounds-36.c: Make functions static to avoid failures with -fpic. * gcc.dg/Warray-bounds-41.c: Same. + * gcc.dg/pr78973.c: Same. + * gcc.dg/pr78973-2.c: Same. 2019-08-22 Marek Polacek diff --git a/gcc/testsuite/gcc.dg/pr78973-2.c b/gcc/testsuite/gcc.dg/pr78973-2.c index 7cf9a9e..ad29209 100644 --- a/gcc/testsuite/gcc.dg/pr78973-2.c +++ b/gcc/testsuite/gcc.dg/pr78973-2.c @@ -10,7 +10,7 @@ void *p; -void f (int n) +static void f (int n) { if (n <= 4) p = __builtin_malloc (n); diff --git a/gcc/testsuite/gcc.dg/pr78973.c b/gcc/testsuite/gcc.dg/pr78973.c index 6c53f89..d0ecba4 100644 --- a/gcc/testsuite/gcc.dg/pr78973.c +++ b/gcc/testsuite/gcc.dg/pr78973.c @@ -6,7 +6,7 @@ { dg-do compile } { dg-options "-O2 -Wall" } */ -void f (void *p, int n) +static void f (void *p, int n) { if (n <= 4) __builtin_memset (p, 0, n); /* { dg-warning "exceeds maximum object size" "pr79073" { xfail ilp32 } } */ -- cgit v1.1 From 7d35d2bf5a15e38122083ddd198d1d20548d0ffa Mon Sep 17 00:00:00 2001 From: Mihailo Stojanovic Date: Fri, 23 Aug 2019 19:04:56 +0000 Subject: mips.md (mips_get_fcsr, [...]): Use SI machine mode for unspec_volatile operand. * config/mips/mips.md (mips_get_fcsr, *mips_get_fcsr): Use SI machine mode for unspec_volatile operand. * gcc.target/mips/get-fcsr-3.c: New test. From-SVN: r274863 --- gcc/ChangeLog | 5 +++++ gcc/config/mips/mips.md | 4 ++-- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.target/mips/get-fcsr-3.c | 9 +++++++++ 4 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/mips/get-fcsr-3.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3fbdb93..989dff7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-08-23 Mihailo Stojanovic + + * config/mips/mips.md (mips_get_fcsr, *mips_get_fcsr): Use SI + machine mode for unspec_volatile operand. + 2019-08-23 Wilco Dijkstra * gcc/doc/invoke.texi (mneon-for-64bits): Deprecate option. diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index e17b1d5..4ad5c62 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -7588,7 +7588,7 @@ ;; __builtin_mips_get_fcsr: move the FCSR into operand 0. (define_expand "mips_get_fcsr" [(set (match_operand:SI 0 "register_operand") - (unspec_volatile [(const_int 0)] UNSPEC_GET_FCSR))] + (unspec_volatile:SI [(const_int 0)] UNSPEC_GET_FCSR))] "TARGET_HARD_FLOAT_ABI" { if (TARGET_MIPS16) @@ -7600,7 +7600,7 @@ (define_insn "*mips_get_fcsr" [(set (match_operand:SI 0 "register_operand" "=d") - (unspec_volatile [(const_int 0)] UNSPEC_GET_FCSR))] + (unspec_volatile:SI [(const_int 0)] UNSPEC_GET_FCSR))] "TARGET_HARD_FLOAT" "cfc1\t%0,$31") diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 887496e..92e6da2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-08-23 Mihailo Stojanovic + + * gcc.target/mips/get-fcsr-3.c: New test. + 2019-08-23 Martin Sebor * gcc.dg/Warray-bounds-36.c: Make functions static to avoid failures diff --git a/gcc/testsuite/gcc.target/mips/get-fcsr-3.c b/gcc/testsuite/gcc.target/mips/get-fcsr-3.c new file mode 100644 index 0000000..7bb97b6 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/get-fcsr-3.c @@ -0,0 +1,9 @@ +/* { dg-options "-mabi=64 -mhard-float" } */ + +NOMIPS16 unsigned int +foo (void) +{ + return __builtin_mips_get_fcsr () & 0x1; +} + +/* { dg-final { scan-assembler "cfc1" } } */ -- cgit v1.1 From 5f9f1ffebe2a3c86d2835118e28714d4a8c878c9 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Fri, 23 Aug 2019 19:26:04 +0000 Subject: [C++ PATCH] vfunc overrider simplification https://gcc.gnu.org/ml/gcc-patches/2019-08/msg01674.html * class.c (check_for_override): Checking IDENTIFIER_VIRTUAL_P is sufficient, reorder DECL_OVERRIDE_P check. From-SVN: r274867 --- gcc/cp/ChangeLog | 5 +++++ gcc/cp/class.c | 35 +++++++++++++++++++++-------------- 2 files changed, 26 insertions(+), 14 deletions(-) (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f014423..c416082 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2019-08-23 Nathan Sidwell + + * class.c (check_for_override): Checking IDENTIFIER_VIRTUAL_P is + sufficient, reorder DECL_OVERRIDE_P check. + 2019-08-23 Iain Sandoe PR pch/61250 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index cc53b15..99332f4 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -2802,31 +2802,34 @@ get_basefndecls (tree name, tree t, vec *base_fndecls) } } -/* If this declaration supersedes the declaration of - a method declared virtual in the base class, then - mark this field as being virtual as well. */ +/* If this method overrides a virtual method from a base, then mark + this member function as being virtual as well. Do 'final' and + 'override' checks too. */ void check_for_override (tree decl, tree ctype) { - bool overrides_found = false; if (TREE_CODE (decl) == TEMPLATE_DECL) /* In [temp.mem] we have: A specialization of a member function template does not override a virtual function from a base class. */ return; - if ((DECL_DESTRUCTOR_P (decl) - || IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) - || DECL_CONV_FN_P (decl)) + + /* IDENTIFIER_VIRTUAL_P indicates whether the name has ever been + used for a vfunc. That avoids the expensive + look_for_overrides call that when we know there's nothing to + find. */ + if (IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) && look_for_overrides (ctype, decl) + /* Check staticness after we've checked if we 'override'. */ && !DECL_STATIC_FUNCTION_P (decl)) - /* Set DECL_VINDEX to a value that is neither an INTEGER_CST nor - the error_mark_node so that we know it is an overriding - function. */ { + /* Set DECL_VINDEX to a value that is neither an INTEGER_CST nor + the error_mark_node so that we know it is an overriding + function. */ DECL_VINDEX (decl) = decl; - overrides_found = true; + if (warn_override && !DECL_OVERRIDE_P (decl) && !DECL_FINAL_P (decl) @@ -2834,19 +2837,23 @@ check_for_override (tree decl, tree ctype) warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wsuggest_override, "%qD can be marked override", decl); } + else if (DECL_OVERRIDE_P (decl)) + error ("%q+#D marked %, but does not override", decl); if (DECL_VIRTUAL_P (decl)) { + /* Remember this identifier is virtual name. */ + IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = true; + if (!DECL_VINDEX (decl)) + /* It's a new vfunc. */ DECL_VINDEX (decl) = error_mark_node; - IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1; + if (DECL_DESTRUCTOR_P (decl)) TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype) = true; } else if (DECL_FINAL_P (decl)) error ("%q+#D marked %, but is not virtual", decl); - if (DECL_OVERRIDE_P (decl) && !overrides_found) - error ("%q+#D marked %, but does not override", decl); } /* Warn about hidden virtual functions that are not overridden in t. -- cgit v1.1 From a0fae476721ccc4072d1289106b01ace17d2a2b0 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Fri, 23 Aug 2019 20:47:30 +0100 Subject: * zh_CN.po: Update. From-SVN: r274868 --- gcc/po/ChangeLog | 4 + gcc/po/zh_CN.po | 305 +++++++++++++++++++------------------------------------ 2 files changed, 107 insertions(+), 202 deletions(-) (limited to 'gcc') diff --git a/gcc/po/ChangeLog b/gcc/po/ChangeLog index c904eeb..ac90b05 100644 --- a/gcc/po/ChangeLog +++ b/gcc/po/ChangeLog @@ -1,3 +1,7 @@ +2019-08-23 Joseph Myers + + * zh_CN.po: Update. + 2019-08-09 Joseph Myers * uk.po: Update. diff --git a/gcc/po/zh_CN.po b/gcc/po/zh_CN.po index 5701d2a..f18c00a 100644 --- a/gcc/po/zh_CN.po +++ b/gcc/po/zh_CN.po @@ -4,6 +4,7 @@ # Meng Jie , 2005-2014. # Jeff Bai , 2015. # Mingye Wang (Arthur2e5) , 2015, 2016. +# Boyuan Yang <073plan@gmail.com>, 2019. # # Fellow translatiors: # Many of the fuzzy strings are caused by an addition of a period (".") @@ -30,20 +31,19 @@ # msgid "" msgstr "" -"Project-Id-Version: gcc 6.1.0\n" +"Project-Id-Version: gcc 9.1.0\n" "Report-Msgid-Bugs-To: https://gcc.gnu.org/bugs/\n" "POT-Creation-Date: 2019-05-02 20:28+0000\n" -"PO-Revision-Date: 2016-04-30 17:13-0400\n" -"Last-Translator: Mingye Wang (Arthur2e5) \n" +"PO-Revision-Date: 2019-08-19 15:13-0400\n" +"Last-Translator: Boyuan Yang <073plan@gmail.com>\n" "Language-Team: Chinese (simplified) \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Bugs: Report translation errors to the Language-Team address.\n" -"X-Poedit-Basepath: C:/MSYS/source/gcc-4.6.0/gcc\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Poedit 1.8.7\n" +"X-Generator: Poedit 2.2.3\n" #: cfgrtl.c:2705 msgid "flow control insn inside a basic block" @@ -478,12 +478,10 @@ msgid " -o Place the output into .\n" msgstr " -o <文件> 输出到 <文件>。\n" #: gcc.c:3597 -#, fuzzy -#| msgid " -pie Create a position independent executable.\n" msgid "" " -pie Create a dynamically linked position independent\n" " executable.\n" -msgstr " -pie 生成位置无关可执行文件。\n" +msgstr " -pie 生成动态链接的位置无关可执行文件。\n" #: gcc.c:3599 msgid " -shared Create a shared library.\n" @@ -668,10 +666,9 @@ msgid " rewrite [options] Rewrite coverage file contents\n" msgstr " rewrite [选项] <目录> 覆写测试覆盖率文件内容\n" #: gcov-tool.c:270 -#, fuzzy, c-format -#| msgid " -n, --normalize Normalize the profile\n" +#, c-format msgid " -n, --normalize Normalize the profile\n" -msgstr " -n, --normalize 归一化配置\n" +msgstr " -n, --normalize 归一化配置\n" #: gcov-tool.c:272 #, c-format @@ -774,10 +771,9 @@ msgstr "" "%s。\n" #: gcov-tool.c:528 -#, fuzzy, c-format -#| msgid "Copyright %s 2014-2016 Free Software Foundation, Inc.\n" +#, c-format msgid "Copyright %s 2019 Free Software Foundation, Inc.\n" -msgstr "版权所有 %s 2014-2015 自由软件基金会。\n" +msgstr "版权所有 %s 2019 自由软件基金会。\n" #: gcov-tool.c:531 gcov.c:925 #, c-format @@ -791,15 +787,12 @@ msgstr "" "包括没有适销性和某一专用目的下的适用性担保。\n" #: gcov.c:885 -#, fuzzy, c-format -#| msgid "" -#| "Usage: gcov [OPTION]... SOURCE|OBJ...\n" -#| "\n" +#, c-format msgid "" "Usage: gcov [OPTION...] SOURCE|OBJ...\n" "\n" msgstr "" -"用法:gconv [选项]... 源文件|对象文件...\n" +"用法:gconv [选项...] 源文件|对象文件...\n" "\n" #: gcov.c:886 @@ -844,22 +837,19 @@ msgid " -h, --help Print this help, then exit\n" msgstr " -h, --help 打印此帮助并退出\n" #: gcov.c:894 -#, fuzzy, c-format -#| msgid " -n, --no-output Do not create an output file\n" +#, c-format msgid " -i, --json-format Output JSON intermediate format into .gcov.json.gz file\n" -msgstr " -n, --no-output 不创建输出文件\n" +msgstr " -i, --json-format 以 JSON 中间格式输出至 .gcov.json.gz 文件\n" #: gcov.c:895 -#, fuzzy, c-format -#| msgid " -m, --demangled-names Output demangled function names\n" +#, c-format msgid " -j, --human-readable Output human readable numbers\n" -msgstr " -m, --demangled-names 输出解码后的函数名\n" +msgstr " -j, --human-readable 输出人类可读的数字\n" #: gcov.c:896 -#, fuzzy, c-format -#| msgid " -n, --no-output Do not create an output file\n" +#, c-format msgid " -k, --use-colors Emit colored output\n" -msgstr " -n, --no-output 不创建输出文件\n" +msgstr " -k, --use-colors 使用带颜色的输出\n" #: gcov.c:897 #, c-format @@ -904,10 +894,9 @@ msgid " -s, --source-prefix DIR Source prefix to elide\n" msgstr " -s, --source-prefix 目录 要略去的来源前缀\n" #: gcov.c:906 -#, fuzzy, c-format -#| msgid " -n, --no-output Do not create an output file\n" +#, c-format msgid " -t, --stdout Output to stdout instead of a file\n" -msgstr " -n, --no-output 不创建输出文件\n" +msgstr " -t, --stdout 输出至标准输出而非文件\n" #: gcov.c:907 #, c-format @@ -920,10 +909,9 @@ msgid " -v, --version Print version number, then exit\n" msgstr " -v, --version 打印版本号并退出\n" #: gcov.c:909 -#, fuzzy, c-format -#| msgid " -v, --verbose Verbose mode\n" +#, c-format msgid " -w, --verbose Print verbose informations\n" -msgstr " -v, --verbo se 输出更多信息\n" +msgstr " -w, --verbose 输出详细信息\n" #: gcov.c:910 #, fuzzy, c-format @@ -937,10 +925,9 @@ msgid "gcov %s%s\n" msgstr "gcov %s%s\n" #: gcov.c:1250 -#, fuzzy, c-format -#| msgid "Treat the input file as already preprocessed" +#, c-format msgid "'%s' file is already processed\n" -msgstr "将输入文件当作已经预处理过的" +msgstr "" #: gcov.c:1364 #, c-format @@ -968,16 +955,14 @@ msgid "\n" msgstr "\n" #: gcov.c:1489 -#, fuzzy, c-format -#| msgid "%s: Cannot open output file: %s\n" +#, c-format msgid "Cannot open JSON output file %s\n" -msgstr "%s:无法打开输出文件:%s\n" +msgstr "无法打开 JSON 输出文件 %s\n" #: gcov.c:1497 -#, fuzzy, c-format -#| msgid "Error writing output file '%s'\n" +#, c-format msgid "Error writing JSON output file %s\n" -msgstr "写入到输出文件 '%s' 时出错\n" +msgstr "写入到 JSON 输出文件 %s 时出错\n" #: gcov.c:1664 #, c-format @@ -3473,8 +3458,9 @@ msgid "unknown move insn:" msgstr "无效的 move 指令:" #: config/avr/avr.c:6279 +#, fuzzy msgid "bad shift insn:" -msgstr "错误的 shift 指令" +msgstr "错误的 shift 指令:" #: config/avr/avr.c:6387 config/avr/avr.c:6868 config/avr/avr.c:7283 msgid "internal compiler error. Incorrect shift:" @@ -4204,10 +4190,9 @@ msgid "invalid %%q value" msgstr "无效 %%q 值" #: config/rs6000/rs6000.c:21141 -#, fuzzy, c-format -#| msgid "invalid %%J value" +#, c-format msgid "invalid %%t value" -msgstr "无效 %%J 值" +msgstr "无效 %%t 值" #: config/rs6000/rs6000.c:21158 #, c-format @@ -4225,21 +4210,19 @@ msgid "invalid %%v value" msgstr "无效 %%v 值" #: config/rs6000/rs6000.c:21234 -#, fuzzy, c-format -#| msgid "invalid %%J value" +#, c-format msgid "invalid %%V value" -msgstr "无效 %%J 值" +msgstr "无效 %%V 值" #: config/rs6000/rs6000.c:21251 config/xtensa/xtensa.c:2439 #, c-format msgid "invalid %%x value" -msgstr "无效的 %%x 值" +msgstr "无效 %%x 值" #: config/rs6000/rs6000.c:21308 -#, fuzzy, c-format -#| msgid "invalid %%J value" +#, c-format msgid "invalid %%z value" -msgstr "无效 %%J 值" +msgstr "无效 %%z 值" #: config/rs6000/rs6000.c:21377 #, c-format @@ -4626,7 +4609,7 @@ msgstr "或称" #: c/c-objc-common.c:213 msgid "({anonymous})" -msgstr "{{匿名}}" +msgstr "({匿名})" #. If we have #. declaration-specifiers declarator decl-specs @@ -4884,7 +4867,7 @@ msgstr "vtable for " #: cp/error.c:1186 msgid " " -msgstr "<返回值>" +msgstr "<返回值> " #: cp/error.c:1201 msgid "{anonymous}" @@ -5196,9 +5179,8 @@ msgid "arguments '%s' and '%s' for intrinsic '%s'" msgstr "‘%s’和‘%s’用作内建函数‘%s’的参数" #: fortran/error.c:853 -#, fuzzy msgid "Fortran 2018 deleted feature:" -msgstr "遵循 ISO Fortran 2008 标准" +msgstr "Fortran 2018 删除的特性:" #: fortran/error.c:855 #, fuzzy @@ -5207,7 +5189,7 @@ msgstr "遵循 ISO Fortran 2008 标准" #: fortran/error.c:857 msgid "Fortran 2018:" -msgstr "" +msgstr "Fortran 2018:" #: fortran/error.c:859 #, fuzzy @@ -5215,9 +5197,8 @@ msgid "Fortran 2008 obsolescent feature:" msgstr "遵循 ISO Fortran 2008 标准" #: fortran/error.c:865 -#, fuzzy msgid "GNU Extension:" -msgstr "使用 PE 格式的 GNU 扩展来对齐 common 数据" +msgstr "GNU 扩展:" #: fortran/error.c:867 #, fuzzy @@ -5230,9 +5211,8 @@ msgid "Obsolescent feature:" msgstr "对声明中的过时用法给出警告" #: fortran/error.c:871 -#, fuzzy msgid "Deleted feature:" -msgstr "%L处的 H 格式限定符已在 Fortran 95 中被删除" +msgstr "删除的特性:" #: fortran/expr.c:3632 msgid "array assignment" @@ -5919,10 +5899,8 @@ msgid "gsplit-dwarf is not supported on this platform" msgstr "%qE属性在此平台上不受支持" #: config/darwin.h:170 -#, fuzzy -#| msgid "-fpic is not supported" msgid "rdynamic is not supported" -msgstr "不支持 -fpic" +msgstr "不支持 rdynamic" #: config/darwin.h:258 msgid "-current_version only allowed with -dynamiclib" @@ -6307,16 +6285,12 @@ msgid "Warn about zero-trip DO loops." msgstr "对长度为 0 的格式字符串给出警告" #: fortran/lang.opt:354 -#, fuzzy -#| msgid "Enable preprocessing" msgid "Enable preprocessing." -msgstr "启用预处理" +msgstr "启用预处理。" #: fortran/lang.opt:362 -#, fuzzy -#| msgid "Disable preprocessing" msgid "Disable preprocessing." -msgstr "禁用预处理" +msgstr "禁用预处理。" #: fortran/lang.opt:370 #, fuzzy @@ -6922,10 +6896,8 @@ msgid "Do not generate #line directives." msgstr "不生成 #line 指令" #: c-family/c.opt:257 -#, fuzzy -#| msgid "-U\tUndefine " msgid "-U\tUndefine ." -msgstr "-U<宏>\t取消定义宏" +msgstr "-U<宏>\t取消定义<宏>。" #: c-family/c.opt:261 #, fuzzy @@ -7116,10 +7088,8 @@ msgid "Warn about possibly nested block comments, and C++ comments spanning more msgstr "对可能嵌套的注释和长度超过一个物理行长的 C++ 注释给出警告" #: c-family/c.opt:437 -#, fuzzy -#| msgid "Synonym for -Wcomment" msgid "Synonym for -Wcomment." -msgstr "-Wcomment 的同义词" +msgstr "-Wcomment 的同义词。" #: c-family/c.opt:441 #, fuzzy @@ -8054,16 +8024,12 @@ msgstr "可变参数函数必须使用基础的 AAPCS 变种" #: c-family/c.opt:1282 c-family/c.opt:1530 c-family/c.opt:1854 #: c-family/c.opt:1858 c-family/c.opt:1874 -#, fuzzy -#| msgid "No longer supported" msgid "No longer supported." -msgstr "不再受支持" +msgstr "不再支持。" #: c-family/c.opt:1286 -#, fuzzy -#| msgid "Recognize the \"asm\" keyword" msgid "Recognize the \"asm\" keyword." -msgstr "识别“asm”关键字" +msgstr "识别“asm”关键字。" #: c-family/c.opt:1294 #, fuzzy @@ -8197,10 +8163,8 @@ msgid "Do not assume that standard C libraries and \"main\" exist." msgstr "不假定标准 C 库和“main”存在" #: c-family/c.opt:1505 -#, fuzzy -#| msgid "Recognize GNU-defined keywords" msgid "Recognize GNU-defined keywords." -msgstr "识别 GNU 定义的关键字" +msgstr "识别 GNU 定义的关键字。" #: c-family/c.opt:1509 #, fuzzy @@ -8495,10 +8459,8 @@ msgid "When \"signed\" or \"unsigned\" is not given make the bitfield unsigned." msgstr "未指定“signed”或“unsigned”时默认位段为无符号的" #: c-family/c.opt:1834 ada/gcc-interface/lang.opt:85 -#, fuzzy -#| msgid "Make \"char\" unsigned by default" msgid "Make \"char\" unsigned by default." -msgstr "使“char”类型默认为无符号" +msgstr "使“char”类型默认为无符号。" #: c-family/c.opt:1838 #, fuzzy @@ -8759,14 +8721,12 @@ msgid "Conform to the ISO 2011 C++ standard with GNU extensions." msgstr "遵循 ISO 1990 C 标准,也支持 GNU 扩展" #: c-family/c.opt:2059 -#, fuzzy msgid "Deprecated in favor of -std=gnu++11." -msgstr "已弃用,请改用 -std=gnu99" +msgstr "已弃用,请改用 -std=gnu++11。" #: c-family/c.opt:2063 -#, fuzzy msgid "Deprecated in favor of -std=gnu++14." -msgstr "已弃用,请改用 -std=gnu99" +msgstr "已弃用,请改用 -std=gnu++14。" #: c-family/c.opt:2067 #, fuzzy @@ -8775,9 +8735,8 @@ msgid "Conform to the ISO 2014 C++ standard with GNU extensions." msgstr "遵循 ISO 1990 C 标准,也支持 GNU 扩展" #: c-family/c.opt:2071 -#, fuzzy msgid "Deprecated in favor of -std=gnu++17." -msgstr "已弃用,请改用 -std=gnu99" +msgstr "已弃用,请改用 -std=gnu+17。" #: c-family/c.opt:2075 #, fuzzy @@ -8798,9 +8757,8 @@ msgid "Conform to the ISO 2011 C standard with GNU extensions." msgstr "遵循 ISO 1990 C 标准,也支持 GNU 扩展" #: c-family/c.opt:2087 -#, fuzzy msgid "Deprecated in favor of -std=gnu11." -msgstr "已弃用,请改用 -std=gnu99" +msgstr "已弃用,请改用 -std=gnu11。" #: c-family/c.opt:2091 c-family/c.opt:2095 #, fuzzy @@ -8845,16 +8803,12 @@ msgid "Deprecated in favor of -std=iso9899:1999." msgstr "已弃用,为 -std=iso9899:1999 所取代" #: c-family/c.opt:2150 -#, fuzzy -#| msgid "Enable traditional preprocessing" msgid "Enable traditional preprocessing." -msgstr "启用传统预处理" +msgstr "启用传统预处理。" #: c-family/c.opt:2154 -#, fuzzy -#| msgid "-trigraphs\tSupport ISO C trigraphs" msgid "-trigraphs\tSupport ISO C trigraphs." -msgstr "-trigraphs\t支持 ISO C 三元符" +msgstr "-trigraphs\t支持 ISO C 三元符。" #: c-family/c.opt:2158 #, fuzzy @@ -9004,7 +8958,7 @@ msgstr "解析后显示代码树" #: d/lang.opt:242 msgid "Ignore unsupported pragmas." -msgstr "" +msgstr "忽略不支持的 pragma。" #: d/lang.opt:246 #, fuzzy @@ -9272,7 +9226,7 @@ msgstr "总认为位段长与 int 相同" #: config/linux-android.opt:23 msgid "Generate code for the Android platform." -msgstr "为 Android 操作系统生成代码。" +msgstr "为 Android 平台生成代码。" #: config/mmix/mmix.opt:24 #, fuzzy @@ -9700,10 +9654,8 @@ msgid "Generate code for a ColdFire v4e." msgstr "为 ColdFire v4e 生成代码" #: config/m68k/m68k.opt:123 -#, fuzzy -#| msgid "Specify the target CPU" msgid "Specify the target CPU." -msgstr "选择目标 CPU" +msgstr "指定目标 CPU。" #: config/m68k/m68k.opt:127 #, fuzzy @@ -11831,10 +11783,8 @@ msgid "Set the max size of data eligible for the TDA area." msgstr "为 TDA 区域合格的数据设置最大尺寸" #: config/v850/v850.opt:82 -#, fuzzy -#| msgid "Do not enforce strict alignment" msgid "Do not enforce strict alignment." -msgstr "不强制严格对齐" +msgstr "不强制严格对齐。" #: config/v850/v850.opt:86 #, fuzzy @@ -11842,22 +11792,16 @@ msgid "Put jump tables for switch statements into the .data section rather than msgstr "置放跳跃式表格用于开关叙述进入.data 区段而非.code 区段" #: config/v850/v850.opt:93 -#, fuzzy -#| msgid "Compile for the v850 processor" msgid "Compile for the v850 processor." -msgstr "为 v850 处理器编译" +msgstr "为 v850 处理器编译。" #: config/v850/v850.opt:97 -#, fuzzy -#| msgid "Compile for the v850e processor" msgid "Compile for the v850e processor." -msgstr "为 v850e 处理器编译" +msgstr "为 v850e 处理器编译。" #: config/v850/v850.opt:101 -#, fuzzy -#| msgid "Compile for the v850e1 processor" msgid "Compile for the v850e1 processor." -msgstr "为 v850e1 处理器编译" +msgstr "为 v850e1 处理器编译。" #: config/v850/v850.opt:105 #, fuzzy @@ -11866,21 +11810,16 @@ msgid "Compile for the v850es variant of the v850e1." msgstr "为 v850e1 的 v850es 变种编译" #: config/v850/v850.opt:109 -#, fuzzy -#| msgid "Compile for the v850e2 processor" msgid "Compile for the v850e2 processor." -msgstr "为 v850e2 处理器编译" +msgstr "为 v850e2 处理器编译。" #: config/v850/v850.opt:113 -#, fuzzy -#| msgid "Compile for the v850e2v3 processor" msgid "Compile for the v850e2v3 processor." -msgstr "为 v850e2v3 处理器编译" +msgstr "为 v850e2v3 处理器编译。" #: config/v850/v850.opt:117 -#, fuzzy msgid "Compile for the v850e3v5 processor." -msgstr "为 v850e2v3 处理器编译" +msgstr "为 v850e2v3 处理器编译。" #: config/v850/v850.opt:124 #, fuzzy @@ -11919,9 +11858,8 @@ msgid "Enable support for the RH850 ABI. This is the default." msgstr "启用使用 RX FPU 指令。这是默认值。" #: config/v850/v850.opt:155 -#, fuzzy msgid "Enable support for the old GCC ABI." -msgstr "启用对巨型对象的支持" +msgstr "启用对旧有 GCC ABI 的支持。" #: config/v850/v850.opt:159 msgid "Support alignments of up to 64-bits." @@ -11940,26 +11878,20 @@ msgid "Support legacy multi-threading." msgstr "支持传统多线程" #: config/lynx.opt:27 -#, fuzzy -#| msgid "Use shared libraries" msgid "Use shared libraries." -msgstr "使用共享库" +msgstr "使用共享库。" #: config/lynx.opt:31 -#, fuzzy -#| msgid "Support multi-threading" msgid "Support multi-threading." -msgstr "支持多线程" +msgstr "支持多线程。" #: config/nvptx/nvptx.opt:22 config/gcn/gcn.opt:47 -#, fuzzy msgid "Generate code for a 32-bit ABI." -msgstr "生成 32 位 SHmedia 代码" +msgstr "为 32 位 ABI 生成代码。" #: config/nvptx/nvptx.opt:26 config/gcn/gcn.opt:51 -#, fuzzy msgid "Generate code for a 64-bit ABI." -msgstr "生成 64 位代码" +msgstr "为 64 位 ABI 生成代码。" #: config/nvptx/nvptx.opt:30 #, fuzzy @@ -12034,9 +11966,8 @@ msgid "Treat data references as near, far or medium. medium is default." msgstr "对待数据参考作为接近,far 或中。中是缺省" #: config/cr16/cr16.opt:42 -#, fuzzy msgid "Generate code for CR16C architecture." -msgstr "为 Android 操作系统生成代码。" +msgstr "为 CR16C 架构生成代码。" #: config/cr16/cr16.opt:46 #, fuzzy @@ -12157,22 +12088,16 @@ msgid "Do not link against the device-specific library lib.a." msgstr "" #: config/m32r/m32r.opt:34 -#, fuzzy -#| msgid "Compile for the m32rx" msgid "Compile for the m32rx." -msgstr "为 m32rx 编译" +msgstr "为 m32rx 编译。" #: config/m32r/m32r.opt:38 -#, fuzzy -#| msgid "Compile for the m32r2" msgid "Compile for the m32r2." -msgstr "为 m32r2 编译" +msgstr "为 m32r2 编译。" #: config/m32r/m32r.opt:42 -#, fuzzy -#| msgid "Compile for the m32r" msgid "Compile for the m32r." -msgstr "为 m32r 编译" +msgstr "为 m32r 编译。" #: config/m32r/m32r.opt:46 #, fuzzy @@ -12259,16 +12184,12 @@ msgid "Specify main object for TPF-OS." msgstr "指定 TPF-OS 的主对象" #: config/s390/s390.opt:48 -#, fuzzy -#| msgid "31 bit ABI" msgid "31 bit ABI." -msgstr "31 位 ABI" +msgstr "31 位 ABI。" #: config/s390/s390.opt:52 -#, fuzzy -#| msgid "64 bit ABI" msgid "64 bit ABI." -msgstr "64 位 ABI" +msgstr "64 位 ABI。" #: config/s390/s390.opt:120 #, fuzzy @@ -12284,9 +12205,8 @@ msgstr "附加的调试输出" #: config/s390/s390.opt:128 #, fuzzy -#| msgid "ESA/390 architecture" msgid "ESA/390 architecture." -msgstr "ESA/390 结构" +msgstr "ESA/390 结构。" #: config/s390/s390.opt:132 #, fuzzy @@ -12739,9 +12659,8 @@ msgstr "生成使用硬件浮点指令的代码" #: config/sparc/sparc.opt:30 config/sparc/sparc.opt:34 #: config/visium/visium.opt:37 #, fuzzy -#| msgid "Use hardware FP" msgid "Use hardware FP." -msgstr "使用硬件浮点单元" +msgstr "使用硬件浮点单元。" #: config/sparc/sparc.opt:38 config/visium/visium.opt:41 #, fuzzy @@ -12785,10 +12704,8 @@ msgid "Enable Local Register Allocation." msgstr "启用 clip 指令" #: config/sparc/sparc.opt:66 -#, fuzzy -#| msgid "Compile for V8+ ABI" msgid "Compile for V8+ ABI." -msgstr "为 V8+ ABI 编译" +msgstr "为 V8+ ABI 编译。" #: config/sparc/sparc.opt:70 #, fuzzy @@ -12851,16 +12768,12 @@ msgid "Pointers are 32-bit." msgstr "指针是 32 位" #: config/sparc/sparc.opt:118 -#, fuzzy -#| msgid "Use 64-bit ABI" msgid "Use 64-bit ABI." -msgstr "使用 64 位 ABI" +msgstr "使用 64 位 ABI。" #: config/sparc/sparc.opt:122 -#, fuzzy -#| msgid "Use 32-bit ABI" msgid "Use 32-bit ABI." -msgstr "使用 32 位 ABI" +msgstr "使用 32 位 ABI。" #: config/sparc/sparc.opt:126 #, fuzzy @@ -12967,10 +12880,8 @@ msgid "Compile for 32-bit pointers." msgstr "为 32 位指针编译" #: config/rs6000/aix64.opt:32 config/rs6000/linux64.opt:28 -#, fuzzy -#| msgid "Select code model" msgid "Select code model." -msgstr "选择代码模型" +msgstr "选择代码模型。" #: config/rs6000/aix64.opt:49 #, fuzzy @@ -13033,10 +12944,8 @@ msgid "Use extended PowerPC V2.05 move floating point to/from GPR instructions." msgstr "使用扩展 PowerPC V2.05 通用寄存器浮点转移指令" #: config/rs6000/rs6000.opt:153 -#, fuzzy -#| msgid "Use AltiVec instructions" msgid "Use AltiVec instructions." -msgstr "使用 AltiVec 指令" +msgstr "使用 AltiVec 指令。" #: config/rs6000/rs6000.opt:157 #, fuzzy @@ -13242,16 +13151,12 @@ msgid "Do not use the AltiVec ABI extensions." msgstr "不使用位段指令" #: config/rs6000/rs6000.opt:358 -#, fuzzy -#| msgid "Use the ELFv1 ABI" msgid "Use the ELFv1 ABI." -msgstr "使用 ELFv1 ABI" +msgstr "使用 ELFv1 ABI。" #: config/rs6000/rs6000.opt:362 -#, fuzzy -#| msgid "Use the ELFv2 ABI" msgid "Use the ELFv2 ABI." -msgstr "使用 ELFv2 ABI" +msgstr "使用 ELFv2 ABI。" #: config/rs6000/rs6000.opt:382 #, fuzzy @@ -13477,10 +13382,8 @@ msgid "Assume all variable arg functions are prototyped." msgstr "假设所有可变参数函数都有原型" #: config/rs6000/sysv4.opt:103 -#, fuzzy -#| msgid "Use EABI" msgid "Use EABI." -msgstr "使用 EABI" +msgstr "使用 EABI。" #: config/rs6000/sysv4.opt:107 #, fuzzy @@ -13776,10 +13679,8 @@ msgid "Use divide emulation." msgstr "使用除法指令" #: config/or1k/or1k.opt:67 -#, fuzzy -#| msgid "Use the soft multiply emulation (default)" msgid "Use multiply emulation." -msgstr "使用软件模拟乘法(默认)" +msgstr "使用乘法模拟。" #: config/nios2/elf.opt:26 #, fuzzy @@ -66815,14 +66716,14 @@ msgid "Include directory %qs: %s" msgstr "不包含子目录注释" #: fortran/scanner.c:336 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "Nonexistent include directory %qs" -msgstr "忽略不存在的目录“%s”\n" +msgstr "不存在的 include 目录 %qs" #: fortran/scanner.c:341 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "%qs is not a directory" -msgstr "不是目录" +msgstr "%qs 不是目录" #: fortran/scanner.c:744 #, fuzzy, gcc-internal-format, gfc-internal-format @@ -66893,9 +66794,9 @@ msgid "Illegal preprocessor directive" msgstr "%s:%d:无效的预处理指令" #: fortran/scanner.c:2471 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "Cannot open file %qs" -msgstr "无法打开文件 %s\n" +msgstr "无法打开文件 %qs" #: fortran/simplify.c:92 #, gcc-internal-format, gfc-internal-format @@ -69343,9 +69244,9 @@ msgid "%<-mfused-madd%> is deprecated; use %<-ffp-contract=%> instead" msgstr "已弃用%<-mfused-madd%>;请改用%<-ffp-contract=%>" #: config/microblaze/microblaze.opt:87 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "%qs is deprecated; use -fstack-check" -msgstr "已弃用%qE:%s" +msgstr "%qs 已弃用;请换用 -fstack-check" #: config/microblaze/microblaze.opt:95 #, gcc-internal-format @@ -69356,9 +69257,9 @@ msgstr "%qs 已弃用;请换用 -fno-zero-initialized-in-bss" #: config/arc/arc.opt:349 config/arc/arc.opt:353 config/arc/arc.opt:357 #: config/arc/arc.opt:361 config/arc/arc.opt:364 config/arc/arc.opt:367 #: config/arc/arc.opt:384 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "%qs is deprecated" -msgstr "已弃用%qE" +msgstr "%qs 已弃用" #: lto/lang.opt:28 #, fuzzy, gcc-internal-format @@ -69392,9 +69293,9 @@ msgid "unknown Control-Flow Protection Level %qs" msgstr "未知的栈重用级别%qs" #: common.opt:1777 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "unknown IRA algorithm %qs" -msgstr "未知的 TLS 模型%qs" +msgstr "未知的 IRA 算法 %qs" #: common.opt:1790 #, fuzzy, gcc-internal-format @@ -69435,7 +69336,7 @@ msgstr "未知的 TLS 模型%qs" #: common.opt:2530 #, gcc-internal-format msgid "unknown TLS model %qs" -msgstr "未知的 TLS 模型%qs" +msgstr "未知的 TLS 模型 %qs" #: common.opt:2862 #, fuzzy, gcc-internal-format -- cgit v1.1 From 5857042a2b3dd635fc6cae214abd60d3a8336060 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Fri, 23 Aug 2019 22:04:32 +0000 Subject: PR c++/79817 - attribute deprecated on namespace. * cp-tree.h (cp_warn_deprecated_use_scopes): Declare. * decl.c (grokdeclarator): Call cp_warn_deprecated_use_scopes. (type_is_deprecated): Likewise. * decl2.c (cp_warn_deprecated_use_scopes): New function. * name-lookup.c (handle_namespace_attrs): Handle attribute deprecated. * parser.c (cp_parser_namespace_alias_definition): Call cp_warn_deprecated_use_scopes. (cp_parser_using_declaration): Likewise. (cp_parser_using_directive): Likewise. * semantics.c (finish_id_expression_1): Likewise. * g++.dg/cpp0x/attributes-namespace1.C: New test. * g++.dg/cpp0x/attributes-namespace2.C: New test. * g++.dg/cpp0x/attributes-namespace3.C: New test. * g++.dg/cpp0x/attributes-namespace4.C: New test. * g++.dg/cpp0x/attributes-namespace5.C: New test. * g++.dg/cpp1z/namespace-attribs.C: Adjust. * g++.dg/cpp1z/namespace-attribs2.C: Adjust. From-SVN: r274888 --- gcc/cp/ChangeLog | 14 ++++++ gcc/cp/cp-tree.h | 1 + gcc/cp/decl.c | 6 ++- gcc/cp/decl2.c | 18 ++++++++ gcc/cp/name-lookup.c | 18 ++++++++ gcc/cp/parser.c | 4 ++ gcc/cp/semantics.c | 2 + gcc/testsuite/ChangeLog | 11 +++++ gcc/testsuite/g++.dg/cpp0x/attributes-namespace1.C | 50 ++++++++++++++++++++++ gcc/testsuite/g++.dg/cpp0x/attributes-namespace2.C | 27 ++++++++++++ gcc/testsuite/g++.dg/cpp0x/attributes-namespace3.C | 33 ++++++++++++++ gcc/testsuite/g++.dg/cpp0x/attributes-namespace4.C | 45 +++++++++++++++++++ gcc/testsuite/g++.dg/cpp0x/attributes-namespace5.C | 20 +++++++++ gcc/testsuite/g++.dg/cpp1z/namespace-attribs.C | 5 +-- gcc/testsuite/g++.dg/cpp1z/namespace-attribs2.C | 5 +-- 15 files changed, 252 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/attributes-namespace1.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/attributes-namespace2.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/attributes-namespace3.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/attributes-namespace4.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/attributes-namespace5.C (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c416082..5a59f98 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,17 @@ +2019-08-23 Marek Polacek + + PR c++/79817 - attribute deprecated on namespace. + * cp-tree.h (cp_warn_deprecated_use_scopes): Declare. + * decl.c (grokdeclarator): Call cp_warn_deprecated_use_scopes. + (type_is_deprecated): Likewise. + * decl2.c (cp_warn_deprecated_use_scopes): New function. + * name-lookup.c (handle_namespace_attrs): Handle attribute deprecated. + * parser.c (cp_parser_namespace_alias_definition): Call + cp_warn_deprecated_use_scopes. + (cp_parser_using_declaration): Likewise. + (cp_parser_using_directive): Likewise. + * semantics.c (finish_id_expression_1): Likewise. + 2019-08-23 Nathan Sidwell * class.c (check_for_override): Checking IDENTIFIER_VIRTUAL_P is diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 05f9186..42f180d 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6264,6 +6264,7 @@ extern bool is_list_ctor (tree); extern void validate_conversion_obstack (void); extern void mark_versions_used (tree); extern bool cp_warn_deprecated_use (tree, tsubst_flags_t = tf_warning_or_error); +extern void cp_warn_deprecated_use_scopes (tree); extern tree get_function_version_dispatcher (tree); /* in class.c */ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 88aa69c..cb5571e 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -10791,6 +10791,7 @@ grokdeclarator (const cp_declarator *declarator, cp_warn_deprecated_use (type); if (type && TREE_CODE (type) == TYPE_DECL) { + cp_warn_deprecated_use_scopes (CP_DECL_CONTEXT (type)); typedef_decl = type; type = TREE_TYPE (typedef_decl); if (DECL_ARTIFICIAL (typedef_decl)) @@ -13230,7 +13231,10 @@ type_is_deprecated (tree type) if (TREE_DEPRECATED (TYPE_NAME (type))) return type; else - return NULL_TREE; + { + cp_warn_deprecated_use_scopes (CP_DECL_CONTEXT (TYPE_NAME (type))); + return NULL_TREE; + } } /* Do warn about using typedefs to a deprecated class. */ diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index a32108f..aca37a2 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -5407,6 +5407,24 @@ cp_warn_deprecated_use (tree decl, tsubst_flags_t complain) return warned; } +/* Like above, but takes into account outer scopes. */ + +void +cp_warn_deprecated_use_scopes (tree scope) +{ + while (scope + && scope != error_mark_node + && scope != global_namespace) + { + if (cp_warn_deprecated_use (scope)) + return; + if (TYPE_P (scope)) + scope = CP_TYPE_CONTEXT (scope); + else + scope = CP_DECL_CONTEXT (scope); + } +} + /* Mark DECL (either a _DECL or a BASELINK) as "used" in the program. If DECL is a specialization or implicitly declared class member, generate the actual definition. Return false if something goes diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 5f5ff81..a8ab4db 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -4905,6 +4905,24 @@ handle_namespace_attrs (tree ns, tree attributes) DECL_ATTRIBUTES (ns) = tree_cons (name, args, DECL_ATTRIBUTES (ns)); } + else if (is_attribute_p ("deprecated", name)) + { + if (!DECL_NAME (ns)) + { + warning (OPT_Wattributes, "ignoring %qD attribute on anonymous " + "namespace", name); + continue; + } + if (args && TREE_CODE (TREE_VALUE (args)) != STRING_CST) + { + error ("deprecated message is not a string"); + continue; + } + TREE_DEPRECATED (ns) = 1; + if (args) + DECL_ATTRIBUTES (ns) = tree_cons (name, args, + DECL_ATTRIBUTES (ns)); + } else { warning (OPT_Wattributes, "%qD attribute directive ignored", diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 504f77a..5351478 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -19378,6 +19378,7 @@ cp_parser_namespace_alias_definition (cp_parser* parser) /* Look for the qualified-namespace-specifier. */ namespace_specifier = cp_parser_qualified_namespace_specifier (parser); + cp_warn_deprecated_use_scopes (namespace_specifier); /* Look for the `;' token. */ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); @@ -19492,6 +19493,8 @@ cp_parser_using_declaration (cp_parser* parser, && !TYPE_FUNCTION_SCOPE_P (qscope)) qscope = CP_TYPE_CONTEXT (qscope); + cp_warn_deprecated_use_scopes (qscope); + if (access_declaration_p && cp_parser_error_occurred (parser)) /* Something has already gone wrong; there's no need to parse further. Since an error has occurred, the return value of @@ -19752,6 +19755,7 @@ cp_parser_using_directive (cp_parser* parser) /*is_declaration=*/true); /* Get the namespace being used. */ namespace_decl = cp_parser_namespace_name (parser); + cp_warn_deprecated_use_scopes (namespace_decl); /* And any specified attributes. */ attribs = cp_parser_attributes_opt (parser); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 7ac1ba0..8aec4ef 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -3811,6 +3811,8 @@ finish_id_expression_1 (tree id_expression, if (TREE_CODE (decl) == FUNCTION_DECL) mark_used (decl); + cp_warn_deprecated_use_scopes (scope); + if (TYPE_P (scope)) decl = finish_qualified_id_expr (scope, decl, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 92e6da2..8e90713 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2019-08-23 Marek Polacek + + PR c++/79817 - attribute deprecated on namespace. + * g++.dg/cpp0x/attributes-namespace1.C: New test. + * g++.dg/cpp0x/attributes-namespace2.C: New test. + * g++.dg/cpp0x/attributes-namespace3.C: New test. + * g++.dg/cpp0x/attributes-namespace4.C: New test. + * g++.dg/cpp0x/attributes-namespace5.C: New test. + * g++.dg/cpp1z/namespace-attribs.C: Adjust. + * g++.dg/cpp1z/namespace-attribs2.C: Adjust. + 2019-08-23 Mihailo Stojanovic * gcc.target/mips/get-fcsr-3.c: New test. diff --git a/gcc/testsuite/g++.dg/cpp0x/attributes-namespace1.C b/gcc/testsuite/g++.dg/cpp0x/attributes-namespace1.C new file mode 100644 index 0000000..d49ebb0 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/attributes-namespace1.C @@ -0,0 +1,50 @@ +// PR c++/79817 - attribute deprecated on namespace. +// { dg-do compile { target c++11 } } + +namespace [[deprecated]] ns1 { int i; } +namespace [[deprecated("foo")]] ns2 { int i; } +namespace __attribute__((deprecated)) ns3 { int i; } +namespace __attribute__((deprecated("foo"))) ns4 { int i; } + +namespace [[deprecated]] ns6 +{ + enum E { X }; + void fn(); +} + +namespace [[deprecated]] ns7 +{ + namespace ns8 { + int x; + struct Z { }; + } + struct S { }; +} + +namespace N1 +{ + namespace N2 + { + namespace [[deprecated]] N3 + { + namespace N4 { int x; } + } + } +} + +void +f () +{ + ns1::i = 0; // { dg-warning ".ns1. is deprecated" } + ns2::i = 0; // { dg-warning ".ns2. is deprecated: foo" } + ns3::i = 0; // { dg-warning ".ns3. is deprecated" } + ns4::i = 0; // { dg-warning ".ns4. is deprecated" } + int i = ns1::i; // { dg-warning ".ns1. is deprecated" } + int k = ns6::E::X; // { dg-warning ".ns6. is deprecated" } + ns7::ns8::x = 42; // { dg-warning ".ns7. is deprecated" } + N1::N2::N3::N4::x = 42; // { dg-warning ".N1::N2::N3. is deprecated" } + ns6::fn(); // { dg-warning ".ns6. is deprecated" } + ns7::S s; // { dg-warning ".ns7. is deprecated" } + ns7::S sfn(int); // { dg-warning ".ns7. is deprecated" } + ns7::ns8::Z sfn2(int); // { dg-warning ".ns7. is deprecated" } +} diff --git a/gcc/testsuite/g++.dg/cpp0x/attributes-namespace2.C b/gcc/testsuite/g++.dg/cpp0x/attributes-namespace2.C new file mode 100644 index 0000000..08a043a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/attributes-namespace2.C @@ -0,0 +1,27 @@ +// PR c++/79817 - attribute deprecated on namespace. +// { dg-do compile { target c++11 } } + +namespace [[deprecated]] { // { dg-warning "ignoring .deprecated. attribute on anonymous namespace" } + int nn; +} + +inline namespace [[deprecated]] I { + int x; +} + +namespace M { + int y; + inline namespace [[deprecated]] N { + int x; + } +} + +void +g () +{ + nn = 42; + I::x = 42; // { dg-warning ".I. is deprecated" } + M::x = 42; + M::y = 42; + M::N::x = 42; // { dg-warning ".M::N. is deprecated" } +} diff --git a/gcc/testsuite/g++.dg/cpp0x/attributes-namespace3.C b/gcc/testsuite/g++.dg/cpp0x/attributes-namespace3.C new file mode 100644 index 0000000..81355ab --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/attributes-namespace3.C @@ -0,0 +1,33 @@ +// PR c++/79817 - attribute deprecated on namespace. +// { dg-do compile { target c++11 } } + +namespace [[deprecated]] N +{ + typedef decltype(sizeof(int)) T; + int x; + + namespace N2 { + typedef decltype(sizeof(int)) T; + int y; + } +} + +namespace M { + namespace [[deprecated]] M2 { + typedef decltype(sizeof(int)) T; + int z; + } +} + +void +fn2 () +{ + using N::x; // { dg-warning ".N. is deprecated" } + N::T j; // { dg-warning ".N. is deprecated" } + + using M::M2::z; // { dg-warning ".M::M2. is deprecated" } + M::M2::T l; // { dg-warning ".M::M2. is deprecated" } + + using N::N2::y; // { dg-warning ".N. is deprecated" } + N::N2::T k; // { dg-warning ".N. is deprecated" } +} diff --git a/gcc/testsuite/g++.dg/cpp0x/attributes-namespace4.C b/gcc/testsuite/g++.dg/cpp0x/attributes-namespace4.C new file mode 100644 index 0000000..de0c6df8 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/attributes-namespace4.C @@ -0,0 +1,45 @@ +// PR c++/79817 - attribute deprecated on namespace. +// { dg-do compile { target c++11 } } + +namespace [[deprecated]] N { + struct S { }; + using T = int; + const int value = 42; + int arr[10]; +} + +namespace [[deprecated]] Y { + int x; + int i = x; +} + +namespace [[deprecated]] M { + namespace M2 { + } +} + +enum E { F = N::value }; // { dg-warning ".N. is deprecated" } + +template // { dg-warning ".N. is deprecated" } +struct X { }; + +N::T foo(); // { dg-warning ".N. is deprecated" } + +void +g(N::T p) // { dg-warning ".N. is deprecated" } +{ + N::S s; // { dg-warning ".N. is deprecated" } + N::arr[0] = 42; // { dg-warning ".N. is deprecated" } +} + +namespace Z = Y; // { dg-warning ".Y. is deprecated" } +namespace Z2 = M::M2; // { dg-warning ".M. is deprecated" } + +void +g2 () +{ + using namespace Y; // { dg-warning ".Y. is deprecated" } + using namespace M::M2; // { dg-warning ".M. is deprecated" } + using TT = N::T; // { dg-warning ".N. is deprecated" } + using N::T; // { dg-warning ".N. is deprecated" } +} diff --git a/gcc/testsuite/g++.dg/cpp0x/attributes-namespace5.C b/gcc/testsuite/g++.dg/cpp0x/attributes-namespace5.C new file mode 100644 index 0000000..6dbcf32 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/attributes-namespace5.C @@ -0,0 +1,20 @@ +// PR c++/79817 - attribute deprecated on namespace. +// { dg-do compile { target c++11 } } + +namespace [[deprecated]] Y { + void f(); + void f2(int); + + template + struct S { + void f3 (); + }; +} + +void Y::f(); +void Y::f() { } +void Y::f2(int); +void Y::f2([[maybe_unused]] int); +void Y::f2(int) { } +template <> void Y::S::f3(); +template <> void Y::S::f3() { } diff --git a/gcc/testsuite/g++.dg/cpp1z/namespace-attribs.C b/gcc/testsuite/g++.dg/cpp1z/namespace-attribs.C index dd18551..29f8ce4 100644 --- a/gcc/testsuite/g++.dg/cpp1z/namespace-attribs.C +++ b/gcc/testsuite/g++.dg/cpp1z/namespace-attribs.C @@ -3,9 +3,8 @@ namespace A __attribute ((visibility ("default"))) {} -namespace B [[deprecated]] {} // { dg-warning "ignored" } +namespace B [[deprecated]] {} namespace __attribute ((visibility ("default"))) C {} -namespace [[deprecated]] D {} // { dg-warning "ignored" } - +namespace [[deprecated]] D {} diff --git a/gcc/testsuite/g++.dg/cpp1z/namespace-attribs2.C b/gcc/testsuite/g++.dg/cpp1z/namespace-attribs2.C index 193dbf6..7996b4b6 100644 --- a/gcc/testsuite/g++.dg/cpp1z/namespace-attribs2.C +++ b/gcc/testsuite/g++.dg/cpp1z/namespace-attribs2.C @@ -1,7 +1,6 @@ // { dg-do compile { target c++17 } } // { dg-additional-options "-pedantic" } -namespace B [[deprecated]] {} // { dg-warning "ignored|must precede" } - -namespace [[deprecated]] D {} // { dg-warning "ignored" } +namespace B [[deprecated]] {} // { dg-error "must precede" } +namespace [[deprecated]] D {} -- cgit v1.1 From 457dac402027dd7e14543fbd59a75858422cf6c6 Mon Sep 17 00:00:00 2001 From: Segher Boessenkool Date: Sat, 24 Aug 2019 00:19:40 +0200 Subject: rs6000: New darn testcase (PR91481) We used to implement darn with unspecs, not unspec_volatiles, which means two darn instructions could be CSEd together. This testcase tests it by adding together four random numbers. If all is well that means we get four darn instructions, because such a small loop is unrolled fine at -O2 already. If things go bad, combine will combine it all to one darn and a shift left by two. gcc/testsuite/ PR target/91481 * gcc.target/powerpc/darn-3.c: New testcase. From-SVN: r274889 --- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.target/powerpc/darn-3.c | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 gcc/testsuite/gcc.target/powerpc/darn-3.c (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8e90713..f657cfa 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-08-23 Segher Boessenkool + + PR target/91481 + * gcc.target/powerpc/darn-3.c: New testcase. + 2019-08-23 Marek Polacek PR c++/79817 - attribute deprecated on namespace. diff --git a/gcc/testsuite/gcc.target/powerpc/darn-3.c b/gcc/testsuite/gcc.target/powerpc/darn-3.c new file mode 100644 index 0000000..477901f --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/darn-3.c @@ -0,0 +1,16 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "" { powerpc*-*-aix* } } */ +/* { dg-options "-O2 -mdejagnu-cpu=power9" } */ + +static int darn32(void) { return __builtin_darn_32(); } + +int four(void) +{ + int sum = 0; + int i; + for (i = 0; i < 4; i++) + sum += darn32(); + return sum; +} + +/* { dg-final { scan-assembler-times {(?n)\mdarn .*,0\M} 4 } } */ -- cgit v1.1 From 6ae361ae458d4056d6c36fa42f1775c417457b10 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 23 Aug 2019 22:38:58 +0000 Subject: compiler: record pointer var values to remove write barriers Record when a local pointer variable is set to a value such that indirecting through the pointer does not require a write barrier. Use that to eliminate write barriers when indirecting through that local pointer variable. Only keep this information per-block, so it's not all that applicable. This reduces the number of write barriers generated when compiling the runtime package from 553 to 524. The point of this is to eliminate a bad write barrier in the bytes function in runtime/print.go. Mark that function nowritebarrier so that the problem does not recur. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/191581 From-SVN: r274890 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/expressions.cc | 2 +- gcc/go/gofrontend/gogo.h | 9 ++- gcc/go/gofrontend/wb.cc | 115 +++++++++++++++++++++++++++++++-------- 4 files changed, 101 insertions(+), 27 deletions(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 5c02446..73c7534 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -82d27f0f140f33406cf59c0fb262f6dba3077f8e +c9ca1c6bf887c752cc75cf1ddaec8ddd1ec962d4 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 378dab5..90a39a2 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -9039,7 +9039,7 @@ Builtin_call_expression::flatten_append(Gogo* gogo, Named_object* function, // directly before the write barrier pass. Statement* assign; if (assign_lhs != NULL - || !gogo->assign_needs_write_barrier(lhs)) + || !gogo->assign_needs_write_barrier(lhs, NULL)) assign = Statement::make_assignment(lhs, elem, loc); else { diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h index 4521763..087e890 100644 --- a/gcc/go/gofrontend/gogo.h +++ b/gcc/go/gofrontend/gogo.h @@ -771,7 +771,14 @@ class Gogo // Return whether an assignment that sets LHS to RHS needs a write // barrier. bool - assign_needs_write_barrier(Expression* lhs); + assign_needs_write_barrier(Expression* lhs, + Unordered_set(const Named_object*)*); + + // Return whether EXPR is the address of a variable that can be set + // without a write barrier. That is, if this returns true, then an + // assignment to *EXPR does not require a write barrier. + bool + is_nonwb_pointer(Expression* expr, Unordered_set(const Named_object*)*); // Return an assignment that sets LHS to RHS using a write barrier. // This returns an if statement that checks whether write barriers diff --git a/gcc/go/gofrontend/wb.cc b/gcc/go/gofrontend/wb.cc index 501ad6a..41d8f94 100644 --- a/gcc/go/gofrontend/wb.cc +++ b/gcc/go/gofrontend/wb.cc @@ -402,14 +402,21 @@ class Write_barriers : public Traverse { public: Write_barriers(Gogo* gogo) - : Traverse(traverse_functions | traverse_variables | traverse_statements), - gogo_(gogo), function_(NULL), statements_added_() + : Traverse(traverse_functions + | traverse_blocks + | traverse_variables + | traverse_statements), + gogo_(gogo), function_(NULL), statements_added_(), + nonwb_pointers_() { } int function(Named_object*); int + block(Block*); + + int variable(Named_object*); int @@ -422,6 +429,9 @@ class Write_barriers : public Traverse Function* function_; // Statements introduced. Statement_inserter::Statements statements_added_; + // Within a single block, pointer variables that point to values + // that do not need write barriers. + Unordered_set(const Named_object*) nonwb_pointers_; }; // Traverse a function. Just record it for later. @@ -439,6 +449,16 @@ Write_barriers::function(Named_object* no) return TRAVERSE_SKIP_COMPONENTS; } +// Traverse a block. Clear anything we know about local pointer +// variables. + +int +Write_barriers::block(Block*) +{ + this->nonwb_pointers_.clear(); + return TRAVERSE_CONTINUE; +} + // Insert write barriers for a global variable: ensure that variable // initialization is handled correctly. This is rarely needed, since // we currently don't enable background GC until after all global @@ -533,7 +553,16 @@ Write_barriers::statement(Block* block, size_t* pindex, Statement* s) // local variables get declaration statements, and local // variables on the stack do not require write barriers. if (!var->is_in_heap()) - break; + { + // If this is a pointer variable, and assigning through + // the initializer does not require a write barrier, + // record that fact. + if (var->type()->points_to() != NULL + && this->gogo_->is_nonwb_pointer(init, &this->nonwb_pointers_)) + this->nonwb_pointers_.insert(no); + + break; + } // Nothing to do if the variable does not contain any pointers. if (!var->type()->has_pointer()) @@ -578,15 +607,27 @@ Write_barriers::statement(Block* block, size_t* pindex, Statement* s) { Assignment_statement* as = s->assignment_statement(); - if (as->omit_write_barrier()) - break; - Expression* lhs = as->lhs(); Expression* rhs = as->rhs(); + // Keep track of variables whose values do not escape. + Var_expression* lhsve = lhs->var_expression(); + if (lhsve != NULL && lhsve->type()->points_to() != NULL) + { + Named_object* no = lhsve->named_object(); + if (this->gogo_->is_nonwb_pointer(rhs, &this->nonwb_pointers_)) + this->nonwb_pointers_.insert(no); + else + this->nonwb_pointers_.erase(no); + } + + if (as->omit_write_barrier()) + break; + // We may need to emit a write barrier for the assignment. - if (!this->gogo_->assign_needs_write_barrier(lhs)) + if (!this->gogo_->assign_needs_write_barrier(lhs, + &this->nonwb_pointers_)) break; // Change the assignment to use a write barrier. @@ -667,9 +708,13 @@ Gogo::write_barrier_variable() } // Return whether an assignment that sets LHS needs a write barrier. +// NONWB_POINTERS is a set of variables that point to values that do +// not need write barriers. bool -Gogo::assign_needs_write_barrier(Expression* lhs) +Gogo::assign_needs_write_barrier( + Expression* lhs, + Unordered_set(const Named_object*)* nonwb_pointers) { // Nothing to do if the variable does not contain any pointers. if (!lhs->type()->has_pointer()) @@ -738,22 +783,10 @@ Gogo::assign_needs_write_barrier(Expression* lhs) // Nothing to do for an assignment to *(convert(&x)) where // x is local variable or a temporary variable. Unary_expression* ue = lhs->unary_expression(); - if (ue != NULL && ue->op() == OPERATOR_MULT) - { - Expression* expr = ue->operand(); - while (true) - { - if (expr->conversion_expression() != NULL) - expr = expr->conversion_expression()->expr(); - else if (expr->unsafe_conversion_expression() != NULL) - expr = expr->unsafe_conversion_expression()->expr(); - else - break; - } - ue = expr->unary_expression(); - if (ue != NULL && ue->op() == OPERATOR_AND) - return this->assign_needs_write_barrier(ue->operand()); - } + if (ue != NULL + && ue->op() == OPERATOR_MULT + && this->is_nonwb_pointer(ue->operand(), nonwb_pointers)) + return false; // For a struct assignment, we don't need a write barrier if all the // pointer types can not be in the heap. @@ -784,6 +817,40 @@ Gogo::assign_needs_write_barrier(Expression* lhs) return true; } +// Return whether EXPR is the address of a variable that can be set +// without a write barrier. That is, if this returns true, then an +// assignment to *EXPR does not require a write barrier. +// NONWB_POINTERS is a set of variables that point to values that do +// not need write barriers. + +bool +Gogo::is_nonwb_pointer(Expression* expr, + Unordered_set(const Named_object*)* nonwb_pointers) +{ + while (true) + { + if (expr->conversion_expression() != NULL) + expr = expr->conversion_expression()->expr(); + else if (expr->unsafe_conversion_expression() != NULL) + expr = expr->unsafe_conversion_expression()->expr(); + else + break; + } + + Var_expression* ve = expr->var_expression(); + if (ve != NULL + && nonwb_pointers != NULL + && nonwb_pointers->find(ve->named_object()) != nonwb_pointers->end()) + return true; + + Unary_expression* ue = expr->unary_expression(); + if (ue == NULL || ue->op() != OPERATOR_AND) + return false; + if (this->assign_needs_write_barrier(ue->operand(), nonwb_pointers)) + return false; + return true; +} + // Return a statement that sets LHS to RHS using a write barrier. // ENCLOSING is the enclosing block. -- cgit v1.1 From 9bf6c63da9ff140bb37d957ad1252848e2df28ef Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Fri, 23 Aug 2019 23:24:46 +0000 Subject: PR c++/91521 - wrong error with operator->. * decl.c (grokdeclarator): Return error_mark_node for an invalid trailing return type. * g++.dg/parse/operator8.C: New test. From-SVN: r274891 --- gcc/cp/ChangeLog | 4 ++++ gcc/cp/decl.c | 2 ++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/parse/operator8.C | 13 +++++++++++++ 4 files changed, 24 insertions(+) create mode 100644 gcc/testsuite/g++.dg/parse/operator8.C (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5a59f98..8eebf89 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2019-08-23 Marek Polacek + PR c++/91521 - wrong error with operator->. + * decl.c (grokdeclarator): Return error_mark_node for an invalid + trailing return type. + PR c++/79817 - attribute deprecated on namespace. * cp-tree.h (cp_warn_deprecated_use_scopes): Declare. * decl.c (grokdeclarator): Call cp_warn_deprecated_use_scopes. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index cb5571e..9f79238 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -11549,6 +11549,8 @@ grokdeclarator (const cp_declarator *declarator, else if (late_return_type && sfk != sfk_conversion) { + if (late_return_type == error_mark_node) + return error_mark_node; if (cxx_dialect < cxx11) /* Not using maybe_warn_cpp0x because this should always be an error. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f657cfa..2162fcf 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-08-23 Marek Polacek + + PR c++/91521 - wrong error with operator->. + * g++.dg/parse/operator8.C: New test. + 2019-08-23 Segher Boessenkool PR target/91481 diff --git a/gcc/testsuite/g++.dg/parse/operator8.C b/gcc/testsuite/g++.dg/parse/operator8.C new file mode 100644 index 0000000..c5ee3eb --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/operator8.C @@ -0,0 +1,13 @@ +// PR c++/91521 - wrong error with operator->. +// { dg-do compile } + +struct foo { + int bar() { return 0; } + foo* operator->() { return this; } +}; + +int main() +{ + int pt(foo()->bar()); + return pt; +} -- cgit v1.1 From 01c53a74cd594131d9b066eb3036c6245562dc41 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 23 Aug 2019 19:29:10 -0400 Subject: * parser.c (cp_parser_nested_name_specifier_opt): Avoid redundant error. From-SVN: r274893 --- gcc/cp/ChangeLog | 5 +++++ gcc/cp/parser.c | 8 +++++--- 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8eebf89..0643755 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2019-08-22 Jason Merrill + + * parser.c (cp_parser_nested_name_specifier_opt): Avoid redundant + error. + 2019-08-23 Marek Polacek PR c++/91521 - wrong error with operator->. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 5351478..3825753 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -6420,9 +6420,11 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser, == CPP_SCOPE)) { token = cp_lexer_consume_token (parser->lexer); - error_at (token->location, "% evaluates to %qT, " - "which is not a class or enumeration type", - token->u.tree_check_value->value); + tree dtype = token->u.tree_check_value->value; + if (dtype != error_mark_node) + error_at (token->location, "% evaluates to %qT, " + "which is not a class or enumeration type", + dtype); parser->scope = error_mark_node; error_p = true; /* As below. */ -- cgit v1.1 From 5b93b053495e46aaf29811f1ac23d7f484be6ea9 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 23 Aug 2019 19:29:16 -0400 Subject: Fix handling of namespace-scope undeduced auto decls. * decl2.c (decl_dependent_p): New. (mark_used): Check it instead of just processing_template_decl. From-SVN: r274894 --- gcc/cp/ChangeLog | 5 +++++ gcc/cp/decl2.c | 24 +++++++++++++++++++++++- gcc/testsuite/g++.dg/cpp1z/constexpr-if30.C | 10 ++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp1z/constexpr-if30.C (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0643755..86d1849 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2019-08-22 Jason Merrill + * decl2.c (decl_dependent_p): New. + (mark_used): Check it instead of just processing_template_decl. + +2019-08-22 Jason Merrill + * parser.c (cp_parser_nested_name_specifier_opt): Avoid redundant error. diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index aca37a2..36c6f4c 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -5425,6 +5425,25 @@ cp_warn_deprecated_use_scopes (tree scope) } } +/* True if DECL or its enclosing scope have unbound template parameters. */ + +bool +decl_dependent_p (tree decl) +{ + if (DECL_FUNCTION_SCOPE_P (decl) + || TREE_CODE (decl) == CONST_DECL + || TREE_CODE (decl) == USING_DECL + || TREE_CODE (decl) == FIELD_DECL) + decl = CP_DECL_CONTEXT (decl); + if (tree tinfo = get_template_info (decl)) + if (any_dependent_template_arguments_p (TI_ARGS (tinfo))) + return true; + if (LAMBDA_FUNCTION_P (decl) + && dependent_type_p (DECL_CONTEXT (decl))) + return true; + return false; +} + /* Mark DECL (either a _DECL or a BASELINK) as "used" in the program. If DECL is a specialization or implicitly declared class member, generate the actual definition. Return false if something goes @@ -5451,6 +5470,9 @@ mark_used (tree decl, tsubst_flags_t complain) decl = OVL_FIRST (decl); } + if (!DECL_P (decl)) + return true; + /* Set TREE_USED for the benefit of -Wunused. */ TREE_USED (decl) = 1; /* And for structured bindings also the underlying decl. */ @@ -5498,7 +5520,7 @@ mark_used (tree decl, tsubst_flags_t complain) || DECL_LANG_SPECIFIC (decl) == NULL || DECL_THUNK_P (decl)) { - if (!processing_template_decl + if (!decl_dependent_p (decl) && !require_deduced_type (decl, complain)) return false; return true; diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if30.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-if30.C new file mode 100644 index 0000000..1e3d15d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-if30.C @@ -0,0 +1,10 @@ +// { dg-do compile { target c++17 } } + +auto fn = [](auto i) { + if constexpr (sizeof(i) == 1) + return fn(123); // { dg-error "auto" } +}; + +int main() { + fn('!'); +} -- cgit v1.1 From 22b23ef2379b1abdb80fd293ac1bc0ff1ab6c170 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sat, 24 Aug 2019 00:16:42 +0000 Subject: Daily bump. From-SVN: r274898 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index c2ad9278..77db483 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20190823 +20190824 -- cgit v1.1 From c6ca0e3e69e2e3681c81d5a5ddd2dcd6f41b7522 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Sat, 24 Aug 2019 19:39:44 +0000 Subject: semantics.c (finish_switch_cond): Improve error message location. /cp 2019-08-24 Paolo Carlini * semantics.c (finish_switch_cond): Improve error message location. /testsuite 2019-08-24 Paolo Carlini * g++.dg/conversion/simd4.C: Test all the locations. From-SVN: r274901 --- gcc/cp/ChangeLog | 4 ++++ gcc/cp/semantics.c | 4 +++- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/g++.dg/conversion/simd4.C | 16 ++++++++-------- 4 files changed, 19 insertions(+), 9 deletions(-) (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 86d1849..d0a8c77 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,7 @@ +2019-08-24 Paolo Carlini + + * semantics.c (finish_switch_cond): Improve error message location. + 2019-08-22 Jason Merrill * decl2.c (decl_dependent_p): New. diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 8aec4ef..1f774593 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -1185,10 +1185,12 @@ finish_switch_cond (tree cond, tree switch_stmt) if (!processing_template_decl) { /* Convert the condition to an integer or enumeration type. */ + tree orig_cond = cond; cond = build_expr_type_conversion (WANT_INT | WANT_ENUM, cond, true); if (cond == NULL_TREE) { - error ("switch quantity not an integer"); + error_at (cp_expr_loc_or_input_loc (orig_cond), + "switch quantity not an integer"); cond = error_mark_node; } /* We want unlowered type here to handle enum bit-fields. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2162fcf..af6fe82 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-08-24 Paolo Carlini + + * g++.dg/conversion/simd4.C: Test all the locations. + 2019-08-23 Marek Polacek PR c++/91521 - wrong error with operator->. diff --git a/gcc/testsuite/g++.dg/conversion/simd4.C b/gcc/testsuite/g++.dg/conversion/simd4.C index 22274a1..9d43b02 100644 --- a/gcc/testsuite/g++.dg/conversion/simd4.C +++ b/gcc/testsuite/g++.dg/conversion/simd4.C @@ -20,15 +20,15 @@ foo () v[b]; // { dg-error "4:invalid types" } w[b]; // { dg-error "4:invalid types" } new int[t]; - new int[u]; // { dg-error "new-declarator must have integral" } - new int[v]; // { dg-error "new-declarator must have integral" } - new int[w]; // { dg-error "new-declarator must have integral" } + new int[u]; // { dg-error "11:expression in new-declarator must have integral" } + new int[v]; // { dg-error "11:expression in new-declarator must have integral" } + new int[w]; // { dg-error "11:expression in new-declarator must have integral" } switch (t) { default: break; } - switch (u) { default: break; } // { dg-error "switch quantity not an integer" } - switch (v) { default: break; } // { dg-error "switch quantity not an integer" } - switch (w) { default: break; } // { dg-error "switch quantity not an integer" } + switch (u) { default: break; } // { dg-error "11:switch quantity not an integer" } + switch (v) { default: break; } // { dg-error "11:switch quantity not an integer" } + switch (w) { default: break; } // { dg-error "11:switch quantity not an integer" } t = ~t; - u = ~u; // { dg-error "wrong type argument to bit-complement" } + u = ~u; // { dg-error "8:wrong type argument to bit-complement" } v = ~v; - w = ~w; // { dg-error "wrong type argument to bit-complement" } + w = ~w; // { dg-error "8:wrong type argument to bit-complement" } } -- cgit v1.1 From e68a35ae4a65d2b3f42b22e6920a7a29f5727b3f Mon Sep 17 00:00:00 2001 From: Thomas Koenig Date: Sat, 24 Aug 2019 21:12:45 +0000 Subject: re PR fortran/91390 (treatment of extra parameter in a subroutine call) 2019-08-24 Thomas Koenig PR fortran/91390 PR fortran/91519 * frontend-passes.c (check_externals_procedure): New function. If a procedure is not in the translation unit, create an "interface" for it, including its formal arguments. (check_externals_code): Use check_externals_procedure for common code with check_externals_expr. (check_externals_expr): Vice versa. * gfortran.h (gfc_get_formal_from_actual-arglist): New prototype. (gfc_compare_actual_formal): New prototype. * interface.c (compare_actual_formal): Rename to (gfc_compare_actual_formal): New function, make global. (gfc_get_formal_from_actual_arglist): Make global, and move here from * trans-types.c (get_formal_from_actual_arglist): Remove here. (gfc_get_function_type): Use gfc_get_formal_from_actual_arglist. 2019-08-24 Thomas Koenig PR fortran/91390 PR fortran/91519 * gfortran.dg/bessel_3.f90: Add type mismatch errors. * gfortran.dg/coarray_7.f90: Rename subroutines to avoid additional errors. * gfortran.dg/g77/20010519-1.f: Add -std=legacy. Remove warnings for ASSIGN. Add warnings for type mismatch. * gfortran.dg/goacc/acc_on_device-1.f95: Add -std=legacy. Add catch-all warning. * gfortran.dg/internal_pack_9.f90: Rename subroutine to avoid type error. * gfortran.dg/internal_pack_9.f90: Add -std=legacy. Add warnings for type mismatch. * gfortran.dg/pr39937.f: Add -std=legacy and type warnings. Move here from * gfortran.fortran-torture/compile/pr39937.f: Move to gfortran.dg. From-SVN: r274902 --- gcc/fortran/ChangeLog | 20 ++++- gcc/fortran/frontend-passes.c | 88 +++++++++++++++------- gcc/fortran/gfortran.h | 3 + gcc/fortran/interface.c | 78 +++++++++++++++++-- gcc/fortran/trans-types.c | 62 +-------------- gcc/testsuite/ChangeLog | 19 +++++ gcc/testsuite/gfortran.dg/bessel_3.f90 | 4 +- gcc/testsuite/gfortran.dg/coarray_7.f90 | 6 +- gcc/testsuite/gfortran.dg/g77/20010519-1.f | 59 ++++++++------- .../gfortran.dg/goacc/acc_on_device-1.f95 | 4 +- gcc/testsuite/gfortran.dg/internal_pack_9.f90 | 4 +- gcc/testsuite/gfortran.dg/pr24823.f | 6 +- gcc/testsuite/gfortran.dg/pr39937.f | 30 ++++++++ .../gfortran.fortran-torture/compile/pr39937.f | 28 ------- 14 files changed, 244 insertions(+), 167 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/pr39937.f delete mode 100644 gcc/testsuite/gfortran.fortran-torture/compile/pr39937.f (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 4bd9291..abdf9e6 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,21 @@ +2019-08-24 Thomas Koenig + + PR fortran/91390 + PR fortran/91519 + * frontend-passes.c (check_externals_procedure): New + function. If a procedure is not in the translation unit, create + an "interface" for it, including its formal arguments. + (check_externals_code): Use check_externals_procedure for common + code with check_externals_expr. + (check_externals_expr): Vice versa. + * gfortran.h (gfc_get_formal_from_actual-arglist): New prototype. + (gfc_compare_actual_formal): New prototype. + * interface.c (compare_actual_formal): Rename to + (gfc_compare_actual_formal): New function, make global. + (gfc_get_formal_from_actual_arglist): Make global, and move here from + * trans-types.c (get_formal_from_actual_arglist): Remove here. + (gfc_get_function_type): Use gfc_get_formal_from_actual_arglist. + 2019-08-23 Mark Eggleston * intrinsics.text: References in 'See also:' are now on @@ -14,7 +32,7 @@ 2019-08-23 Mark Eggleston - * intrinsics.text: Removed empty sections. The order of + * intrinsics.text: Removed empty sections. The order of sections for each intrinsic is now consistent throughout. Stray words removed. Text in the wrong section moved. Missing standard statement inserted. diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c index dd82089..fa41667 100644 --- a/gcc/fortran/frontend-passes.c +++ b/gcc/fortran/frontend-passes.c @@ -5369,72 +5369,104 @@ gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn, We do this by looping over the code (and expressions). The first call we happen to find is assumed to be canonical. */ -/* Callback for external functions. */ + +/* Common tests for argument checking for both functions and subroutines. */ static int -check_externals_expr (gfc_expr **ep, int *walk_subtrees ATTRIBUTE_UNUSED, - void *data ATTRIBUTE_UNUSED) +check_externals_procedure (gfc_symbol *sym, locus *loc, gfc_actual_arglist *actual) { - gfc_expr *e = *ep; - gfc_symbol *sym, *def_sym; gfc_gsymbol *gsym; + gfc_symbol *def_sym = NULL; - if (e->expr_type != EXPR_FUNCTION) + if (sym == NULL || sym->attr.is_bind_c) return 0; - sym = e->value.function.esym; - - if (sym == NULL || sym->attr.is_bind_c) + if (sym->attr.proc != PROC_EXTERNAL && sym->attr.proc != PROC_UNKNOWN) return 0; - if (sym->attr.proc != PROC_EXTERNAL && sym->attr.proc != PROC_UNKNOWN) + if (sym->attr.if_source == IFSRC_IFBODY || sym->attr.if_source == IFSRC_DECL) return 0; gsym = gfc_find_gsymbol (gfc_gsym_root, sym->name); if (gsym == NULL) return 0; - gfc_find_symbol (sym->name, gsym->ns, 0, &def_sym); + if (gsym->ns) + gfc_find_symbol (sym->name, gsym->ns, 0, &def_sym); - if (sym && def_sym) - gfc_procedure_use (def_sym, &e->value.function.actual, &e->where); + if (def_sym) + { + gfc_procedure_use (def_sym, &actual, loc); + return 0; + } + + /* First time we have seen this procedure called. Let's create an + "interface" from the call and put it into a new namespace. */ + gfc_namespace *save_ns; + gfc_symbol *new_sym; + + gsym->where = *loc; + save_ns = gfc_current_ns; + gsym->ns = gfc_get_namespace (gfc_current_ns, 0); + gsym->ns->proc_name = sym; + + gfc_get_symbol (sym->name, gsym->ns, &new_sym); + gcc_assert (new_sym); + new_sym->attr = sym->attr; + new_sym->attr.if_source = IFSRC_DECL; + gfc_current_ns = gsym->ns; + + gfc_get_formal_from_actual_arglist (new_sym, actual); + gfc_current_ns = save_ns; return 0; + } -/* Callback for external code. */ +/* Callback for calls of external routines. */ static int check_externals_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED, void *data ATTRIBUTE_UNUSED) { gfc_code *co = *c; - gfc_symbol *sym, *def_sym; - gfc_gsymbol *gsym; + gfc_symbol *sym; + locus *loc; + gfc_actual_arglist *actual; if (co->op != EXEC_CALL) return 0; sym = co->resolved_sym; - if (sym == NULL || sym->attr.is_bind_c) - return 0; + loc = &co->loc; + actual = co->ext.actual; - if (sym->attr.proc != PROC_EXTERNAL && sym->attr.proc != PROC_UNKNOWN) - return 0; + return check_externals_procedure (sym, loc, actual); - if (sym->attr.if_source == IFSRC_IFBODY || sym->attr.if_source == IFSRC_DECL) - return 0; +} - gsym = gfc_find_gsymbol (gfc_gsym_root, sym->name); - if (gsym == NULL) +/* Callback for external functions. */ + +static int +check_externals_expr (gfc_expr **ep, int *walk_subtrees ATTRIBUTE_UNUSED, + void *data ATTRIBUTE_UNUSED) +{ + gfc_expr *e = *ep; + gfc_symbol *sym; + locus *loc; + gfc_actual_arglist *actual; + + if (e->expr_type != EXPR_FUNCTION) return 0; - gfc_find_symbol (sym->name, gsym->ns, 0, &def_sym); + sym = e->value.function.esym; + if (sym == NULL) + return 0; - if (sym && def_sym) - gfc_procedure_use (def_sym, &co->ext.actual, &co->loc); + loc = &e->where; + actual = e->value.function.actual; - return 0; + return check_externals_procedure (sym, loc, actual); } /* Called routine. */ diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 6a491ab..7f54897 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -3421,6 +3421,9 @@ bool gfc_check_typebound_override (gfc_symtree*, gfc_symtree*); void gfc_check_dtio_interfaces (gfc_symbol*); gfc_symtree* gfc_find_typebound_dtio_proc (gfc_symbol *, bool, bool); gfc_symbol* gfc_find_specific_dtio_proc (gfc_symbol*, bool, bool); +void gfc_get_formal_from_actual_arglist (gfc_symbol *, gfc_actual_arglist *); +bool gfc_compare_actual_formal (gfc_actual_arglist **, gfc_formal_arglist *, + int, int, bool, locus *); /* io.c */ diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c index d6f6cce..43d7cd5 100644 --- a/gcc/fortran/interface.c +++ b/gcc/fortran/interface.c @@ -2878,10 +2878,10 @@ lookup_arg_fuzzy (const char *arg, gfc_formal_arglist *arguments) errors when things don't match instead of just returning the status code. */ -static bool -compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, - int ranks_must_agree, int is_elemental, - bool in_statement_function, locus *where) +bool +gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, + int ranks_must_agree, int is_elemental, + bool in_statement_function, locus *where) { gfc_actual_arglist **new_arg, *a, *actual; gfc_formal_arglist *f; @@ -3805,8 +3805,8 @@ gfc_procedure_use (gfc_symbol *sym, gfc_actual_arglist **ap, locus *where) /* For a statement function, check that types and type parameters of actual arguments and dummy arguments match. */ - if (!compare_actual_formal (ap, dummy_args, 0, sym->attr.elemental, - sym->attr.proc == PROC_ST_FUNCTION, where)) + if (!gfc_compare_actual_formal (ap, dummy_args, 0, sym->attr.elemental, + sym->attr.proc == PROC_ST_FUNCTION, where)) return false; if (!check_intents (dummy_args, *ap)) @@ -3854,7 +3854,7 @@ gfc_ppc_use (gfc_component *comp, gfc_actual_arglist **ap, locus *where) return; } - if (!compare_actual_formal (ap, comp->ts.interface->formal, 0, + if (!gfc_compare_actual_formal (ap, comp->ts.interface->formal, 0, comp->attr.elemental, false, where)) return; @@ -3880,7 +3880,7 @@ gfc_arglist_matches_symbol (gfc_actual_arglist** args, gfc_symbol* sym) dummy_args = gfc_sym_get_dummy_args (sym); r = !sym->attr.elemental; - if (compare_actual_formal (args, dummy_args, r, !r, false, NULL)) + if (gfc_compare_actual_formal (args, dummy_args, r, !r, false, NULL)) { check_intents (dummy_args, *args); if (warn_aliasing) @@ -5131,3 +5131,65 @@ finish: return dtio_sub; } + +/* Helper function - if we do not find an interface for a procedure, + construct it from the actual arglist. Luckily, this can only + happen for call by reference, so the information we actually need + to provide (and which would be impossible to guess from the call + itself) is not actually needed. */ + +void +gfc_get_formal_from_actual_arglist (gfc_symbol *sym, + gfc_actual_arglist *actual_args) +{ + gfc_actual_arglist *a; + gfc_formal_arglist **f; + gfc_symbol *s; + char name[GFC_MAX_SYMBOL_LEN + 1]; + static int var_num; + + f = &sym->formal; + for (a = actual_args; a != NULL; a = a->next) + { + (*f) = gfc_get_formal_arglist (); + if (a->expr) + { + snprintf (name, GFC_MAX_SYMBOL_LEN, "_formal_%d", var_num ++); + gfc_get_symbol (name, gfc_current_ns, &s); + if (a->expr->ts.type == BT_PROCEDURE) + { + s->attr.flavor = FL_PROCEDURE; + } + else + { + s->ts = a->expr->ts; + + if (s->ts.type == BT_CHARACTER) + s->ts.u.cl = gfc_get_charlen (); + + s->ts.deferred = 0; + s->ts.is_iso_c = 0; + s->ts.is_c_interop = 0; + s->attr.flavor = FL_VARIABLE; + s->attr.artificial = 1; + if (a->expr->rank > 0) + { + s->attr.dimension = 1; + s->as = gfc_get_array_spec (); + s->as->rank = 1; + s->as->lower[0] = gfc_get_int_expr (gfc_index_integer_kind, + &a->expr->where, 1); + s->as->upper[0] = NULL; + s->as->type = AS_ASSUMED_SIZE; + } + } + s->attr.dummy = 1; + s->attr.intent = INTENT_UNKNOWN; + (*f)->sym = s; + } + else /* If a->expr is NULL, this is an alternate rerturn. */ + (*f)->sym = NULL; + + f = &((*f)->next); + } +} diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c index e1033b3..82666c4 100644 --- a/gcc/fortran/trans-types.c +++ b/gcc/fortran/trans-types.c @@ -2975,66 +2975,6 @@ create_fn_spec (gfc_symbol *sym, tree fntype) return build_type_attribute_variant (fntype, tmp); } -/* Helper function - if we do not find an interface for a procedure, - construct it from the actual arglist. Luckily, this can only - happen for call by reference, so the information we actually need - to provide (and which would be impossible to guess from the call - itself) is not actually needed. */ - -static void -get_formal_from_actual_arglist (gfc_symbol *sym, gfc_actual_arglist *actual_args) -{ - gfc_actual_arglist *a; - gfc_formal_arglist **f; - gfc_symbol *s; - char name[GFC_MAX_SYMBOL_LEN + 1]; - static int var_num; - - f = &sym->formal; - for (a = actual_args; a != NULL; a = a->next) - { - (*f) = gfc_get_formal_arglist (); - if (a->expr) - { - snprintf (name, GFC_MAX_SYMBOL_LEN, "_formal_%d", var_num ++); - gfc_get_symbol (name, gfc_current_ns, &s); - if (a->expr->ts.type == BT_PROCEDURE) - { - s->attr.flavor = FL_PROCEDURE; - } - else - { - s->ts = a->expr->ts; - - if (s->ts.type == BT_CHARACTER) - s->ts.u.cl = gfc_get_charlen (); - - s->ts.deferred = 0; - s->ts.is_iso_c = 0; - s->ts.is_c_interop = 0; - s->attr.flavor = FL_VARIABLE; - if (a->expr->rank > 0) - { - s->attr.dimension = 1; - s->as = gfc_get_array_spec (); - s->as->rank = 1; - s->as->lower[0] = gfc_get_int_expr (gfc_index_integer_kind, - &a->expr->where, 1); - s->as->upper[0] = NULL; - s->as->type = AS_ASSUMED_SIZE; - } - } - s->attr.dummy = 1; - s->attr.intent = INTENT_UNKNOWN; - (*f)->sym = s; - } - else /* If a->expr is NULL, this is an alternate rerturn. */ - (*f)->sym = NULL; - - f = &((*f)->next); - } -} - tree gfc_get_function_type (gfc_symbol * sym, gfc_actual_arglist *actual_args) { @@ -3097,7 +3037,7 @@ gfc_get_function_type (gfc_symbol * sym, gfc_actual_arglist *actual_args) if (sym->backend_decl == error_mark_node && actual_args != NULL && sym->formal == NULL && (sym->attr.proc == PROC_EXTERNAL || sym->attr.proc == PROC_UNKNOWN)) - get_formal_from_actual_arglist (sym, actual_args); + gfc_get_formal_from_actual_arglist (sym, actual_args); /* Build the argument types for the function. */ for (f = gfc_sym_get_dummy_args (sym); f; f = f->next) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index af6fe82..efb0157 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,22 @@ +2019-08-24 Thomas Koenig + + PR fortran/91390 + PR fortran/91519 + * gfortran.dg/bessel_3.f90: Add type mismatch errors. + * gfortran.dg/coarray_7.f90: Rename subroutines to avoid + additional errors. + * gfortran.dg/g77/20010519-1.f: Add -std=legacy. Remove + warnings for ASSIGN. Add warnings for type mismatch. + * gfortran.dg/goacc/acc_on_device-1.f95: Add -std=legacy. + Add catch-all warning. + * gfortran.dg/internal_pack_9.f90: Rename subroutine to + avoid type error. + * gfortran.dg/internal_pack_9.f90: Add -std=legacy. Add + warnings for type mismatch. + * gfortran.dg/pr39937.f: Add -std=legacy and type warnings. Move + here from + * gfortran.fortran-torture/compile/pr39937.f: Move to gfortran.dg. + 2019-08-24 Paolo Carlini * g++.dg/conversion/simd4.C: Test all the locations. diff --git a/gcc/testsuite/gfortran.dg/bessel_3.f90 b/gcc/testsuite/gfortran.dg/bessel_3.f90 index 271768d..05610ae 100644 --- a/gcc/testsuite/gfortran.dg/bessel_3.f90 +++ b/gcc/testsuite/gfortran.dg/bessel_3.f90 @@ -9,10 +9,10 @@ print *, SIN (1.0) print *, BESSEL_J0(1.0) ! { dg-error "has no IMPLICIT type" }) print *, BESSEL_J1(1.0) ! { dg-error "has no IMPLICIT type" } print *, BESSEL_JN(1,1.0) ! { dg-error "has no IMPLICIT type" } -print *, BESSEL_JN(1,2,1.0) ! { dg-error "has no IMPLICIT type" } +print *, BESSEL_JN(1,2,1.0) ! { dg-error "has no IMPLICIT type|Type mismatch" } print *, BESSEL_Y0(1.0) ! { dg-error "has no IMPLICIT type" } print *, BESSEL_Y1(1.0) ! { dg-error "has no IMPLICIT type" } print *, BESSEL_YN(1,1.0) ! { dg-error "has no IMPLICIT type" } -print *, BESSEL_YN(1,2,1.0) ! { dg-error "has no IMPLICIT type" } +print *, BESSEL_YN(1,2,1.0) ! { dg-error "has no IMPLICIT type|Type mismatch" } end diff --git a/gcc/testsuite/gfortran.dg/coarray_7.f90 b/gcc/testsuite/gfortran.dg/coarray_7.f90 index abbd64d..49482ef 100644 --- a/gcc/testsuite/gfortran.dg/coarray_7.f90 +++ b/gcc/testsuite/gfortran.dg/coarray_7.f90 @@ -50,9 +50,9 @@ program test call coarray(caf2) call coarray(caf2[1]) ! { dg-error "must be a coarray" } call ups(i) - call ups(i[1]) ! { dg-error "with ultimate pointer component" } - call ups(i%ptr) - call ups(i[1]%ptr) ! OK - passes target not pointer + call ups1(i[1]) ! { dg-error "with ultimate pointer component" } + call ups2(i%ptr) + call ups3(i[1]%ptr) ! OK - passes target not pointer contains subroutine asyn(a) integer, intent(in), asynchronous :: a diff --git a/gcc/testsuite/gfortran.dg/g77/20010519-1.f b/gcc/testsuite/gfortran.dg/g77/20010519-1.f index c268bf0..4cefb95 100644 --- a/gcc/testsuite/gfortran.dg/g77/20010519-1.f +++ b/gcc/testsuite/gfortran.dg/g77/20010519-1.f @@ -1,4 +1,5 @@ c { dg-do compile } +c { dg-options "-std=legacy" } CHARMM Element source/dimb/nmdimb.src 1.1 C.##IF DIMB SUBROUTINE NMDIMB(X,Y,Z,NAT3,BNBND,BIMAG,LNOMA,AMASS,DDS,DDSCR, @@ -711,19 +712,19 @@ C Begin 1 'NFREG IS LARGER THAN PARDIM*3') C C ALLOCATE-SPACE-FOR-TRANSROT-VECTORS - ASSIGN 801 TO I800 ! { dg-warning "Deleted feature: ASSIGN" "Deleted feature: ASSIGN" } + ASSIGN 801 TO I800 GOTO 800 801 CONTINUE C ALLOCATE-SPACE-FOR-DIAGONALIZATION - ASSIGN 721 TO I720 ! { dg-warning "Deleted feature: ASSIGN" "Deleted feature: ASSIGN" } + ASSIGN 721 TO I720 GOTO 720 721 CONTINUE C ALLOCATE-SPACE-FOR-REDUCED-BASIS - ASSIGN 761 TO I760 ! { dg-warning "Deleted feature: ASSIGN" "Deleted feature: ASSIGN" } + ASSIGN 761 TO I760 GOTO 760 761 CONTINUE C ALLOCATE-SPACE-FOR-OTHER-ARRAYS - ASSIGN 921 TO I920 ! { dg-warning "Deleted feature: ASSIGN" "Deleted feature: ASSIGN" } + ASSIGN 921 TO I920 GOTO 920 921 CONTINUE C @@ -731,12 +732,12 @@ C Space allocation for working arrays of EISPACK C diagonalization subroutines IF(LSCI) THEN C ALLOCATE-SPACE-FOR-LSCI - ASSIGN 841 TO I840 ! { dg-warning "Deleted feature: ASSIGN" "Deleted feature: ASSIGN" } + ASSIGN 841 TO I840 GOTO 840 841 CONTINUE ELSE C ALLOCATE-DUMMY-SPACE-FOR-LSCI - ASSIGN 881 TO I880 ! { dg-warning "Deleted feature: ASSIGN" "Deleted feature: ASSIGN" } + ASSIGN 881 TO I880 GOTO 880 881 CONTINUE ENDIF @@ -846,7 +847,7 @@ C Orthonormalize the eigenvectors C OLDPRN=PRNLEV PRNLEV=1 - CALL ORTHNM(1,NFRET,NFRET,DDV,NAT3,LPURG,TOLER) + CALL ORTHNM(1,NFRET,NFRET,DDV,NAT3,LPURG,TOLER) ! { dg-warning "Type mismatch" } PRNLEV=OLDPRN C C Do reduced basis diagonalization using the DDV vectors @@ -878,11 +879,11 @@ C C C DO-THE-DIAGONALISATIONS-WITH-RESIDUALS C - ASSIGN 621 TO I620 ! { dg-warning "Deleted feature: ASSIGN" "Deleted feature: ASSIGN" } + ASSIGN 621 TO I620 GOTO 620 621 CONTINUE C SAVE-MODES - ASSIGN 701 TO I700 ! { dg-warning "Deleted feature: ASSIGN" "Deleted feature: ASSIGN" } + ASSIGN 701 TO I700 GOTO 700 701 CONTINUE IF(ITER.EQ.ITMX) THEN @@ -1025,17 +1026,17 @@ C CALL PARTDS(NAT3,NPARC,ATMPAR,NPARS,ATMPAS,INIDS,NPARMX, 1 DDF,NFREG,CUTF1,PARDIM,NFCUT1) C DO-THE-DIAGONALISATIONS - ASSIGN 641 to I640 ! { dg-warning "Deleted feature: ASSIGN" "Deleted feature: ASSIGN" } + ASSIGN 641 to I640 GOTO 640 641 CONTINUE QDIAG=.FALSE. C DO-THE-DIAGONALISATIONS-WITH-RESIDUALS - ASSIGN 622 TO I620 ! { dg-warning "Deleted feature: ASSIGN" "Deleted feature: ASSIGN" } + ASSIGN 622 TO I620 GOTO 620 622 CONTINUE QDIAG=.TRUE. C SAVE-MODES - ASSIGN 702 TO I700 ! { dg-warning "Deleted feature: ASSIGN" "Deleted feature: ASSIGN" } + ASSIGN 702 TO I700 GOTO 700 702 CONTINUE C @@ -1048,7 +1049,7 @@ C ITER=ITER+1 IF(PRNLEV.GE.2) WRITE(OUTU,553) ITER C DO-THE-DWIN-DIAGONALISATIONS - ASSIGN 661 TO I660 ! { dg-warning "Deleted feature: ASSIGN" "Deleted feature: ASSIGN" } + ASSIGN 661 TO I660 GOTO 660 661 CONTINUE ENDIF @@ -1056,13 +1057,13 @@ C DO-THE-DWIN-DIAGONALISATIONS IRESF=0 QDIAG=.FALSE. C DO-THE-DIAGONALISATIONS-WITH-RESIDUALS - ASSIGN 623 TO I620 ! { dg-warning "Deleted feature: ASSIGN" "Deleted feature: ASSIGN" } + ASSIGN 623 TO I620 GOTO 620 623 CONTINUE QDIAG=.TRUE. IF((CVGMX.LE.TOLDIM).OR.(ITER.EQ.ITMX)) GOTO 600 C SAVE-MODES - ASSIGN 703 TO I700 ! { dg-warning "Deleted feature: ASSIGN" "Deleted feature: ASSIGN" } + ASSIGN 703 TO I700 GOTO 700 703 CONTINUE ENDIF @@ -1072,7 +1073,7 @@ C SAVE-MODES 600 CONTINUE C C SAVE-MODES - ASSIGN 704 TO I700 ! { dg-warning "Deleted feature: ASSIGN" "Deleted feature: ASSIGN" } + ASSIGN 704 TO I700 GOTO 700 704 CONTINUE CALL CLEANHP(NAT3,NFREG,NPARD,NSUBP,PARDIM,DDV2,DDSS,DDVBAS, @@ -1125,7 +1126,7 @@ C NFCUT=NFRET OLDPRN=PRNLEV PRNLEV=1 - CALL ORTHNM(1,NFRET,NFCUT,DDV,NAT3,LPURG,TOLER) + CALL ORTHNM(1,NFRET,NFCUT,DDV,NAT3,LPURG,TOLER) ! { dg-warning "Type mismatch" } PRNLEV=OLDPRN NFRET=NFCUT IF(PRNLEV.GE.2) WRITE(OUTU,568) NFRET @@ -1150,7 +1151,7 @@ C 6 HEAP(BDRATQ),HEAP(INRATQ),LSCI,LBIG,IUNMOD) CALL SELNMD(DDF,NFRET,CUTF1,NFCUT1) ENDIF - GOTO I620 ! { dg-warning "Deleted feature: Assigned" "Assigned GO TO" } + GOTO I620 C C----------------------------------------------------------------------- C TO DO-THE-DIAGONALISATIONS @@ -1173,7 +1174,7 @@ C TO DO-THE-DIAGONALISATIONS NFSAV=NFCUT1 OLDPRN=PRNLEV PRNLEV=1 - CALL ORTHNM(1,NFCUT1,NFCUT,DDV,NAT3,LPURG,TOLER) + CALL ORTHNM(1,NFCUT1,NFCUT,DDV,NAT3,LPURG,TOLER) ! { dg-warning "Type mismatch" } PRNLEV=OLDPRN CALL CPARAY(HEAP(DDVBAS),DDV,NAT3,1,NFCUT,1) NFRET=NDIM+NFCUT @@ -1190,7 +1191,7 @@ C TO DO-THE-DIAGONALISATIONS NFCUT1=NFCUT NFRET=NFCUT ENDDO - GOTO I640 ! { dg-warning "Deleted feature: Assigned" "Assigned GO TO" } + GOTO I640 C C----------------------------------------------------------------------- C TO DO-THE-DWIN-DIAGONALISATIONS @@ -1223,7 +1224,7 @@ C CALL ADZERD(DDV,1,NFCUT1,NAT3,IS1,IS2,IS3,IS4) OLDPRN=PRNLEV PRNLEV=1 - CALL ORTHNM(1,NFCUT1,NFCUT,DDV,NAT3,LPURG,TOLER) + CALL ORTHNM(1,NFCUT1,NFCUT,DDV,NAT3,LPURG,TOLER) ! { dg-warning "Type mismatch" } PRNLEV=OLDPRN CALL CPARAY(HEAP(DDVBAS),DDV,NAT3,1,NFCUT,1) C @@ -1241,7 +1242,7 @@ C IF(NFCUT.GT.NFRRES) NFCUT=NFRRES NFCUT1=NFCUT NFRET=NFCUT - GOTO I660 ! { dg-warning "Deleted feature: Assigned" "Assigned GO TO" } + GOTO I660 C C----------------------------------------------------------------------- C TO SAVE-MODES @@ -1258,7 +1259,7 @@ C TO SAVE-MODES CALL WRTNMD(LCARD,ISTRT,ISTOP,NAT3,DDV,DDSCR,DDEV,IUNMOD, 1 AMASS) CALL SAVEIT(IUNMOD) - GOTO I700 ! { dg-warning "Deleted feature: Assigned" "Assigned GO TO" } + GOTO I700 C C----------------------------------------------------------------------- C TO ALLOCATE-SPACE-FOR-DIAGONALIZATION @@ -1269,7 +1270,7 @@ C TO ALLOCATE-SPACE-FOR-DIAGONALIZATION JSPACE=JSPACE+JSP DDSS=ALLHP(JSPACE) DD5=DDSS+JSPACE-JSP - GOTO I720 ! { dg-warning "Deleted feature: Assigned" "Assigned GO TO" } + GOTO I720 C C----------------------------------------------------------------------- C TO ALLOCATE-SPACE-FOR-REDUCED-BASIS @@ -1279,13 +1280,13 @@ C TO ALLOCATE-SPACE-FOR-REDUCED-BASIS ELSE DDVBAS=ALLHP(IREAL8(NFREG*NAT3)) ENDIF - GOTO I760 ! { dg-warning "Deleted feature: Assigned" "Assigned GO TO" } + GOTO I760 C C----------------------------------------------------------------------- C TO ALLOCATE-SPACE-FOR-TRANSROT-VECTORS 800 CONTINUE TRAROT=ALLHP(IREAL8(6*NAT3)) - GOTO I800 ! { dg-warning "Deleted feature: Assigned" "Assigned GO TO" } + GOTO I800 C C----------------------------------------------------------------------- C TO ALLOCATE-SPACE-FOR-LSCI @@ -1300,7 +1301,7 @@ C TO ALLOCATE-SPACE-FOR-LSCI E2RATQ=ALLHP(IREAL8(PARDIM+3)) BDRATQ=ALLHP(IREAL8(PARDIM+3)) INRATQ=ALLHP(INTEG4(PARDIM+3)) - GOTO I840 ! { dg-warning "Deleted feature: Assigned" "Assigned GO TO" } + GOTO I840 C C----------------------------------------------------------------------- C TO ALLOCATE-DUMMY-SPACE-FOR-LSCI @@ -1315,13 +1316,13 @@ C TO ALLOCATE-DUMMY-SPACE-FOR-LSCI E2RATQ=ALLHP(IREAL8(2)) BDRATQ=ALLHP(IREAL8(2)) INRATQ=ALLHP(INTEG4(2)) - GOTO I880 ! { dg-warning "Deleted feature: Assigned" "Assigned GO TO" } + GOTO I880 C C----------------------------------------------------------------------- C TO ALLOCATE-SPACE-FOR-OTHER-ARRAYS 920 CONTINUE IUPD=ALLHP(INTEG4(PARDIM+3)) - GOTO I920 ! { dg-warning "Deleted feature: Assigned" "Assigned GO TO" } + GOTO I920 C.##ELSE C.##ENDIF END diff --git a/gcc/testsuite/gfortran.dg/goacc/acc_on_device-1.f95 b/gcc/testsuite/gfortran.dg/goacc/acc_on_device-1.f95 index 79dc731..e204b53 100644 --- a/gcc/testsuite/gfortran.dg/goacc/acc_on_device-1.f95 +++ b/gcc/testsuite/gfortran.dg/goacc/acc_on_device-1.f95 @@ -1,5 +1,5 @@ ! Have to enable optimizations, as otherwise builtins won't be expanded. -! { dg-additional-options "-O -fdump-rtl-expand" } +! { dg-additional-options "-O -fdump-rtl-expand -std=legacy" } logical function f () implicit none @@ -9,7 +9,7 @@ logical function f () f = .false. f = f .or. acc_on_device () - f = f .or. acc_on_device (1, 2) + f = f .or. acc_on_device (1, 2) ! { dg-warning ".*" } f = f .or. acc_on_device (3.14) f = f .or. acc_on_device ("hello") diff --git a/gcc/testsuite/gfortran.dg/internal_pack_9.f90 b/gcc/testsuite/gfortran.dg/internal_pack_9.f90 index 2b44db5..568b42c 100644 --- a/gcc/testsuite/gfortran.dg/internal_pack_9.f90 +++ b/gcc/testsuite/gfortran.dg/internal_pack_9.f90 @@ -10,9 +10,9 @@ ! Case 1: Substring encompassing the whole string subroutine foo2 implicit none - external foo + external foo_char character(len=20) :: str(2) = '1234567890' - call foo(str(:)(1:20)) ! This is still not fixed. + call foo_char (str(:)(1:20)) ! This is still not fixed. end ! Case 2: Contiguous array section diff --git a/gcc/testsuite/gfortran.dg/pr24823.f b/gcc/testsuite/gfortran.dg/pr24823.f index 1b6f448..bb63c41 100644 --- a/gcc/testsuite/gfortran.dg/pr24823.f +++ b/gcc/testsuite/gfortran.dg/pr24823.f @@ -1,5 +1,5 @@ ! { dg-do compile } -! { dg-options "-O2" } +! { dg-options "-O2 -std=legacy" } ! PR24823 Flow didn't handle a PARALLEL as destination of a SET properly. SUBROUTINE ZLATMR( M, N, DIST, ISEED, SYM, D, MODE, COND, DMAX, $ RSIGN, GRADE, DL, MODEL, CONDL, DR, MODER, @@ -52,7 +52,7 @@ A( J-I+1, I ) = DCONJG( ZLATM2( M, N, I, J, KL, $ DR, IPVTNG, IWORK, SPARSE ) ) ELSE - A( J-I+1, I ) = ZLATM2( M, N, I, J, KL, KU, + A( J-I+1, I ) = ZLATM2( M, N, I, J, KL, KU, ! { dg-warning "Type mismatch" } $ IPVTNG, IWORK, SPARSE ) END IF END IF @@ -61,7 +61,7 @@ IF( ISYM.EQ.0 ) THEN END IF END IF - A( I-J+KUU+1, J ) = ZLATM2( M, N, I, J, KL, KU, + A( I-J+KUU+1, J ) = ZLATM2( M, N, I, J, KL, KU, ! { dg-warning "Type mismatch" } $ DR, IPVTNG, IWORK, SPARSE ) END IF END IF diff --git a/gcc/testsuite/gfortran.dg/pr39937.f b/gcc/testsuite/gfortran.dg/pr39937.f new file mode 100644 index 0000000..1ab22ee --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr39937.f @@ -0,0 +1,30 @@ +C { dg-do compile } +C { dg-options "-std=legacy" } + SUBROUTINE DTREVC( SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR, + $ LDVR, MM, M, WORK, INFO ) + DOUBLE PRECISION T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ), + $ WORK( * ) + DOUBLE PRECISION X( 2, 2 ) + CALL DLALN2( .FALSE., 1, 1, SMIN, ONE, T( J, J ), + $ ZERO, X, 2, SCALE, XNORM, IERR ) + CALL DSCAL( KI, SCALE, WORK( 1+N ), 1 ) + DO 90 J = KI - 2, 1, -1 + IF( J.GT.JNXT ) + $ GO TO 90 + JNXT = J - 1 + IF( J.GT.1 ) THEN + IF( T( J, J-1 ).NE.ZERO ) THEN + IF( WORK( J ).GT.BIGNUM / XNORM ) THEN + X( 1, 1 ) = X( 1, 1 ) / XNORM + END IF + END IF + CALL DLALN2( .FALSE., 2, 2, SMIN, ONE, + $ T( J-1, J-1 ), LDT, ONE, ONE, + $ XNORM, IERR ) ! { dg-warning "Type mismatch" } + CALL DAXPY( J-2, -X( 1, 1 ), T( 1, J-1 ), 1, + $ WORK( 1+N ), 1 ) + CALL DAXPY( J-2, -X( 2, 2 ), T( 1, J ), 1, + $ WORK( 1+N2 ), 1 ) + END IF + 90 CONTINUE + END diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/pr39937.f b/gcc/testsuite/gfortran.fortran-torture/compile/pr39937.f deleted file mode 100644 index 5ead135..0000000 --- a/gcc/testsuite/gfortran.fortran-torture/compile/pr39937.f +++ /dev/null @@ -1,28 +0,0 @@ - SUBROUTINE DTREVC( SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR, - $ LDVR, MM, M, WORK, INFO ) - DOUBLE PRECISION T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ), - $ WORK( * ) - DOUBLE PRECISION X( 2, 2 ) - CALL DLALN2( .FALSE., 1, 1, SMIN, ONE, T( J, J ), - $ ZERO, X, 2, SCALE, XNORM, IERR ) - CALL DSCAL( KI, SCALE, WORK( 1+N ), 1 ) - DO 90 J = KI - 2, 1, -1 - IF( J.GT.JNXT ) - $ GO TO 90 - JNXT = J - 1 - IF( J.GT.1 ) THEN - IF( T( J, J-1 ).NE.ZERO ) THEN - IF( WORK( J ).GT.BIGNUM / XNORM ) THEN - X( 1, 1 ) = X( 1, 1 ) / XNORM - END IF - END IF - CALL DLALN2( .FALSE., 2, 2, SMIN, ONE, - $ T( J-1, J-1 ), LDT, ONE, ONE, - $ XNORM, IERR ) - CALL DAXPY( J-2, -X( 1, 1 ), T( 1, J-1 ), 1, - $ WORK( 1+N ), 1 ) - CALL DAXPY( J-2, -X( 2, 2 ), T( 1, J ), 1, - $ WORK( 1+N2 ), 1 ) - END IF - 90 CONTINUE - END -- cgit v1.1 From 6dfc1e1f33a0b9cdbff194e02b94b8a1a69d1425 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Sat, 24 Aug 2019 22:44:06 +0000 Subject: [C++ PATCH] vfunc overrider simplification https://gcc.gnu.org/ml/gcc-patches/2019-08/msg01674.html cp/ * class.c (check_for_overrides): Conversion operators need checking too. testsuite/ * g++.dg/inherit/virtual14.C: New. From-SVN: r274903 --- gcc/cp/ChangeLog | 9 +++++++-- gcc/cp/class.c | 10 ++++++---- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/g++.dg/inherit/virtual14.C | 24 ++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/g++.dg/inherit/virtual14.C (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d0a8c77..013de12 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,13 +1,18 @@ +2019-08-24 Nathan Sidwell + + * class.c (check_for_overrides): Conversion operators need + checking too. + 2019-08-24 Paolo Carlini * semantics.c (finish_switch_cond): Improve error message location. -2019-08-22 Jason Merrill +2019-08-23 Jason Merrill * decl2.c (decl_dependent_p): New. (mark_used): Check it instead of just processing_template_decl. -2019-08-22 Jason Merrill +2019-08-23 Jason Merrill * parser.c (cp_parser_nested_name_specifier_opt): Avoid redundant error. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 99332f4..47350c2 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -2817,10 +2817,12 @@ check_for_override (tree decl, tree ctype) return; /* IDENTIFIER_VIRTUAL_P indicates whether the name has ever been - used for a vfunc. That avoids the expensive - look_for_overrides call that when we know there's nothing to - find. */ - if (IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) + used for a vfunc. That avoids the expensive look_for_overrides + call that when we know there's nothing to find. As conversion + operators for the same type can have distinct identifiers, we + cannot optimize those in that way. */ + if ((IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) + || DECL_CONV_FN_P (decl)) && look_for_overrides (ctype, decl) /* Check staticness after we've checked if we 'override'. */ && !DECL_STATIC_FUNCTION_P (decl)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index efb0157..08e48c3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-08-24 Nathan Sidwell + + * g++.dg/inherit/virtual14.C: New. + 2019-08-24 Thomas Koenig PR fortran/91390 diff --git a/gcc/testsuite/g++.dg/inherit/virtual14.C b/gcc/testsuite/g++.dg/inherit/virtual14.C new file mode 100644 index 0000000..17aabf3 --- /dev/null +++ b/gcc/testsuite/g++.dg/inherit/virtual14.C @@ -0,0 +1,24 @@ +// { dg-do run } + +struct base +{ + virtual operator int () { return 0;} +}; + +typedef int q; + +struct d : base +{ + operator q () { return 1; } +}; + +int invoke (base *d) +{ + return int (*d); +} + +int main () +{ + d d; + return !(invoke (&d) == 1); +} -- cgit v1.1 From fed7268f740acb6c74d3925c72d6f584c22812f8 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sun, 25 Aug 2019 00:16:50 +0000 Subject: Daily bump. From-SVN: r274907 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 77db483..6ed2a6c 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20190824 +20190825 -- cgit v1.1 From 1460c0bbb7fbb9f4a019d1d97cdc2bb79c9e2833 Mon Sep 17 00:00:00 2001 From: Gerald Pfeifer Date: Sun, 25 Aug 2019 22:25:23 +0000 Subject: gmm_malloc.h: Only use and errno if __STDC_HOSTED__. * config/i386/gmm_malloc.h: Only use and errno if __STDC_HOSTED__. From-SVN: r274915 --- gcc/ChangeLog | 5 +++++ gcc/config/i386/gmm_malloc.h | 4 ++++ 2 files changed, 9 insertions(+) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 989dff7..f751920 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-08-26 Gerald Pfeifer + + * config/i386/gmm_malloc.h: Only use and errno if + __STDC_HOSTED__. + 2019-08-23 Mihailo Stojanovic * config/mips/mips.md (mips_get_fcsr, *mips_get_fcsr): Use SI diff --git a/gcc/config/i386/gmm_malloc.h b/gcc/config/i386/gmm_malloc.h index b988655..cfe6046 100644 --- a/gcc/config/i386/gmm_malloc.h +++ b/gcc/config/i386/gmm_malloc.h @@ -25,7 +25,9 @@ #define _MM_MALLOC_H_INCLUDED #include +#if __STDC_HOSTED__ #include +#endif static __inline__ void * _mm_malloc (size_t __size, size_t __align) @@ -36,7 +38,9 @@ _mm_malloc (size_t __size, size_t __align) /* Error if align is not a power of two. */ if (__align & (__align - 1)) { +#if __STDC_HOSTED__ errno = EINVAL; +#endif return ((void *) 0); } -- cgit v1.1 From 900af77fc2cd68e9bc7f5acbc50df44ae97f0a78 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Mon, 26 Aug 2019 00:16:48 +0000 Subject: Daily bump. From-SVN: r274919 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 6ed2a6c..07f9b34 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20190825 +20190826 -- cgit v1.1 From 20e7012b755427d1db00ba6f236583ff3c24e710 Mon Sep 17 00:00:00 2001 From: Kito Cheng Date: Mon, 26 Aug 2019 02:15:47 +0000 Subject: RISC-V: Add testcase for testing li pseudo instruction gcc/testsuite/ChangeLog: gcc.target/riscv/li.c: New test. From-SVN: r274920 --- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.target/riscv/li.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/li.c (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 08e48c3..dd4d9b7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-08-26 Kito Cheng + + * gcc.target/riscv/li.c: New test. + 2019-08-24 Nathan Sidwell * g++.dg/inherit/virtual14.C: New. diff --git a/gcc/testsuite/gcc.target/riscv/li.c b/gcc/testsuite/gcc.target/riscv/li.c new file mode 100644 index 0000000..fa5c02c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/li.c @@ -0,0 +1,36 @@ +/* { dg-do run } */ +/* { dg-options "-O1" } */ +#include +#define LOAD_IMM(var, val) \ + asm ("li %0, %1\n": "=r"(var): "i" (val)) + +#define CHECK_LI(type, val) \ + { \ + type var; \ + LOAD_IMM(var, val); \ + if (var != val) \ + abort(); \ + } + +#define CHECK_LI32(val) CHECK_LI(int, val) +#define CHECK_LI64(val) CHECK_LI(long long, val) + +int main() +{ + CHECK_LI32(0x8001); + CHECK_LI32(0x1f01); + CHECK_LI32(0x12345001); + CHECK_LI32(0xf2345001); +#if __riscv_xlen == 64 + CHECK_LI64(0x8001ll); + CHECK_LI64(0x1f01ll); + CHECK_LI64(0x12345001ll); + CHECK_LI64(0xf2345001ll); + CHECK_LI64(0xf12345001ll); + CHECK_LI64(0xff00ff00ff001f01ll); + CHECK_LI64(0x7ffffffff2345001ll); + CHECK_LI64(0x7f0f243ff2345001ll); + CHECK_LI64(0x1234567887654321ll); +#endif + return 0; +} -- cgit v1.1 From bf05a3bbb58b355899ccabe861a06e85b7abe6e4 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 26 Aug 2019 09:29:07 +0000 Subject: re PR c/91526 (Unnecessary SSE and other instructions generated when compiling in C mode (vs. C++ mode)) 2019-08-26 Richard Biener PR tree-optimization/91526 * passes.def: Note that after late FRE we do TODO_update_address_taken. * tree-ssa-sccvn.c (pass_fre::execute): In late mode schedule TODO_update_address_taken. From-SVN: r274922 --- gcc/ChangeLog | 7 +++++++ gcc/passes.def | 2 ++ gcc/tree-ssa-sccvn.c | 5 +++++ 3 files changed, 14 insertions(+) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f751920..705c993 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2019-08-26 Richard Biener + + PR tree-optimization/91526 + * passes.def: Note that after late FRE we do TODO_update_address_taken. + * tree-ssa-sccvn.c (pass_fre::execute): In late mode schedule + TODO_update_address_taken. + 2019-08-26 Gerald Pfeifer * config/i386/gmm_malloc.h: Only use and errno if diff --git a/gcc/passes.def b/gcc/passes.def index 1a7fd14..fe5a411 100644 --- a/gcc/passes.def +++ b/gcc/passes.def @@ -313,6 +313,8 @@ along with GCC; see the file COPYING3. If not see NEXT_PASS (pass_split_paths); NEXT_PASS (pass_tracer); NEXT_PASS (pass_fre, false /* may_iterate */); + /* After late FRE we rewrite no longer addressed locals into SSA + form if possible. */ NEXT_PASS (pass_thread_jumps); NEXT_PASS (pass_dominator, false /* may_peel_loop_headers_p */); NEXT_PASS (pass_strlen); diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 76cad43..336a7c7 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -7312,6 +7312,11 @@ pass_fre::execute (function *fun) if (iterate_p) loop_optimizer_finalize (); + /* For late FRE after IVOPTs and unrolling, see if we can + remove some TREE_ADDRESSABLE and rewrite stuff into SSA. */ + if (!may_iterate) + todo |= TODO_update_address_taken; + return todo; } -- cgit v1.1 From e944354ec05891474b0d204c6c239c04ee7b527b Mon Sep 17 00:00:00 2001 From: Robin Dapp Date: Mon, 26 Aug 2019 10:18:24 +0000 Subject: [PATCH 1/2] Allow folding all statements. This patch allows users of the substitute_and_fold_engine to enable folding all statements. It is now enabled for VRP which is needed for the match.pd pattern in patch 2/2. The loop versioning pass was missing one case when deconstructing addresses that would only be triggered after this patch for me: It could handle addition and subsequent convert/nop but not a convert/nop directly. This would cause the hash to be calculated differently and, in turn, cause the pass to miss a versioning opportunity. Fixed this by adding the missing case. -- gcc/ChangeLog: 2019-08-26 Robin Dapp * gimple-loop-versioning.cc (loop_versioning::record_address_fragment): Add nop_convert case. * tree-ssa-propagate.c (substitute_and_fold_dom_walker::before_dom_children): Fold all statements if requested. * tree-ssa-propagate.h (class substitute_and_fold_engine): Allow to fold all statements. * tree-vrp.c (class vrp_folder): Let substitute_and_fold_engine fold all statements. From-SVN: r274923 --- gcc/ChangeLog | 11 +++++++++++ gcc/gimple-loop-versioning.cc | 6 ++++++ gcc/tree-ssa-propagate.c | 9 ++++++++- gcc/tree-ssa-propagate.h | 6 ++++++ gcc/tree-vrp.c | 1 + 5 files changed, 32 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 705c993..f5acb32 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2019-08-26 Robin Dapp + + * gimple-loop-versioning.cc (loop_versioning::record_address_fragment): + Add nop_convert case. + * tree-ssa-propagate.c (substitute_and_fold_dom_walker::before_dom_children): + Fold all statements if requested. + * tree-ssa-propagate.h (class substitute_and_fold_engine): + Allow to fold all statements. + * tree-vrp.c (class vrp_folder): + Let substitute_and_fold_engine fold all statements. + 2019-08-26 Richard Biener PR tree-optimization/91526 diff --git a/gcc/gimple-loop-versioning.cc b/gcc/gimple-loop-versioning.cc index 8fa1948..35344b7 100644 --- a/gcc/gimple-loop-versioning.cc +++ b/gcc/gimple-loop-versioning.cc @@ -1266,6 +1266,12 @@ loop_versioning::record_address_fragment (gimple *stmt, continue; } } + if (CONVERT_EXPR_CODE_P (code)) + { + tree op1 = gimple_assign_rhs1 (assign); + address->terms[i].expr = strip_casts (op1); + continue; + } } i += 1; } diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c index 0862f83..7172ef8 100644 --- a/gcc/tree-ssa-propagate.c +++ b/gcc/tree-ssa-propagate.c @@ -814,7 +814,6 @@ ssa_propagation_engine::ssa_propagate (void) ssa_prop_fini (); } - /* Return true if STMT is of the form 'mem_ref = RHS', where 'mem_ref' is a non-volatile pointer dereference, a structure reference or a reference to a single _DECL. Ignore volatile memory references @@ -1071,6 +1070,14 @@ substitute_and_fold_dom_walker::before_dom_children (basic_block bb) stmt = gsi_stmt (i); gimple_set_modified (stmt, true); } + /* Also fold if we want to fold all statements. */ + else if (substitute_and_fold_engine->fold_all_stmts + && fold_stmt (&i, follow_single_use_edges)) + { + did_replace = true; + stmt = gsi_stmt (i); + gimple_set_modified (stmt, true); + } /* Some statements may be simplified using propagator specific information. Do this before propagating diff --git a/gcc/tree-ssa-propagate.h b/gcc/tree-ssa-propagate.h index 81b635e..f79c2ff 100644 --- a/gcc/tree-ssa-propagate.h +++ b/gcc/tree-ssa-propagate.h @@ -100,6 +100,8 @@ class ssa_propagation_engine class substitute_and_fold_engine { public: + substitute_and_fold_engine (bool fold_all_stmts = false) + : fold_all_stmts (fold_all_stmts) { } virtual ~substitute_and_fold_engine (void) { } virtual bool fold_stmt (gimple_stmt_iterator *) { return false; } virtual tree get_value (tree) { return NULL_TREE; } @@ -107,6 +109,10 @@ class substitute_and_fold_engine bool substitute_and_fold (basic_block = NULL); bool replace_uses_in (gimple *); bool replace_phi_args_in (gphi *); + + /* Users like VRP can set this when they want to perform + folding for every propagation. */ + bool fold_all_stmts; }; #endif /* _TREE_SSA_PROPAGATE_H */ diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 8067f85..4145bcc 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -6415,6 +6415,7 @@ vrp_prop::visit_phi (gphi *phi) class vrp_folder : public substitute_and_fold_engine { public: + vrp_folder () : substitute_and_fold_engine (/* Fold all stmts. */ true) { } tree get_value (tree) FINAL OVERRIDE; bool fold_stmt (gimple_stmt_iterator *) FINAL OVERRIDE; bool fold_predicate_in (gimple_stmt_iterator *); -- cgit v1.1 From df7d46d925c7baca7bf9961aee900876d8aef225 Mon Sep 17 00:00:00 2001 From: Robin Dapp Date: Mon, 26 Aug 2019 10:24:44 +0000 Subject: [PATCH 2/2] Add simplify rule for wrapped addition. Add the transform (T)(A) + CST -> (T)(A + CST). This enables vrp to simplify sequences like _2 = a_7 - 1; _3 = (long unsigned int) _2; _5 = _3 + 1 that ivopts creates. -- gcc/ChangeLog: 2019-08-26 Robin Dapp * match.pd: Add (T)(A) + CST -> (T)(A + CST). gcc/testsuite/ChangeLog: 2019-08-26 Robin Dapp * gcc.dg/tree-ssa/copy-headers-5.c: Do not run vrp pass. * gcc.dg/tree-ssa/copy-headers-7.c: Do not run vrp pass. * gcc.dg/tree-ssa/loop-15.c: Remove XFAIL. * gcc.dg/tree-ssa/pr23744.c: Change search pattern. * gcc.dg/wrapped-binop-simplify.c: New test. From-SVN: r274925 --- gcc/ChangeLog | 4 +++ gcc/match.pd | 31 +++++++++++++++++++ gcc/testsuite/ChangeLog | 8 +++++ gcc/testsuite/gcc.dg/tree-ssa/copy-headers-5.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/copy-headers-7.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/loop-15.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/pr23744.c | 4 +-- gcc/testsuite/gcc.dg/wrapped-binop-simplify.c | 43 ++++++++++++++++++++++++++ 8 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/wrapped-binop-simplify.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f5acb32..abccd69 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,9 @@ 2019-08-26 Robin Dapp + * match.pd: Add (T)(A) + CST -> (T)(A + CST). + +2019-08-26 Robin Dapp + * gimple-loop-versioning.cc (loop_versioning::record_address_fragment): Add nop_convert case. * tree-ssa-propagate.c (substitute_and_fold_dom_walker::before_dom_children): diff --git a/gcc/match.pd b/gcc/match.pd index 93dcef9..13e41a9 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -2022,6 +2022,37 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (cst && !TREE_OVERFLOW (cst)) (plus { cst; } @0)))) +/* ((T)(A)) + CST -> (T)(A + CST) */ +#if GIMPLE + (simplify + (plus (convert SSA_NAME@0) INTEGER_CST@1) + (if (TREE_CODE (TREE_TYPE (@0)) == INTEGER_TYPE + && TREE_CODE (type) == INTEGER_TYPE + && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (@0)) + && int_fits_type_p (@1, TREE_TYPE (@0))) + /* Perform binary operation inside the cast if the constant fits + and (A + CST)'s range does not overflow. */ + (with + { + wi::overflow_type min_ovf = wi::OVF_OVERFLOW, + max_ovf = wi::OVF_OVERFLOW; + tree inner_type = TREE_TYPE (@0); + + wide_int w1 = wide_int::from (wi::to_wide (@1), TYPE_PRECISION (inner_type), + TYPE_SIGN (inner_type)); + + wide_int wmin0, wmax0; + if (get_range_info (@0, &wmin0, &wmax0) == VR_RANGE) + { + wi::add (wmin0, w1, TYPE_SIGN (inner_type), &min_ovf); + wi::add (wmax0, w1, TYPE_SIGN (inner_type), &max_ovf); + } + } + (if (min_ovf == wi::OVF_NONE && max_ovf == wi::OVF_NONE) + (convert (plus @0 { wide_int_to_tree (TREE_TYPE (@0), w1); } ))) + ))) +#endif + /* ~A + A -> -1 */ (simplify (plus:c (bit_not @0) @0) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index dd4d9b7..c7bf9cc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2019-08-26 Robin Dapp + + * gcc.dg/tree-ssa/copy-headers-5.c: Do not run vrp pass. + * gcc.dg/tree-ssa/copy-headers-7.c: Do not run vrp pass. + * gcc.dg/tree-ssa/loop-15.c: Remove XFAIL. + * gcc.dg/tree-ssa/pr23744.c: Change search pattern. + * gcc.dg/wrapped-binop-simplify.c: New test. + 2019-08-26 Kito Cheng * gcc.target/riscv/li.c: New test. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-5.c b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-5.c index 3d99405..42e0ed9 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-5.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-5.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-ch2-details" } */ +/* { dg-options "-O2 -fno-tree-vrp -fdump-tree-ch2-details" } */ int is_sorted(int *a, int n) { diff --git a/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-7.c b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-7.c index a0a6e6a..3c9b380 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-7.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-7.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-ch2-details --param logical-op-non-short-circuit=0" } */ +/* { dg-options "-O2 -fno-tree-vrp -fdump-tree-ch2-details --param logical-op-non-short-circuit=0" } */ int is_sorted(int *a, int n, int m, int k) { diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-15.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-15.c index b437518..dce6ad5 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/loop-15.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-15.c @@ -19,7 +19,7 @@ int bla(void) } /* Since the loop is removed, there should be no addition. */ -/* { dg-final { scan-tree-dump-times " \\+ " 0 "optimized" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-times " \\+ " 0 "optimized" } } */ /* { dg-final { scan-tree-dump-times " \\* " 1 "optimized" } } */ /* The if from the loop header copying remains in the code. */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr23744.c b/gcc/testsuite/gcc.dg/tree-ssa/pr23744.c index 3385aa1..ba3fda3 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr23744.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr23744.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fno-tree-ccp -fdisable-tree-evrp -fdump-tree-vrp1" } */ +/* { dg-options "-O2 -fno-tree-ccp -fdisable-tree-evrp -fdump-tree-vrp1-details" } */ void h (void); @@ -17,4 +17,4 @@ int g (int i, int j) return 1; } -/* { dg-final { scan-tree-dump-times "Folding predicate.*to 1" 1 "vrp1" } } */ +/* { dg-final { scan-tree-dump-times "gimple_simplified" 1 "vrp1" } } */ diff --git a/gcc/testsuite/gcc.dg/wrapped-binop-simplify.c b/gcc/testsuite/gcc.dg/wrapped-binop-simplify.c new file mode 100644 index 0000000..44d85c0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/wrapped-binop-simplify.c @@ -0,0 +1,43 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-vrp2-details" } */ +/* { dg-final { scan-tree-dump-times "gimple_simplified to" 4 "vrp2" } } */ + +void v1 (unsigned long *in, unsigned long *out, unsigned int n) +{ + int i; + + for (i = 0; i < n; i++) + { + out[i] = in[i]; + } +} + +void v2 (unsigned long *in, unsigned long *out, int n) +{ + int i; + + for (i = 0; i < n; i++) + { + out[i] = in[i]; + } +} + +void v3 (unsigned long *in, unsigned long *out, unsigned int n) +{ + unsigned int i; + + for (i = 0; i < n; i++) + { + out[i] = in[i]; + } +} + +void v4 (unsigned long *in, unsigned long *out, int n) +{ + unsigned int i; + + for (i = 0; i < n; i++) + { + out[i] = in[i]; + } +} -- cgit v1.1 From 48a31a09839b12127ce7c40d7adc4bd5bf1d3407 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 26 Aug 2019 10:35:59 +0000 Subject: re PR target/91522 (STV is slow) 2019-08-26 Richard Biener PR target/91522 PR target/91527 * config/i386/i386-features.h (general_scalar_chain::defs_map): New member. (general_scalar_chain::replace_with_subreg): Remove. (general_scalar_chain::replace_with_subreg_in_insn): Likewise. (general_scalar_chain::convert_reg): Adjust signature. * config/i386/i386-features.c (scalar_chain::add_insn): Do not iterate over all defs of a reg. (general_scalar_chain::replace_with_subreg): Remove. (general_scalar_chain::replace_with_subreg_in_insn): Likewise. (general_scalar_chain::make_vector_copies): Populate defs_map, place copy only after defs that are used as vectors in the chain. (general_scalar_chain::convert_reg): Emit a copy for a specific def in a specific instruction. (general_scalar_chain::convert_op): All reg uses are converted here. (general_scalar_chain::convert_insn): Emit copies for scalar uses of defs here. Replace uses with the copies we created. Replace and convert the def. Adjust REG_DEAD notes, remove REG_EQUIV/EQUAL notes. (general_scalar_chain::convert_registers): Only handle copies into the chain here. From-SVN: r274926 --- gcc/ChangeLog | 25 +++ gcc/config/i386/i386-features.c | 419 +++++++++++++++++----------------------- gcc/config/i386/i386-features.h | 5 +- 3 files changed, 200 insertions(+), 249 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index abccd69..f4e2919 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,28 @@ +2019-08-26 Richard Biener + + PR target/91522 + PR target/91527 + * config/i386/i386-features.h (general_scalar_chain::defs_map): + New member. + (general_scalar_chain::replace_with_subreg): Remove. + (general_scalar_chain::replace_with_subreg_in_insn): Likewise. + (general_scalar_chain::convert_reg): Adjust signature. + * config/i386/i386-features.c (scalar_chain::add_insn): Do not + iterate over all defs of a reg. + (general_scalar_chain::replace_with_subreg): Remove. + (general_scalar_chain::replace_with_subreg_in_insn): Likewise. + (general_scalar_chain::make_vector_copies): Populate defs_map, + place copy only after defs that are used as vectors in the chain. + (general_scalar_chain::convert_reg): Emit a copy for a specific + def in a specific instruction. + (general_scalar_chain::convert_op): All reg uses are converted here. + (general_scalar_chain::convert_insn): Emit copies for scalar + uses of defs here. Replace uses with the copies we created. + Replace and convert the def. Adjust REG_DEAD notes, remove + REG_EQUIV/EQUAL notes. + (general_scalar_chain::convert_registers): Only handle copies + into the chain here. + 2019-08-26 Robin Dapp * match.pd: Add (T)(A) + CST -> (T)(A + CST). diff --git a/gcc/config/i386/i386-features.c b/gcc/config/i386/i386-features.c index fb7ac1b..b70757e 100644 --- a/gcc/config/i386/i386-features.c +++ b/gcc/config/i386/i386-features.c @@ -416,13 +416,9 @@ scalar_chain::add_insn (bitmap candidates, unsigned int insn_uid) iterates over all refs to look for dual-mode regs. Instead this should be done separately for all regs mentioned in the chain once. */ df_ref ref; - df_ref def; for (ref = DF_INSN_UID_DEFS (insn_uid); ref; ref = DF_REF_NEXT_LOC (ref)) if (!HARD_REGISTER_P (DF_REF_REG (ref))) - for (def = DF_REG_DEF_CHAIN (DF_REF_REGNO (ref)); - def; - def = DF_REF_NEXT_REG (def)) - analyze_register_chain (candidates, def); + analyze_register_chain (candidates, ref); for (ref = DF_INSN_UID_USES (insn_uid); ref; ref = DF_REF_NEXT_LOC (ref)) if (!DF_REF_REG_MEM_P (ref)) analyze_register_chain (candidates, ref); @@ -605,42 +601,6 @@ general_scalar_chain::compute_convert_gain () return gain; } -/* Replace REG in X with a V2DI subreg of NEW_REG. */ - -rtx -general_scalar_chain::replace_with_subreg (rtx x, rtx reg, rtx new_reg) -{ - if (x == reg) - return gen_rtx_SUBREG (vmode, new_reg, 0); - - /* But not in memory addresses. */ - if (MEM_P (x)) - return x; - - const char *fmt = GET_RTX_FORMAT (GET_CODE (x)); - int i, j; - for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--) - { - if (fmt[i] == 'e') - XEXP (x, i) = replace_with_subreg (XEXP (x, i), reg, new_reg); - else if (fmt[i] == 'E') - for (j = XVECLEN (x, i) - 1; j >= 0; j--) - XVECEXP (x, i, j) = replace_with_subreg (XVECEXP (x, i, j), - reg, new_reg); - } - - return x; -} - -/* Replace REG in INSN with a V2DI subreg of NEW_REG. */ - -void -general_scalar_chain::replace_with_subreg_in_insn (rtx_insn *insn, - rtx reg, rtx new_reg) -{ - replace_with_subreg (single_set (insn), reg, new_reg); -} - /* Insert generated conversion instruction sequence INSNS after instruction AFTER. New BB may be required in case instruction has EH region attached. */ @@ -691,204 +651,147 @@ general_scalar_chain::make_vector_copies (unsigned regno) rtx vreg = gen_reg_rtx (smode); df_ref ref; - for (ref = DF_REG_DEF_CHAIN (regno); ref; ref = DF_REF_NEXT_REG (ref)) - if (!bitmap_bit_p (insns, DF_REF_INSN_UID (ref))) - { - start_sequence (); - if (!TARGET_INTER_UNIT_MOVES_TO_VEC) - { - rtx tmp = assign_386_stack_local (smode, SLOT_STV_TEMP); - if (smode == DImode && !TARGET_64BIT) - { - emit_move_insn (adjust_address (tmp, SImode, 0), - gen_rtx_SUBREG (SImode, reg, 0)); - emit_move_insn (adjust_address (tmp, SImode, 4), - gen_rtx_SUBREG (SImode, reg, 4)); - } - else - emit_move_insn (copy_rtx (tmp), reg); - emit_insn (gen_rtx_SET (gen_rtx_SUBREG (vmode, vreg, 0), - gen_gpr_to_xmm_move_src (vmode, tmp))); - } - else if (!TARGET_64BIT && smode == DImode) - { - if (TARGET_SSE4_1) - { - emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, vreg, 0), - CONST0_RTX (V4SImode), - gen_rtx_SUBREG (SImode, reg, 0))); - emit_insn (gen_sse4_1_pinsrd (gen_rtx_SUBREG (V4SImode, vreg, 0), - gen_rtx_SUBREG (V4SImode, vreg, 0), - gen_rtx_SUBREG (SImode, reg, 4), - GEN_INT (2))); - } - else - { - rtx tmp = gen_reg_rtx (DImode); - emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, vreg, 0), - CONST0_RTX (V4SImode), - gen_rtx_SUBREG (SImode, reg, 0))); - emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, tmp, 0), - CONST0_RTX (V4SImode), - gen_rtx_SUBREG (SImode, reg, 4))); - emit_insn (gen_vec_interleave_lowv4si - (gen_rtx_SUBREG (V4SImode, vreg, 0), - gen_rtx_SUBREG (V4SImode, vreg, 0), - gen_rtx_SUBREG (V4SImode, tmp, 0))); - } - } - else - emit_insn (gen_rtx_SET (gen_rtx_SUBREG (vmode, vreg, 0), - gen_gpr_to_xmm_move_src (vmode, reg))); - rtx_insn *seq = get_insns (); - end_sequence (); - rtx_insn *insn = DF_REF_INSN (ref); - emit_conversion_insns (seq, insn); - - if (dump_file) - fprintf (dump_file, - " Copied r%d to a vector register r%d for insn %d\n", - regno, REGNO (vreg), INSN_UID (insn)); - } - - for (ref = DF_REG_USE_CHAIN (regno); ref; ref = DF_REF_NEXT_REG (ref)) - if (bitmap_bit_p (insns, DF_REF_INSN_UID (ref))) - { - rtx_insn *insn = DF_REF_INSN (ref); - replace_with_subreg_in_insn (insn, reg, vreg); - - if (dump_file) - fprintf (dump_file, " Replaced r%d with r%d in insn %d\n", - regno, REGNO (vreg), INSN_UID (insn)); - } -} - -/* Convert all definitions of register REGNO - and fix its uses. Scalar copies may be created - in case register is used in not convertible insn. */ - -void -general_scalar_chain::convert_reg (unsigned regno) -{ - bool scalar_copy = bitmap_bit_p (defs_conv, regno); - rtx reg = regno_reg_rtx[regno]; - rtx scopy = NULL_RTX; - df_ref ref; - bitmap conv; - - conv = BITMAP_ALLOC (NULL); - bitmap_copy (conv, insns); - - if (scalar_copy) - scopy = gen_reg_rtx (smode); + defs_map.put (reg, vreg); + /* For each insn defining REGNO, see if it is defined by an insn + not part of the chain but with uses in insns part of the chain + and insert a copy in that case. */ for (ref = DF_REG_DEF_CHAIN (regno); ref; ref = DF_REF_NEXT_REG (ref)) { - rtx_insn *insn = DF_REF_INSN (ref); - rtx def_set = single_set (insn); - rtx src = SET_SRC (def_set); - rtx reg = DF_REF_REG (ref); + if (bitmap_bit_p (insns, DF_REF_INSN_UID (ref))) + continue; + df_link *use; + for (use = DF_REF_CHAIN (ref); use; use = use->next) + if (!DF_REF_REG_MEM_P (use->ref) + && bitmap_bit_p (insns, DF_REF_INSN_UID (use->ref))) + break; + if (!use) + continue; - if (!MEM_P (src)) + start_sequence (); + if (!TARGET_INTER_UNIT_MOVES_TO_VEC) { - replace_with_subreg_in_insn (insn, reg, reg); - bitmap_clear_bit (conv, INSN_UID (insn)); + rtx tmp = assign_386_stack_local (smode, SLOT_STV_TEMP); + if (smode == DImode && !TARGET_64BIT) + { + emit_move_insn (adjust_address (tmp, SImode, 0), + gen_rtx_SUBREG (SImode, reg, 0)); + emit_move_insn (adjust_address (tmp, SImode, 4), + gen_rtx_SUBREG (SImode, reg, 4)); + } + else + emit_move_insn (copy_rtx (tmp), reg); + emit_insn (gen_rtx_SET (gen_rtx_SUBREG (vmode, vreg, 0), + gen_gpr_to_xmm_move_src (vmode, tmp))); } - - if (scalar_copy) + else if (!TARGET_64BIT && smode == DImode) { - start_sequence (); - if (!TARGET_INTER_UNIT_MOVES_FROM_VEC) + if (TARGET_SSE4_1) { - rtx tmp = assign_386_stack_local (smode, SLOT_STV_TEMP); - emit_move_insn (tmp, reg); - if (!TARGET_64BIT && smode == DImode) - { - emit_move_insn (gen_rtx_SUBREG (SImode, scopy, 0), - adjust_address (tmp, SImode, 0)); - emit_move_insn (gen_rtx_SUBREG (SImode, scopy, 4), - adjust_address (tmp, SImode, 4)); - } - else - emit_move_insn (scopy, copy_rtx (tmp)); + emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, vreg, 0), + CONST0_RTX (V4SImode), + gen_rtx_SUBREG (SImode, reg, 0))); + emit_insn (gen_sse4_1_pinsrd (gen_rtx_SUBREG (V4SImode, vreg, 0), + gen_rtx_SUBREG (V4SImode, vreg, 0), + gen_rtx_SUBREG (SImode, reg, 4), + GEN_INT (2))); } - else if (!TARGET_64BIT && smode == DImode) + else { - if (TARGET_SSE4_1) - { - rtx tmp = gen_rtx_PARALLEL (VOIDmode, - gen_rtvec (1, const0_rtx)); - emit_insn - (gen_rtx_SET - (gen_rtx_SUBREG (SImode, scopy, 0), - gen_rtx_VEC_SELECT (SImode, - gen_rtx_SUBREG (V4SImode, reg, 0), - tmp))); - - tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, const1_rtx)); - emit_insn - (gen_rtx_SET - (gen_rtx_SUBREG (SImode, scopy, 4), - gen_rtx_VEC_SELECT (SImode, - gen_rtx_SUBREG (V4SImode, reg, 0), - tmp))); - } - else - { - rtx vcopy = gen_reg_rtx (V2DImode); - emit_move_insn (vcopy, gen_rtx_SUBREG (V2DImode, reg, 0)); - emit_move_insn (gen_rtx_SUBREG (SImode, scopy, 0), - gen_rtx_SUBREG (SImode, vcopy, 0)); - emit_move_insn (vcopy, - gen_rtx_LSHIFTRT (V2DImode, - vcopy, GEN_INT (32))); - emit_move_insn (gen_rtx_SUBREG (SImode, scopy, 4), - gen_rtx_SUBREG (SImode, vcopy, 0)); - } + rtx tmp = gen_reg_rtx (DImode); + emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, vreg, 0), + CONST0_RTX (V4SImode), + gen_rtx_SUBREG (SImode, reg, 0))); + emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, tmp, 0), + CONST0_RTX (V4SImode), + gen_rtx_SUBREG (SImode, reg, 4))); + emit_insn (gen_vec_interleave_lowv4si + (gen_rtx_SUBREG (V4SImode, vreg, 0), + gen_rtx_SUBREG (V4SImode, vreg, 0), + gen_rtx_SUBREG (V4SImode, tmp, 0))); } - else - emit_move_insn (scopy, reg); - - rtx_insn *seq = get_insns (); - end_sequence (); - emit_conversion_insns (seq, insn); - - if (dump_file) - fprintf (dump_file, - " Copied r%d to a scalar register r%d for insn %d\n", - regno, REGNO (scopy), INSN_UID (insn)); } - } - - for (ref = DF_REG_USE_CHAIN (regno); ref; ref = DF_REF_NEXT_REG (ref)) - if (bitmap_bit_p (insns, DF_REF_INSN_UID (ref))) - { - if (bitmap_bit_p (conv, DF_REF_INSN_UID (ref))) - { - rtx_insn *insn = DF_REF_INSN (ref); + else + emit_insn (gen_rtx_SET (gen_rtx_SUBREG (vmode, vreg, 0), + gen_gpr_to_xmm_move_src (vmode, reg))); + rtx_insn *seq = get_insns (); + end_sequence (); + rtx_insn *insn = DF_REF_INSN (ref); + emit_conversion_insns (seq, insn); - rtx def_set = single_set (insn); - gcc_assert (def_set); + if (dump_file) + fprintf (dump_file, + " Copied r%d to a vector register r%d for insn %d\n", + regno, REGNO (vreg), INSN_UID (insn)); + } +} - rtx src = SET_SRC (def_set); - rtx dst = SET_DEST (def_set); +/* Copy the definition SRC of INSN inside the chain to DST for + scalar uses outside of the chain. */ - if (!MEM_P (dst) || !REG_P (src)) - replace_with_subreg_in_insn (insn, reg, reg); +void +general_scalar_chain::convert_reg (rtx_insn *insn, rtx dst, rtx src) +{ + start_sequence (); + if (!TARGET_INTER_UNIT_MOVES_FROM_VEC) + { + rtx tmp = assign_386_stack_local (smode, SLOT_STV_TEMP); + emit_move_insn (tmp, src); + if (!TARGET_64BIT && smode == DImode) + { + emit_move_insn (gen_rtx_SUBREG (SImode, dst, 0), + adjust_address (tmp, SImode, 0)); + emit_move_insn (gen_rtx_SUBREG (SImode, dst, 4), + adjust_address (tmp, SImode, 4)); + } + else + emit_move_insn (dst, copy_rtx (tmp)); + } + else if (!TARGET_64BIT && smode == DImode) + { + if (TARGET_SSE4_1) + { + rtx tmp = gen_rtx_PARALLEL (VOIDmode, + gen_rtvec (1, const0_rtx)); + emit_insn + (gen_rtx_SET + (gen_rtx_SUBREG (SImode, dst, 0), + gen_rtx_VEC_SELECT (SImode, + gen_rtx_SUBREG (V4SImode, src, 0), + tmp))); + + tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, const1_rtx)); + emit_insn + (gen_rtx_SET + (gen_rtx_SUBREG (SImode, dst, 4), + gen_rtx_VEC_SELECT (SImode, + gen_rtx_SUBREG (V4SImode, src, 0), + tmp))); + } + else + { + rtx vcopy = gen_reg_rtx (V2DImode); + emit_move_insn (vcopy, gen_rtx_SUBREG (V2DImode, src, 0)); + emit_move_insn (gen_rtx_SUBREG (SImode, dst, 0), + gen_rtx_SUBREG (SImode, vcopy, 0)); + emit_move_insn (vcopy, + gen_rtx_LSHIFTRT (V2DImode, + vcopy, GEN_INT (32))); + emit_move_insn (gen_rtx_SUBREG (SImode, dst, 4), + gen_rtx_SUBREG (SImode, vcopy, 0)); + } + } + else + emit_move_insn (dst, src); - bitmap_clear_bit (conv, INSN_UID (insn)); - } - } - /* Skip debug insns and uninitialized uses. */ - else if (DF_REF_CHAIN (ref) - && NONDEBUG_INSN_P (DF_REF_INSN (ref))) - { - gcc_assert (scopy); - replace_rtx (DF_REF_INSN (ref), reg, scopy); - df_insn_rescan (DF_REF_INSN (ref)); - } + rtx_insn *seq = get_insns (); + end_sequence (); + emit_conversion_insns (seq, insn); - BITMAP_FREE (conv); + if (dump_file) + fprintf (dump_file, + " Copied r%d to a scalar register r%d for insn %d\n", + REGNO (src), REGNO (dst), INSN_UID (insn)); } /* Convert operand OP in INSN. We should handle @@ -921,16 +824,6 @@ general_scalar_chain::convert_op (rtx *op, rtx_insn *insn) } else if (REG_P (*op)) { - /* We may have not converted register usage in case - this register has no definition. Otherwise it - should be converted in convert_reg. */ - df_ref ref; - FOR_EACH_INSN_USE (ref, insn) - if (DF_REF_REGNO (ref) == REGNO (*op)) - { - gcc_assert (!DF_REF_CHAIN (ref)); - break; - } *op = gen_rtx_SUBREG (vmode, *op, 0); } else if (CONST_INT_P (*op)) @@ -975,6 +868,32 @@ general_scalar_chain::convert_op (rtx *op, rtx_insn *insn) void general_scalar_chain::convert_insn (rtx_insn *insn) { + /* Generate copies for out-of-chain uses of defs. */ + for (df_ref ref = DF_INSN_DEFS (insn); ref; ref = DF_REF_NEXT_LOC (ref)) + if (bitmap_bit_p (defs_conv, DF_REF_REGNO (ref))) + { + df_link *use; + for (use = DF_REF_CHAIN (ref); use; use = use->next) + if (DF_REF_REG_MEM_P (use->ref) + || !bitmap_bit_p (insns, DF_REF_INSN_UID (use->ref))) + break; + if (use) + convert_reg (insn, DF_REF_REG (ref), + *defs_map.get (regno_reg_rtx [DF_REF_REGNO (ref)])); + } + + /* Replace uses in this insn with the defs we use in the chain. */ + for (df_ref ref = DF_INSN_USES (insn); ref; ref = DF_REF_NEXT_LOC (ref)) + if (!DF_REF_REG_MEM_P (ref)) + if (rtx *vreg = defs_map.get (regno_reg_rtx[DF_REF_REGNO (ref)])) + { + /* Also update a corresponding REG_DEAD note. */ + rtx note = find_reg_note (insn, REG_DEAD, DF_REF_REG (ref)); + if (note) + XEXP (note, 0) = *vreg; + *DF_REF_REAL_LOC (ref) = *vreg; + } + rtx def_set = single_set (insn); rtx src = SET_SRC (def_set); rtx dst = SET_DEST (def_set); @@ -988,6 +907,20 @@ general_scalar_chain::convert_insn (rtx_insn *insn) emit_conversion_insns (gen_move_insn (dst, tmp), insn); dst = gen_rtx_SUBREG (vmode, tmp, 0); } + else if (REG_P (dst)) + { + /* Replace the definition with a SUBREG to the definition we + use inside the chain. */ + rtx *vdef = defs_map.get (dst); + if (vdef) + dst = *vdef; + dst = gen_rtx_SUBREG (vmode, dst, 0); + /* IRA doesn't like to have REG_EQUAL/EQUIV notes when the SET_DEST + is a non-REG_P. So kill those off. */ + rtx note = find_reg_equal_equiv_note (insn); + if (note) + remove_note (insn, note); + } switch (GET_CODE (src)) { @@ -1045,20 +978,15 @@ general_scalar_chain::convert_insn (rtx_insn *insn) case COMPARE: src = SUBREG_REG (XEXP (XEXP (src, 0), 0)); - gcc_assert ((REG_P (src) && GET_MODE (src) == DImode) - || (SUBREG_P (src) && GET_MODE (src) == V2DImode)); - - if (REG_P (src)) - subreg = gen_rtx_SUBREG (V2DImode, src, 0); - else - subreg = copy_rtx_if_shared (src); + gcc_assert (REG_P (src) && GET_MODE (src) == DImode); + subreg = gen_rtx_SUBREG (V2DImode, src, 0); emit_insn_before (gen_vec_interleave_lowv2di (copy_rtx_if_shared (subreg), copy_rtx_if_shared (subreg), copy_rtx_if_shared (subreg)), insn); dst = gen_rtx_REG (CCmode, FLAGS_REG); - src = gen_rtx_UNSPEC (CCmode, gen_rtvec (2, copy_rtx_if_shared (src), - copy_rtx_if_shared (src)), + src = gen_rtx_UNSPEC (CCmode, gen_rtvec (2, copy_rtx_if_shared (subreg), + copy_rtx_if_shared (subreg)), UNSPEC_PTEST); break; @@ -1217,16 +1145,15 @@ timode_scalar_chain::convert_insn (rtx_insn *insn) df_insn_rescan (insn); } +/* Generate copies from defs used by the chain but not defined therein. + Also populates defs_map which is used later by convert_insn. */ + void general_scalar_chain::convert_registers () { bitmap_iterator bi; unsigned id; - - EXECUTE_IF_SET_IN_BITMAP (defs, 0, id, bi) - convert_reg (id); - - EXECUTE_IF_AND_COMPL_IN_BITMAP (defs_conv, defs, 0, id, bi) + EXECUTE_IF_SET_IN_BITMAP (defs_conv, 0, id, bi) make_vector_copies (id); } diff --git a/gcc/config/i386/i386-features.h b/gcc/config/i386/i386-features.h index c85ac45..8381efe 100644 --- a/gcc/config/i386/i386-features.h +++ b/gcc/config/i386/i386-features.h @@ -171,12 +171,11 @@ class general_scalar_chain : public scalar_chain : scalar_chain (smode_, vmode_) {} int compute_convert_gain (); private: + hash_map defs_map; void mark_dual_mode_def (df_ref def); - rtx replace_with_subreg (rtx x, rtx reg, rtx subreg); - void replace_with_subreg_in_insn (rtx_insn *insn, rtx reg, rtx subreg); void convert_insn (rtx_insn *insn); void convert_op (rtx *op, rtx_insn *insn); - void convert_reg (unsigned regno); + void convert_reg (rtx_insn *insn, rtx dst, rtx src); void make_vector_copies (unsigned regno); void convert_registers (); int vector_const_cost (rtx exp); -- cgit v1.1 From 7d7b99f95bf2517caab5f9300090b471135b4fc0 Mon Sep 17 00:00:00 2001 From: Tejas Joshi Date: Mon, 26 Aug 2019 12:32:29 +0000 Subject: Builtin function roundeven folding implementation 2019-08-26 Tejas Joshi * builtins.c (mathfn_built_in_2): Added CASE_MATHFN_FLOATN for ROUNDEVEN. * builtins.def: Added function definitions for roundeven function variants. * fold-const-call.c (fold_const_call_ss): Added case for roundeven function call. Adjust condition for floor, ceil, trunc and round. * fold-const.c (negate_mathfn_p): Added case for roundeven function. (tree_call_nonnegative_warnv_p): Added case for roundeven function. (integer_valued_real_call_p): Added case for roundeven function. * real.c (is_even): New function. Returns true if real number is even, otherwise returns false. (is_halfway_below): New function. Returns true if real number is halfway between two integers, else return false. (real_roundeven): New function. Round real number to nearest integer, rounding halfway cases towards even. * real.h (real_value): Added descriptive comments. Added function declaration for roundeven function. * doc/extend.texi (Other Builtins): List roundeven variants among functions which can be handled as builtins. gcc/testsuite/ChangeLog: 2019-08-26 Tejas Joshi * gcc.dg/torture/builtin-round-roundeven.c: New test. * gcc.dg/torture/builtin-round-roundevenf128.c: New test. From-SVN: r274927 --- gcc/ChangeLog | 22 +++++ gcc/builtins.c | 1 + gcc/builtins.def | 6 ++ gcc/doc/extend.texi | 3 +- gcc/fold-const-call.c | 23 ++++-- gcc/fold-const.c | 6 ++ gcc/real.c | 95 ++++++++++++++++++++++ gcc/real.h | 9 ++ gcc/testsuite/ChangeLog | 5 ++ .../gcc.dg/torture/builtin-round-roundeven.c | 36 ++++++++ .../gcc.dg/torture/builtin-round-roundevenf128.c | 21 +++++ 11 files changed, 221 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/builtin-round-roundeven.c create mode 100644 gcc/testsuite/gcc.dg/torture/builtin-round-roundevenf128.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f4e2919..c67cbe3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,25 @@ +2019-08-26 Tejas Joshi + + * builtins.c (mathfn_built_in_2): Added CASE_MATHFN_FLOATN + for ROUNDEVEN. + * builtins.def: Added function definitions for roundeven function + variants. + * fold-const-call.c (fold_const_call_ss): Added case for roundeven + function call. Adjust condition for floor, ceil, trunc and round. + * fold-const.c (negate_mathfn_p): Added case for roundeven function. + (tree_call_nonnegative_warnv_p): Added case for roundeven function. + (integer_valued_real_call_p): Added case for roundeven function. + * real.c (is_even): New function. Returns true if real number is even, + otherwise returns false. + (is_halfway_below): New function. Returns true if real number is + halfway between two integers, else return false. + (real_roundeven): New function. Round real number to nearest integer, + rounding halfway cases towards even. + * real.h (real_value): Added descriptive comments. Added function + declaration for roundeven function. + * doc/extend.texi (Other Builtins): List roundeven variants among + functions which can be handled as builtins. + 2019-08-26 Richard Biener PR target/91522 diff --git a/gcc/builtins.c b/gcc/builtins.c index 073b92a..f902e24 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -2061,6 +2061,7 @@ mathfn_built_in_2 (tree type, combined_fn fn) CASE_MATHFN (REMQUO) CASE_MATHFN_FLOATN (RINT) CASE_MATHFN_FLOATN (ROUND) + CASE_MATHFN_FLOATN (ROUNDEVEN) CASE_MATHFN (SCALB) CASE_MATHFN (SCALBLN) CASE_MATHFN (SCALBN) diff --git a/gcc/builtins.def b/gcc/builtins.def index 6d41bdb..8bb7027 100644 --- a/gcc/builtins.def +++ b/gcc/builtins.def @@ -542,12 +542,18 @@ DEF_C99_BUILTIN (BUILT_IN_RINTL, "rintl", BT_FN_LONGDOUBLE_LONGDOUBLE, AT #define RINT_TYPE(F) BT_FN_##F##_##F DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_RINT, "rint", RINT_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST) #undef RINT_TYPE +DEF_EXT_LIB_BUILTIN (BUILT_IN_ROUNDEVEN, "roundeven", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_ROUNDEVENF, "roundevenf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_ROUNDEVENL, "roundevenl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) DEF_C99_BUILTIN (BUILT_IN_ROUND, "round", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) DEF_C99_BUILTIN (BUILT_IN_ROUNDF, "roundf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) DEF_C99_BUILTIN (BUILT_IN_ROUNDL, "roundl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) #define ROUND_TYPE(F) BT_FN_##F##_##F DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_ROUND, "round", ROUND_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST) #undef ROUND_TYPE +#define ROUNDEVEN_TYPE(F) BT_FN_##F##_##F +DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_ROUNDEVEN, "roundeven", ROUNDEVEN_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST) +#undef ROUNDEVEN_TYPE DEF_EXT_LIB_BUILTIN (BUILT_IN_SCALB, "scalb", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) DEF_EXT_LIB_BUILTIN (BUILT_IN_SCALBF, "scalbf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) DEF_EXT_LIB_BUILTIN (BUILT_IN_SCALBL, "scalbl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 235be99..4aea4d3 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -12448,7 +12448,8 @@ Outside strict ISO C mode (@option{-ansi}, @option{-std=c90}, @code{j1f}, @code{j1l}, @code{j1}, @code{jnf}, @code{jnl}, @code{jn}, @code{lgammaf_r}, @code{lgammal_r}, @code{lgamma_r}, @code{mempcpy}, @code{pow10f}, @code{pow10l}, @code{pow10}, @code{printf_unlocked}, -@code{rindex}, @code{scalbf}, @code{scalbl}, @code{scalb}, +@code{rindex}, @code{roundeven}, @code{roundevenf}, @code{roudnevenl}, +@code{scalbf}, @code{scalbl}, @code{scalb}, @code{signbit}, @code{signbitf}, @code{signbitl}, @code{signbitd32}, @code{signbitd64}, @code{signbitd128}, @code{significandf}, @code{significandl}, @code{significand}, @code{sincosf}, diff --git a/gcc/fold-const-call.c b/gcc/fold-const-call.c index e21d8e11..3a14d2a 100644 --- a/gcc/fold-const-call.c +++ b/gcc/fold-const-call.c @@ -836,7 +836,7 @@ fold_const_call_ss (real_value *result, combined_fn fn, CASE_CFN_FLOOR: CASE_CFN_FLOOR_FN: - if (!REAL_VALUE_ISNAN (*arg) || !flag_errno_math) + if (!REAL_VALUE_ISSIGNALING_NAN (*arg)) { real_floor (result, format, arg); return true; @@ -845,7 +845,7 @@ fold_const_call_ss (real_value *result, combined_fn fn, CASE_CFN_CEIL: CASE_CFN_CEIL_FN: - if (!REAL_VALUE_ISNAN (*arg) || !flag_errno_math) + if (!REAL_VALUE_ISSIGNALING_NAN (*arg)) { real_ceil (result, format, arg); return true; @@ -854,18 +854,31 @@ fold_const_call_ss (real_value *result, combined_fn fn, CASE_CFN_TRUNC: CASE_CFN_TRUNC_FN: - real_trunc (result, format, arg); - return true; + if (!REAL_VALUE_ISSIGNALING_NAN (*arg)) + { + real_trunc (result, format, arg); + return true; + } + return false; CASE_CFN_ROUND: CASE_CFN_ROUND_FN: - if (!REAL_VALUE_ISNAN (*arg) || !flag_errno_math) + if (!REAL_VALUE_ISSIGNALING_NAN (*arg)) { real_round (result, format, arg); return true; } return false; + CASE_CFN_ROUNDEVEN: + CASE_CFN_ROUNDEVEN_FN: + if (!REAL_VALUE_ISSIGNALING_NAN (*arg)) + { + real_roundeven (result, format, arg); + return true; + } + return false; + CASE_CFN_LOGB: return fold_const_logb (result, arg, format); diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 8c711ab..0376cdb 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -329,6 +329,8 @@ negate_mathfn_p (combined_fn fn) CASE_CFN_LLROUND: CASE_CFN_LROUND: CASE_CFN_ROUND: + CASE_CFN_ROUNDEVEN: + CASE_CFN_ROUNDEVEN_FN: CASE_CFN_SIN: CASE_CFN_SINH: CASE_CFN_TAN: @@ -13107,6 +13109,8 @@ tree_call_nonnegative_warnv_p (tree type, combined_fn fn, tree arg0, tree arg1, CASE_CFN_RINT_FN: CASE_CFN_ROUND: CASE_CFN_ROUND_FN: + CASE_CFN_ROUNDEVEN: + CASE_CFN_ROUNDEVEN_FN: CASE_CFN_SCALB: CASE_CFN_SCALBLN: CASE_CFN_SCALBN: @@ -13630,6 +13634,8 @@ integer_valued_real_call_p (combined_fn fn, tree arg0, tree arg1, int depth) CASE_CFN_RINT_FN: CASE_CFN_ROUND: CASE_CFN_ROUND_FN: + CASE_CFN_ROUNDEVEN: + CASE_CFN_ROUNDEVEN_FN: CASE_CFN_TRUNC: CASE_CFN_TRUNC_FN: return true; diff --git a/gcc/real.c b/gcc/real.c index 0164f09..6e6a394 100644 --- a/gcc/real.c +++ b/gcc/real.c @@ -5010,6 +5010,101 @@ real_round (REAL_VALUE_TYPE *r, format_helper fmt, real_convert (r, fmt, r); } +/* Return true including 0 if integer part of R is even, else return + false. The function is not valid for rvc_inf and rvc_nan classes. */ + +bool +is_even (REAL_VALUE_TYPE *r) +{ + gcc_assert (r->cl != rvc_inf); + gcc_assert (r->cl != rvc_nan); + + if (r->cl == rvc_zero) + return true; + + /* For (-1,1), number is even. */ + if (REAL_EXP (r) <= 0) + return true; + + /* Check lowest bit, if not set, return true. */ + else if (REAL_EXP (r) <= SIGNIFICAND_BITS) + { + unsigned int n = SIGNIFICAND_BITS - REAL_EXP (r); + int w = n / HOST_BITS_PER_LONG; + + unsigned long num = ((unsigned long)1 << (n % HOST_BITS_PER_LONG)); + + if ((r->sig[w] & num) == 0) + return true; + } + else + return true; + + return false; +} + +/* Return true if R is halfway between two integers, else return + false. The function is not valid for rvc_inf and rvc_nan classes. */ + +bool +is_halfway_below (const REAL_VALUE_TYPE *r) +{ + gcc_assert (r->cl != rvc_inf); + gcc_assert (r->cl != rvc_nan); + int i; + + if (r->cl == rvc_zero) + return false; + + /* For numbers (-0.5,0) and (0,0.5). */ + if (REAL_EXP (r) < 0) + return false; + + else if (REAL_EXP (r) < SIGNIFICAND_BITS) + { + unsigned int n = SIGNIFICAND_BITS - REAL_EXP (r) - 1; + int w = n / HOST_BITS_PER_LONG; + + for (i = 0; i < w; ++i) + if (r->sig[i] != 0) + return false; + + unsigned long num = ((unsigned long)1 << (n % HOST_BITS_PER_LONG)); + + if (((r->sig[w] & num) != 0) && ((r->sig[w] & (num-1)) == 0)) + return true; + } + return false; +} + +/* Round X to nearest integer, rounding halfway cases towards even. */ + +void +real_roundeven (REAL_VALUE_TYPE *r, format_helper fmt, + const REAL_VALUE_TYPE *x) +{ + if (is_halfway_below (x)) + { + /* Special case as -0.5 rounds to -0.0 and + similarly +0.5 rounds to +0.0. */ + if (REAL_EXP (x) == 0) + { + *r = *x; + clear_significand_below (r, SIGNIFICAND_BITS); + } + else + { + do_add (r, x, &dconsthalf, x->sign); + if (!is_even (r)) + do_add (r, r, &dconstm1, x->sign); + } + if (fmt) + real_convert (r, fmt, r); + } + else + real_round (r, fmt, x); +} + /* Set the sign of R to the sign of X. */ void diff --git a/gcc/real.h b/gcc/real.h index 95b9db8..2f41834 100644 --- a/gcc/real.h +++ b/gcc/real.h @@ -41,11 +41,18 @@ struct GTY(()) real_value { sure they're packed together, otherwise REAL_VALUE_TYPE_SIZE will be miscomputed. */ unsigned int /* ENUM_BITFIELD (real_value_class) */ cl : 2; + /* 1 if number is decimal floating point. */ unsigned int decimal : 1; + /* 1 if number is negative. */ unsigned int sign : 1; + /* 1 if number is signalling. */ unsigned int signalling : 1; + /* 1 if number is canonical + All are generally used for handling cases in real.c. */ unsigned int canonical : 1; + /* unbiased exponent of the number. */ unsigned int uexp : EXP_BITS; + /* significand of the number. */ unsigned long sig[SIGSZ]; }; @@ -500,6 +507,8 @@ extern void real_ceil (REAL_VALUE_TYPE *, format_helper, const REAL_VALUE_TYPE *); extern void real_round (REAL_VALUE_TYPE *, format_helper, const REAL_VALUE_TYPE *); +extern void real_roundeven (REAL_VALUE_TYPE *, format_helper, + const REAL_VALUE_TYPE *); /* Set the sign of R to the sign of X. */ extern void real_copysign (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c7bf9cc..c68c823 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-08-26 Tejas Joshi + + * gcc.dg/torture/builtin-round-roundeven.c: New test. + * gcc.dg/torture/builtin-round-roundevenf128.c: Likewise. + 2019-08-26 Robin Dapp * gcc.dg/tree-ssa/copy-headers-5.c: Do not run vrp pass. diff --git a/gcc/testsuite/gcc.dg/torture/builtin-round-roundeven.c b/gcc/testsuite/gcc.dg/torture/builtin-round-roundeven.c new file mode 100644 index 0000000..a39ab0c --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/builtin-round-roundeven.c @@ -0,0 +1,36 @@ +/* { dg-do link } */ + +extern int link_error (int); + +#define TEST(FN, VALUE, RESULT) \ + if (__builtin_##FN (VALUE) != RESULT) link_error (__LINE__); + +int +main (void) +{ + TEST(roundeven, 0, 0); + TEST(roundeven, 0.5, 0); + TEST(roundeven, -0.5, 0); + TEST(roundeven, 6, 6); + TEST(roundeven, -8, -8); + TEST(roundeven, 2.5, 2); + TEST(roundeven, 3.5, 4); + TEST(roundeven, -1.5, -2); + TEST(roundeven, 3.499, 3); + TEST(roundeven, 3.501, 4); + + if (__builtin_copysign (1, __builtin_roundeven (-0.5)) != -1) + link_error (__LINE__); + if (__builtin_copysign (1, __builtin_roundeven (-0.0)) != -1) + link_error (__LINE__); + if (__builtin_copysign (-1, __builtin_roundeven (0.5)) != 1) + link_error (__LINE__); + if (__builtin_copysign (-1, __builtin_roundeven (0.0)) != 1) + link_error (__LINE__); + if (__builtin_copysign (1, __builtin_roundeven (-0.25)) != -1) + link_error (__LINE__); + if (__builtin_copysign (-1, __builtin_roundeven (0.25)) != 1) + link_error (__LINE__); + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/torture/builtin-round-roundevenf128.c b/gcc/testsuite/gcc.dg/torture/builtin-round-roundevenf128.c new file mode 100644 index 0000000..85a8cbf --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/builtin-round-roundevenf128.c @@ -0,0 +1,21 @@ +/* { dg-do link } */ +/* { dg-add-options float128 } */ +/* { dg-require-effective-target float128 } */ + +extern int link_error (int); + +#define TEST(FN, VALUE, RESULT) \ + if (__builtin_##FN##f128 (VALUE) != RESULT) link_error (__LINE__); + +int +main (void) +{ + TEST(roundeven, (0x1p64+0.5f128), (0x1p64f128)); + TEST(roundeven, (0x1p63+0.5f128), (0x1p63f128)); + TEST(roundeven, (0x1p63-0.5f128), (0x1p63f128)); + TEST(roundeven, (0x1p64-0.5f128), (0x1p64f128)); + TEST(roundeven, (0x1p64+0.501f128), (0x1p64+1.0f128)); + TEST(roundeven, (0x1.C00000000000039A5653p1f128), (0x1p2f128)) + return 0; +} + -- cgit v1.1 From d3b92f35d84f44a8599028086286699213b73e7c Mon Sep 17 00:00:00 2001 From: Tejas Joshi Date: Mon, 26 Aug 2019 12:41:59 +0000 Subject: i386: Roundeven expansion for SSE4.1+ gcc/ChangeLog: 2019-08-26 Tejas Joshi Uros Bizjak * builtins.c (mathfn_built_in_2): Change CASE_MATHFN to CASE_MATHFN_FLOATN for roundeven. * config/i386/i386.c (ix86_i387_mode_needed): Add case I387_ROUNDEVEN. (ix86_mode_needed): Likewise. (ix86_mode_after): Likewise. (ix86_mode_entry): Likewise. (ix86_mode_exit): Likewise. (ix86_emit_mode_set): Likewise. (emit_i387_cw_initialization): Add case I387_CW_ROUNDEVEN. * config/i386/i386.h (ix86_stack_slot): Add SLOT_CW_ROUNDEVEN. (ix86_entry): Add I387_ROUNDEVEN. (avx_u128_state): Add I387_CW_ANY. * config/i386/i386.md: Define UNSPEC_FRNDINT_ROUNDEVEN. (define_int_iterator): Likewise. (define_int_attr): Likewise for rounding_insn, rounding and ROUNDING. (define_constant): Define ROUND_ROUNDEVEN mode. (define_attr): Add roundeven mode for i387_cw. (2): Add condition for ROUND_ROUNDEVEN. * internal-fn.def (ROUNDEVEN): New builtin function. * optabs.def (roundeven_optab): New optab. gcc/testsuite/ChangeLog: 2019-08-26 Tejas Joshi * gcc.target/i386/sse4_1-round-roundeven-1.c: New test. * gcc.target/i386/sse4_1-round-roundeven-2.c: New test. Co-Authored-By: Uros Bizjak From-SVN: r274928 --- gcc/ChangeLog | 25 ++++++++++++++++++++++ gcc/config/i386/i386.c | 16 ++++++++++++++ gcc/config/i386/i386.h | 4 +++- gcc/config/i386/i386.md | 23 +++++++++++++------- gcc/internal-fn.def | 1 + gcc/optabs.def | 1 + gcc/reg-stack.c | 1 + gcc/testsuite/ChangeLog | 5 +++++ .../gcc.target/i386/sse4_1-round-roundeven-1.c | 17 +++++++++++++++ .../gcc.target/i386/sse4_1-round-roundeven-2.c | 15 +++++++++++++ 10 files changed, 99 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/sse4_1-round-roundeven-1.c create mode 100644 gcc/testsuite/gcc.target/i386/sse4_1-round-roundeven-2.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c67cbe3..aa2bec6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,29 @@ 2019-08-26 Tejas Joshi + Uros Bizjak + + * builtins.c (mathfn_built_in_2): Change CASE_MATHFN to + CASE_MATHFN_FLOATN for roundeven. + * config/i386/i386.c (ix86_i387_mode_needed): Add case + I387_ROUNDEVEN. + (ix86_mode_needed): Likewise. + (ix86_mode_after): Likewise. + (ix86_mode_entry): Likewise. + (ix86_mode_exit): Likewise. + (ix86_emit_mode_set): Likewise. + (emit_i387_cw_initialization): Add case I387_CW_ROUNDEVEN. + * config/i386/i386.h (ix86_stack_slot): Add SLOT_CW_ROUNDEVEN. + (ix86_entry): Add I387_ROUNDEVEN. + (avx_u128_state): Add I387_CW_ANY. + * config/i386/i386.md: Define UNSPEC_FRNDINT_ROUNDEVEN. + (define_int_iterator): Likewise. + (define_int_attr): Likewise for rounding_insn, rounding and ROUNDING. + (define_constant): Define ROUND_ROUNDEVEN mode. + (define_attr): Add roundeven mode for i387_cw. + (2): Add condition for ROUND_ROUNDEVEN. + * internal-fn.def (ROUNDEVEN): New builtin function. + * optabs.def (roundeven_optab): New optab. + +2019-08-26 Tejas Joshi * builtins.c (mathfn_built_in_2): Added CASE_MATHFN_FLOATN for ROUNDEVEN. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 49ab50e..c712c03 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -13557,6 +13557,11 @@ ix86_i387_mode_needed (int entity, rtx_insn *insn) switch (entity) { + case I387_ROUNDEVEN: + if (mode == I387_CW_ROUNDEVEN) + return mode; + break; + case I387_TRUNC: if (mode == I387_CW_TRUNC) return mode; @@ -13591,6 +13596,7 @@ ix86_mode_needed (int entity, rtx_insn *insn) return ix86_dirflag_mode_needed (insn); case AVX_U128: return ix86_avx_u128_mode_needed (insn); + case I387_ROUNDEVEN: case I387_TRUNC: case I387_FLOOR: case I387_CEIL: @@ -13651,6 +13657,7 @@ ix86_mode_after (int entity, int mode, rtx_insn *insn) return mode; case AVX_U128: return ix86_avx_u128_mode_after (mode, insn); + case I387_ROUNDEVEN: case I387_TRUNC: case I387_FLOOR: case I387_CEIL: @@ -13703,6 +13710,7 @@ ix86_mode_entry (int entity) return ix86_dirflag_mode_entry (); case AVX_U128: return ix86_avx_u128_mode_entry (); + case I387_ROUNDEVEN: case I387_TRUNC: case I387_FLOOR: case I387_CEIL: @@ -13740,6 +13748,7 @@ ix86_mode_exit (int entity) return X86_DIRFLAG_ANY; case AVX_U128: return ix86_avx_u128_mode_exit (); + case I387_ROUNDEVEN: case I387_TRUNC: case I387_FLOOR: case I387_CEIL: @@ -13774,6 +13783,12 @@ emit_i387_cw_initialization (int mode) switch (mode) { + case I387_CW_ROUNDEVEN: + /* round to nearest */ + emit_insn (gen_andhi3 (reg, reg, GEN_INT (0x0c00))); + slot = SLOT_CW_ROUNDEVEN; + break; + case I387_CW_TRUNC: /* round toward zero (truncate) */ emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0c00))); @@ -13820,6 +13835,7 @@ ix86_emit_mode_set (int entity, int mode, int prev_mode ATTRIBUTE_UNUSED, if (mode == AVX_U128_CLEAN) emit_insn (gen_avx_vzeroupper ()); break; + case I387_ROUNDEVEN: case I387_TRUNC: case I387_FLOOR: case I387_CEIL: diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 167b73e..a1d0484d7 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -2511,6 +2511,7 @@ enum ix86_stack_slot { SLOT_TEMP = 0, SLOT_CW_STORED, + SLOT_CW_ROUNDEVEN, SLOT_CW_TRUNC, SLOT_CW_FLOOR, SLOT_CW_CEIL, @@ -2522,6 +2523,7 @@ enum ix86_entity { X86_DIRFLAG = 0, AVX_U128, + I387_ROUNDEVEN, I387_TRUNC, I387_FLOOR, I387_CEIL, @@ -2557,7 +2559,7 @@ enum avx_u128_state #define NUM_MODES_FOR_MODE_SWITCHING \ { X86_DIRFLAG_ANY, AVX_U128_ANY, \ - I387_CW_ANY, I387_CW_ANY, I387_CW_ANY } + I387_CW_ANY, I387_CW_ANY, I387_CW_ANY, I387_CW_ANY } /* Avoid renaming of stack registers, as doing so in combination with diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 9951d46..7ad9788 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -141,6 +141,7 @@ UNSPEC_FXAM ;; x87 Rounding + UNSPEC_FRNDINT_ROUNDEVEN UNSPEC_FRNDINT_FLOOR UNSPEC_FRNDINT_CEIL UNSPEC_FRNDINT_TRUNC @@ -303,7 +304,8 @@ ;; Constants to represent rounding modes in the ROUND instruction (define_constants - [(ROUND_FLOOR 0x1) + [(ROUND_ROUNDEVEN 0x0) + (ROUND_FLOOR 0x1) (ROUND_CEIL 0x2) (ROUND_TRUNC 0x3) (ROUND_MXCSR 0x4) @@ -779,7 +781,7 @@ ;; Defines rounding mode of an FP operation. -(define_attr "i387_cw" "trunc,floor,ceil,uninitialized,any" +(define_attr "i387_cw" "roundeven,floor,ceil,trunc,uninitialized,any" (const_string "any")) ;; Define attribute to indicate AVX insns with partial XMM register update. @@ -16212,7 +16214,8 @@ }) (define_int_iterator FRNDINT_ROUNDING - [UNSPEC_FRNDINT_FLOOR + [UNSPEC_FRNDINT_ROUNDEVEN + UNSPEC_FRNDINT_FLOOR UNSPEC_FRNDINT_CEIL UNSPEC_FRNDINT_TRUNC]) @@ -16222,21 +16225,24 @@ ;; Base name for define_insn (define_int_attr rounding_insn - [(UNSPEC_FRNDINT_FLOOR "floor") + [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven") + (UNSPEC_FRNDINT_FLOOR "floor") (UNSPEC_FRNDINT_CEIL "ceil") (UNSPEC_FRNDINT_TRUNC "btrunc") (UNSPEC_FIST_FLOOR "floor") (UNSPEC_FIST_CEIL "ceil")]) (define_int_attr rounding - [(UNSPEC_FRNDINT_FLOOR "floor") + [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven") + (UNSPEC_FRNDINT_FLOOR "floor") (UNSPEC_FRNDINT_CEIL "ceil") (UNSPEC_FRNDINT_TRUNC "trunc") (UNSPEC_FIST_FLOOR "floor") (UNSPEC_FIST_CEIL "ceil")]) (define_int_attr ROUNDING - [(UNSPEC_FRNDINT_FLOOR "FLOOR") + [(UNSPEC_FRNDINT_ROUNDEVEN "ROUNDEVEN") + (UNSPEC_FRNDINT_FLOOR "FLOOR") (UNSPEC_FRNDINT_CEIL "CEIL") (UNSPEC_FRNDINT_TRUNC "TRUNC") (UNSPEC_FIST_FLOOR "FLOOR") @@ -16299,8 +16305,9 @@ || TARGET_MIX_SSE_I387) && (flag_fp_int_builtin_inexact || !flag_trapping_math)) || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH - && (TARGET_SSE4_1 || flag_fp_int_builtin_inexact - || !flag_trapping_math))" + && (TARGET_SSE4_1 + || (ROUND_ != ROUND_ROUNDEVEN + && (flag_fp_int_builtin_inexact || !flag_trapping_math))))" { if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH && (TARGET_SSE4_1 || flag_fp_int_builtin_inexact || !flag_trapping_math)) diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def index 9461693..b5a6ca3 100644 --- a/gcc/internal-fn.def +++ b/gcc/internal-fn.def @@ -238,6 +238,7 @@ DEF_INTERNAL_FLT_FLOATN_FN (FLOOR, ECF_CONST, floor, unary) DEF_INTERNAL_FLT_FLOATN_FN (NEARBYINT, ECF_CONST, nearbyint, unary) DEF_INTERNAL_FLT_FLOATN_FN (RINT, ECF_CONST, rint, unary) DEF_INTERNAL_FLT_FLOATN_FN (ROUND, ECF_CONST, round, unary) +DEF_INTERNAL_FLT_FLOATN_FN (ROUNDEVEN, ECF_CONST, roundeven, unary) DEF_INTERNAL_FLT_FLOATN_FN (TRUNC, ECF_CONST, btrunc, unary) /* Binary math functions. */ diff --git a/gcc/optabs.def b/gcc/optabs.def index 5283e67..0860b38 100644 --- a/gcc/optabs.def +++ b/gcc/optabs.def @@ -271,6 +271,7 @@ OPTAB_D (fnms_optab, "fnms$a4") OPTAB_D (rint_optab, "rint$a2") OPTAB_D (round_optab, "round$a2") +OPTAB_D (roundeven_optab, "roundeven$a2") OPTAB_D (floor_optab, "floor$a2") OPTAB_D (ceil_optab, "ceil$a2") OPTAB_D (btrunc_optab, "btrunc$a2") diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c index 710f14a..0f0089a 100644 --- a/gcc/reg-stack.c +++ b/gcc/reg-stack.c @@ -1817,6 +1817,7 @@ subst_stack_regs_pat (rtx_insn *insn, stack_ptr regstack, rtx pat) case UNSPEC_FRNDINT: case UNSPEC_F2XM1: + case UNSPEC_FRNDINT_ROUNDEVEN: case UNSPEC_FRNDINT_FLOOR: case UNSPEC_FRNDINT_CEIL: case UNSPEC_FRNDINT_TRUNC: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c68c823..b5a2d7b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2019-08-26 Tejas Joshi + * gcc.target/i386/sse4_1-round-roundeven-1.c: New test. + * gcc.target/i386/sse4_1-round-roundeven-2.c: New test. + +2019-08-26 Tejas Joshi + * gcc.dg/torture/builtin-round-roundeven.c: New test. * gcc.dg/torture/builtin-round-roundevenf128.c: Likewise. diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-round-roundeven-1.c b/gcc/testsuite/gcc.target/i386/sse4_1-round-roundeven-1.c new file mode 100644 index 0000000..3633263 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse4_1-round-roundeven-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -msse4.1" } */ + +__attribute__((noinline, noclone)) double +f1 (double x) +{ + return __builtin_roundeven (x); +} + +__attribute__((noinline, noclone)) float +f2 (float x) +{ + return __builtin_roundevenf (x); +} + +/* { dg-final { scan-assembler-times "roundsd\[^\n\r\]*xmm" 1 } } */ +/* { dg-final { scan-assembler-times "roundss\[^\n\r\]*xmm" 1 } } */ diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-round-roundeven-2.c b/gcc/testsuite/gcc.target/i386/sse4_1-round-roundeven-2.c new file mode 100644 index 0000000..9505796 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse4_1-round-roundeven-2.c @@ -0,0 +1,15 @@ +/* { dg-do run } */ +/* { dg-require-effective-target sse4 } */ +/* { dg-options "-O2 -msse4.1" } */ + +#include "sse4_1-check.h" +#include "sse4_1-round-roundeven-1.c" + +static void +sse4_1_test (void) +{ + if (f1 (0.5) != 0.0 || f1 (1.5) != 2.0 || f1 (-0.5) != 0.0 || f1 (-1.5) != -2.0) + abort (); + if (f2 (0.5f) != 0.0f || f2 (1.5f) != 2.0f || f2 (-0.5f) != 0.0f || f2 (-1.5f) != -2.0f) + abort (); +} -- cgit v1.1 From d2ea2406ccd002f8c150e6accaffd6bfdbd7444b Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 26 Aug 2019 13:55:46 +0000 Subject: i386-features.c (general_remove_non_convertible_regs): Remove. 2019-08-26 Richard Biener * config/i386/i386-features.c (general_remove_non_convertible_regs): Remove. (convert_scalars_to_vector): Do not call it. From-SVN: r274929 --- gcc/ChangeLog | 6 ++++ gcc/config/i386/i386-features.c | 62 ----------------------------------------- 2 files changed, 6 insertions(+), 62 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index aa2bec6..c61f338 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-08-26 Richard Biener + + * config/i386/i386-features.c (general_remove_non_convertible_regs): + Remove. + (convert_scalars_to_vector): Do not call it. + 2019-08-26 Tejas Joshi Uros Bizjak diff --git a/gcc/config/i386/i386-features.c b/gcc/config/i386/i386-features.c index b70757e..8f12bd2 100644 --- a/gcc/config/i386/i386-features.c +++ b/gcc/config/i386/i386-features.c @@ -1425,66 +1425,6 @@ timode_scalar_to_vector_candidate_p (rtx_insn *insn) return false; } -/* For a given bitmap of insn UIDs scans all instruction and - remove insn from CANDIDATES in case it has both convertible - and not convertible definitions. - - All insns in a bitmap are conversion candidates according to - scalar_to_vector_candidate_p. Currently it implies all insns - are single_set. */ - -static void -general_remove_non_convertible_regs (bitmap candidates) -{ - bitmap_iterator bi; - unsigned id; - bitmap regs = BITMAP_ALLOC (NULL); - - EXECUTE_IF_SET_IN_BITMAP (candidates, 0, id, bi) - { - rtx def_set = single_set (DF_INSN_UID_GET (id)->insn); - rtx reg = SET_DEST (def_set); - - if (!REG_P (reg) - || bitmap_bit_p (regs, REGNO (reg)) - || HARD_REGISTER_P (reg)) - continue; - - for (df_ref def = DF_REG_DEF_CHAIN (REGNO (reg)); - def; - def = DF_REF_NEXT_REG (def)) - { - if (!bitmap_bit_p (candidates, DF_REF_INSN_UID (def))) - { - if (dump_file) - fprintf (dump_file, - "r%d has non convertible definition in insn %d\n", - REGNO (reg), DF_REF_INSN_UID (def)); - - bitmap_set_bit (regs, REGNO (reg)); - break; - } - } - } - - EXECUTE_IF_SET_IN_BITMAP (regs, 0, id, bi) - { - for (df_ref def = DF_REG_DEF_CHAIN (id); - def; - def = DF_REF_NEXT_REG (def)) - if (bitmap_bit_p (candidates, DF_REF_INSN_UID (def))) - { - if (dump_file) - fprintf (dump_file, "Removing insn %d from candidates list\n", - DF_REF_INSN_UID (def)); - - bitmap_clear_bit (candidates, DF_REF_INSN_UID (def)); - } - } - - BITMAP_FREE (regs); -} - /* For a register REGNO, scan instructions for its defs and uses. Put REGNO in REGS if a def or use isn't in CANDIDATES. */ @@ -1646,8 +1586,6 @@ convert_scalars_to_vector (bool timode_p) if (timode_p) timode_remove_non_convertible_regs (&candidates[2]); - for (unsigned i = 0; i <= 1; ++i) - general_remove_non_convertible_regs (&candidates[i]); for (unsigned i = 0; i <= 2; ++i) if (!bitmap_empty_p (&candidates[i])) -- cgit v1.1 From 7d349dd8e87c7f0bcfd1e03911035b578220c50f Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Mon, 26 Aug 2019 14:39:08 +0000 Subject: PR c++/91545 - ICE in constexpr store evaluation. * constexpr.c (cxx_eval_store_expression): Check FIELD_DECL instead of DECL_P. * g++.dg/cpp0x/pr91545.C: New test. From-SVN: r274930 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/constexpr.c | 2 +- gcc/testsuite/ChangeLog | 9 +++++++-- gcc/testsuite/g++.dg/cpp0x/pr91545.C | 5 +++++ 4 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/pr91545.C (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 013de12..f0eb35c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2019-08-26 Marek Polacek + + PR c++/91545 - ICE in constexpr store evaluation. + * constexpr.c (cxx_eval_store_expression): Check FIELD_DECL instead + of DECL_P. + 2019-08-24 Nathan Sidwell * class.c (check_for_overrides): Conversion operators need diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index dbd0dc3..6c547d6 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -3849,7 +3849,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, { tree ob = TREE_OPERAND (probe, 0); tree elt = TREE_OPERAND (probe, 1); - if (DECL_P (elt) && DECL_MUTABLE_P (elt)) + if (TREE_CODE (elt) == FIELD_DECL && DECL_MUTABLE_P (elt)) mutable_p = true; if (evaluated && modifying_const_object_p (TREE_CODE (t), probe, mutable_p) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b5a2d7b..fab9d33 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-08-26 Marek Polacek + + PR c++/91545 - ICE in constexpr store evaluation. + * g++.dg/cpp0x/pr91545.C: New test. + 2019-08-26 Tejas Joshi * gcc.target/i386/sse4_1-round-roundeven-1.c: New test. @@ -5,8 +10,8 @@ 2019-08-26 Tejas Joshi - * gcc.dg/torture/builtin-round-roundeven.c: New test. - * gcc.dg/torture/builtin-round-roundevenf128.c: Likewise. + * gcc.dg/torture/builtin-round-roundeven.c: New test. + * gcc.dg/torture/builtin-round-roundevenf128.c: Likewise. 2019-08-26 Robin Dapp diff --git a/gcc/testsuite/g++.dg/cpp0x/pr91545.C b/gcc/testsuite/g++.dg/cpp0x/pr91545.C new file mode 100644 index 0000000..2aa1fa1 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/pr91545.C @@ -0,0 +1,5 @@ +// PR c++/91545 +// { dg-do compile { target c++11 } } + +long a[1]; +int d, e { d && (a[d] = 0) }; -- cgit v1.1 From f7cf1751a9389bf5b1d69b41b07d31c1cfd9761d Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Mon, 26 Aug 2019 17:29:28 +0200 Subject: * ChangeLog: Fix roundeven entry. From-SVN: r274931 --- gcc/ChangeLog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c61f338..b2c9767 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -18,8 +18,8 @@ (ix86_emit_mode_set): Likewise. (emit_i387_cw_initialization): Add case I387_CW_ROUNDEVEN. * config/i386/i386.h (ix86_stack_slot): Add SLOT_CW_ROUNDEVEN. - (ix86_entry): Add I387_ROUNDEVEN. - (avx_u128_state): Add I387_CW_ANY. + (ix86_entity): Add I387_ROUNDEVEN. + (NUM_MODES_FOR_MODE_SWITCHING): Add I387_CW_ANY. * config/i386/i386.md: Define UNSPEC_FRNDINT_ROUNDEVEN. (define_int_iterator): Likewise. (define_int_attr): Likewise for rounding_insn, rounding and ROUNDING. -- cgit v1.1 From 59bce4ad03e438e81dcaa8ed956fbad6461c7d75 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 26 Aug 2019 14:03:26 -0400 Subject: * decl.c (duplicate_decls): Always merge DECL_DECLARED_CONSTEXPR_P. From-SVN: r274932 --- gcc/cp/ChangeLog | 4 ++++ gcc/cp/decl.c | 5 ++--- gcc/testsuite/g++.dg/cpp0x/constexpr-redeclaration2.C | 5 +++++ 3 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-redeclaration2.C (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f0eb35c..162b2c8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,7 @@ +2019-08-26 Jason Merrill + + * decl.c (duplicate_decls): Always merge DECL_DECLARED_CONSTEXPR_P. + 2019-08-26 Marek Polacek PR c++/91545 - ICE in constexpr store evaluation. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 9f79238..8478170 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -2204,9 +2204,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) SET_DECL_DEPENDENT_INIT_P (newdecl, true); DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (newdecl) |= DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (olddecl); - if (DECL_CLASS_SCOPE_P (olddecl)) - DECL_DECLARED_CONSTEXPR_P (newdecl) - |= DECL_DECLARED_CONSTEXPR_P (olddecl); + DECL_DECLARED_CONSTEXPR_P (newdecl) + |= DECL_DECLARED_CONSTEXPR_P (olddecl); /* Merge the threadprivate attribute from OLDDECL into NEWDECL. */ if (DECL_LANG_SPECIFIC (olddecl) diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-redeclaration2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-redeclaration2.C new file mode 100644 index 0000000..3d492fa --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-redeclaration2.C @@ -0,0 +1,5 @@ +// { dg-do compile { target c++11 } } + +constexpr float pi = 3.14; +extern const float pi; +constexpr float x = pi; -- cgit v1.1 From 22fca489eaf98f2691772b51773a1e4eb7bb4ef2 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Mon, 26 Aug 2019 18:29:45 +0000 Subject: PR tree-optimization/83431 - -Wformat-truncation may incorrectly report truncation gcc/ChangeLog: PR c++/83431 * gimple-ssa-sprintf.c (pass_data_sprintf_length): Remove object. (sprintf_dom_walker): Remove class. (get_int_range): Make argument const. (directive::fmtfunc, directive::set_precision): Same. (format_none): Same. (build_intmax_type_nodes): Same. (adjust_range_for_overflow): Same. (format_floating): Same. (format_character): Same. (format_string): Same. (format_plain): Same. (get_int_range): Cast away constness. (format_integer): Same. (get_string_length): Call get_range_strlen_dynamic. Handle null lendata.maxbound. (should_warn_p): Adjust argument scope qualifier. (maybe_warn): Same. (format_directive): Same. (parse_directive): Same. (is_call_safe): Same. (try_substitute_return_value): Same. (sprintf_dom_walker::handle_printf_call): Rename... (handle_printf_call): ...to this. Initialize target to host charmap here instead of in pass_sprintf_length::execute. (struct call_info): Make global. (sprintf_dom_walker::compute_format_length): Make global. (sprintf_dom_walker::handle_gimple_call): Same. * passes.def (pass_sprintf_length): Replace with pass_strlen. * print-rtl.c (print_pattern): Reduce the number of spaces to avoid -Wformat-truncation. * tree-pass.h (make_pass_warn_printf): New function. * tree-ssa-strlen.c (strlen_optimize): New variable. (get_string_length): Add comments. (get_range_strlen_dynamic): New function. (check_and_optimize_call): New function. (handle_integral_assign): New function. (strlen_check_and_optimize_stmt): Factor code out into strlen_check_and_optimize_call and handle_integral_assign. (strlen_dom_walker::evrp): New member. (strlen_dom_walker::before_dom_children): Use evrp member. (strlen_dom_walker::after_dom_children): Use evrp member. (printf_strlen_execute): New function. (pass_strlen::gate): Update to handle printf calls. (dump_strlen_info): New function. (pass_data_warn_printf): New variable. (pass_warn_printf): New class. * tree-ssa-strlen.h (get_range_strlen_dynamic): Declare. (handle_printf_call): Same. * tree-vrp.c (value_range_base::type): Adjust assertion. * vr-values.c (vr_values::update_value_range): Use type of the first argument rather than the second. gcc/testsuite/ChangeLog: PR c++/83431 * gcc.dg/strlenopt-63.c: New test. * gcc.dg/pr79538.c: Adjust text of expected warning. * gcc.dg/pr81292-1.c: Adjust pass name. * gcc.dg/pr81292-2.c: Same. * gcc.dg/pr81703.c: Same. * gcc.dg/strcmpopt_2.c: Same. * gcc.dg/strcmpopt_3.c: Same. * gcc.dg/strcmpopt_4.c: Same. * gcc.dg/strlenopt-1.c: Same. * gcc.dg/strlenopt-10.c: Same. * gcc.dg/strlenopt-11.c: Same. * gcc.dg/strlenopt-13.c: Same. * gcc.dg/strlenopt-14g.c: Same. * gcc.dg/strlenopt-14gf.c: Same. * gcc.dg/strlenopt-15.c: Same. * gcc.dg/strlenopt-16g.c: Same. * gcc.dg/strlenopt-17g.c: Same. * gcc.dg/strlenopt-18g.c: Same. * gcc.dg/strlenopt-19.c: Same. * gcc.dg/strlenopt-1f.c: Same. * gcc.dg/strlenopt-2.c: Same. * gcc.dg/strlenopt-20.c: Same. * gcc.dg/strlenopt-21.c: Same. * gcc.dg/strlenopt-22.c: Same. * gcc.dg/strlenopt-22g.c: Same. * gcc.dg/strlenopt-24.c: Same. * gcc.dg/strlenopt-25.c: Same. * gcc.dg/strlenopt-26.c: Same. * gcc.dg/strlenopt-27.c: Same. * gcc.dg/strlenopt-28.c: Same. * gcc.dg/strlenopt-29.c: Same. * gcc.dg/strlenopt-2f.c: Same. * gcc.dg/strlenopt-3.c: Same. * gcc.dg/strlenopt-30.c: Same. * gcc.dg/strlenopt-31g.c: Same. * gcc.dg/strlenopt-32.c: Same. * gcc.dg/strlenopt-33.c: Same. * gcc.dg/strlenopt-33g.c: Same. * gcc.dg/strlenopt-34.c: Same. * gcc.dg/strlenopt-35.c: Same. * gcc.dg/strlenopt-4.c: Same. * gcc.dg/strlenopt-48.c: Same. * gcc.dg/strlenopt-49.c: Same. * gcc.dg/strlenopt-4g.c: Same. * gcc.dg/strlenopt-4gf.c: Same. * gcc.dg/strlenopt-5.c: Same. * gcc.dg/strlenopt-50.c: Same. * gcc.dg/strlenopt-51.c: Same. * gcc.dg/strlenopt-52.c: Same. * gcc.dg/strlenopt-53.c: Same. * gcc.dg/strlenopt-54.c: Same. * gcc.dg/strlenopt-55.c: Same. * gcc.dg/strlenopt-56.c: Same. * gcc.dg/strlenopt-6.c: Same. * gcc.dg/strlenopt-61.c: Same. * gcc.dg/strlenopt-7.c: Same. * gcc.dg/strlenopt-8.c: Same. * gcc.dg/strlenopt-9.c: Same. * gcc.dg/strlenopt.h (snprintf, snprintf): Declare. * gcc.dg/tree-ssa/builtin-snprintf-6.c: New test. * gcc.dg/tree-ssa/builtin-snprintf-7.c: New test. * gcc.dg/tree-ssa/builtin-snprintf-8.c: New test. * gcc.dg/tree-ssa/builtin-snprintf-9.c: New test. * gcc.dg/tree-ssa/builtin-sprintf-warn-21.c: New test. * gcc.dg/tree-ssa/dump-4.c: New test. * gcc.dg/tree-ssa/pr83501.c: Adjust pass name. From-SVN: r274933 --- gcc/ChangeLog | 55 ++ gcc/gimple-ssa-sprintf.c | 263 ++---- gcc/passes.def | 5 +- gcc/print-rtl.c | 2 +- gcc/testsuite/ChangeLog | 70 ++ gcc/testsuite/gcc.dg/pr79538.c | 2 +- gcc/testsuite/gcc.dg/pr81292-1.c | 2 +- gcc/testsuite/gcc.dg/pr81292-2.c | 2 +- gcc/testsuite/gcc.dg/pr81703.c | 2 +- gcc/testsuite/gcc.dg/strcmpopt_2.c | 2 +- gcc/testsuite/gcc.dg/strcmpopt_3.c | 2 +- gcc/testsuite/gcc.dg/strcmpopt_4.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-1.c | 12 +- gcc/testsuite/gcc.dg/strlenopt-10.c | 18 +- gcc/testsuite/gcc.dg/strlenopt-11.c | 22 +- gcc/testsuite/gcc.dg/strlenopt-13.c | 24 +- gcc/testsuite/gcc.dg/strlenopt-14g.c | 14 +- gcc/testsuite/gcc.dg/strlenopt-14gf.c | 24 +- gcc/testsuite/gcc.dg/strlenopt-15.c | 12 +- gcc/testsuite/gcc.dg/strlenopt-16g.c | 14 +- gcc/testsuite/gcc.dg/strlenopt-17g.c | 14 +- gcc/testsuite/gcc.dg/strlenopt-18g.c | 12 +- gcc/testsuite/gcc.dg/strlenopt-19.c | 12 +- gcc/testsuite/gcc.dg/strlenopt-1f.c | 20 +- gcc/testsuite/gcc.dg/strlenopt-2.c | 12 +- gcc/testsuite/gcc.dg/strlenopt-20.c | 12 +- gcc/testsuite/gcc.dg/strlenopt-21.c | 12 +- gcc/testsuite/gcc.dg/strlenopt-22.c | 12 +- gcc/testsuite/gcc.dg/strlenopt-22g.c | 12 +- gcc/testsuite/gcc.dg/strlenopt-24.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-25.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-26.c | 4 +- gcc/testsuite/gcc.dg/strlenopt-27.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-28.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-29.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-2f.c | 20 +- gcc/testsuite/gcc.dg/strlenopt-3.c | 12 +- gcc/testsuite/gcc.dg/strlenopt-30.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-31g.c | 6 +- gcc/testsuite/gcc.dg/strlenopt-32.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-33.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-33g.c | 4 +- gcc/testsuite/gcc.dg/strlenopt-34.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-35.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-4.c | 12 +- gcc/testsuite/gcc.dg/strlenopt-48.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-49.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-4g.c | 12 +- gcc/testsuite/gcc.dg/strlenopt-4gf.c | 20 +- gcc/testsuite/gcc.dg/strlenopt-5.c | 12 +- gcc/testsuite/gcc.dg/strlenopt-50.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-51.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-52.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-53.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-54.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-55.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-56.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-6.c | 12 +- gcc/testsuite/gcc.dg/strlenopt-61.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-68.c | 382 +++++++++ gcc/testsuite/gcc.dg/strlenopt-7.c | 14 +- gcc/testsuite/gcc.dg/strlenopt-9.c | 12 +- gcc/testsuite/gcc.dg/strlenopt.h | 5 +- gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-6.c | 139 ++++ gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-7.c | 152 ++++ gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-8.c | 41 + gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-9.c | 163 ++++ .../gcc.dg/tree-ssa/builtin-snprintf-warn-5.c | 140 ++++ .../gcc.dg/tree-ssa/builtin-sprintf-warn-21.c | 94 +++ gcc/testsuite/gcc.dg/tree-ssa/dump-4.c | 11 + gcc/testsuite/gcc.dg/tree-ssa/pr83501.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/strlen-2.c | 2 +- gcc/tree-pass.h | 1 + gcc/tree-ssa-strlen.c | 905 ++++++++++++++++----- gcc/tree-ssa-strlen.h | 7 + gcc/tree-vrp.c | 2 +- gcc/vr-values.c | 2 +- 77 files changed, 2264 insertions(+), 631 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/strlenopt-68.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-6.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-7.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-8.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-9.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-warn-5.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-21.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/dump-4.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b2c9767..852382e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,58 @@ +2019-08-23 Martin Sebor + + PR c++/83431 + * gimple-ssa-sprintf.c (pass_data_sprintf_length): Remove object. + (sprintf_dom_walker): Remove class. + (get_int_range): Make argument const. + (directive::fmtfunc, directive::set_precision): Same. + (format_none): Same. + (build_intmax_type_nodes): Same. + (adjust_range_for_overflow): Same. + (format_floating): Same. + (format_character): Same. + (format_string): Same. + (format_plain): Same. + (get_int_range): Cast away constness. + (format_integer): Same. + (get_string_length): Call get_range_strlen_dynamic. Handle + null lendata.maxbound. + (should_warn_p): Adjust argument scope qualifier. + (maybe_warn): Same. + (format_directive): Same. + (parse_directive): Same. + (is_call_safe): Same. + (try_substitute_return_value): Same. + (sprintf_dom_walker::handle_printf_call): Rename... + (handle_printf_call): ...to this. Initialize target to host charmap + here instead of in pass_sprintf_length::execute. + (struct call_info): Make global. + (sprintf_dom_walker::compute_format_length): Make global. + (sprintf_dom_walker::handle_gimple_call): Same. + * passes.def (pass_sprintf_length): Replace with pass_strlen. + * print-rtl.c (print_pattern): Reduce the number of spaces to + avoid -Wformat-truncation. + * tree-pass.h (make_pass_warn_printf): New function. + * tree-ssa-strlen.c (strlen_optimize): New variable. + (get_string_length): Add comments. + (get_range_strlen_dynamic): New function. + (check_and_optimize_call): New function. + (handle_integral_assign): New function. + (strlen_check_and_optimize_stmt): Factor code out into + strlen_check_and_optimize_call and handle_integral_assign. + (strlen_dom_walker::evrp): New member. + (strlen_dom_walker::before_dom_children): Use evrp member. + (strlen_dom_walker::after_dom_children): Use evrp member. + (printf_strlen_execute): New function. + (pass_strlen::gate): Update to handle printf calls. + (dump_strlen_info): New function. + (pass_data_warn_printf): New variable. + (pass_warn_printf): New class. + * tree-ssa-strlen.h (get_range_strlen_dynamic): Declare. + (handle_printf_call): Same. + * tree-vrp.c (value_range_base::type): Adjust assertion. + * vr-values.c (vr_values::update_value_range): Use type of the first + argument rather than the second. + 2019-08-26 Richard Biener * config/i386/i386-features.c (general_remove_non_convertible_regs): diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c index 88ba1f2..6a39a71 100644 --- a/gcc/gimple-ssa-sprintf.c +++ b/gcc/gimple-ssa-sprintf.c @@ -85,7 +85,7 @@ along with GCC; see the file COPYING3. If not see #include "domwalk.h" #include "alloc-pool.h" #include "vr-values.h" -#include "gimple-ssa-evrp-analyze.h" +#include "tree-ssa-strlen.h" /* The likely worst case value of MB_LEN_MAX for the target, large enough for UTF-8. Ideally, this would be obtained by a target hook if it were @@ -100,80 +100,15 @@ along with GCC; see the file COPYING3. If not see namespace { -const pass_data pass_data_sprintf_length = { - GIMPLE_PASS, // pass type - "printf-return-value", // pass name - OPTGROUP_NONE, // optinfo_flags - TV_NONE, // tv_id - PROP_cfg, // properties_required - 0, // properties_provided - 0, // properties_destroyed - 0, // properties_start - 0, // properties_finish -}; - /* Set to the warning level for the current function which is equal either to warn_format_trunc for bounded functions or to warn_format_overflow otherwise. */ static int warn_level; +struct call_info; struct format_result; -class sprintf_dom_walker : public dom_walker -{ - public: - sprintf_dom_walker () - : dom_walker (CDI_DOMINATORS), - evrp_range_analyzer (false) {} - ~sprintf_dom_walker () {} - - edge before_dom_children (basic_block) FINAL OVERRIDE; - void after_dom_children (basic_block) FINAL OVERRIDE; - bool handle_gimple_call (gimple_stmt_iterator *); - - struct call_info; - bool compute_format_length (call_info &, format_result *); - class evrp_range_analyzer evrp_range_analyzer; -}; - -class pass_sprintf_length : public gimple_opt_pass -{ - bool fold_return_value; - -public: - pass_sprintf_length (gcc::context *ctxt) - : gimple_opt_pass (pass_data_sprintf_length, ctxt), - fold_return_value (false) - { } - - opt_pass * clone () { return new pass_sprintf_length (m_ctxt); } - - virtual bool gate (function *); - - virtual unsigned int execute (function *); - - void set_pass_param (unsigned int n, bool param) - { - gcc_assert (n == 0); - fold_return_value = param; - } - -}; - -bool -pass_sprintf_length::gate (function *) -{ - /* Run the pass iff -Warn-format-overflow or -Warn-format-truncation - is specified and either not optimizing and the pass is being invoked - early, or when optimizing and the pass is being invoked during - optimization (i.e., "late"). */ - return ((warn_format_overflow > 0 - || warn_format_trunc > 0 - || flag_printf_return_value) - && (optimize > 0) == fold_return_value); -} - /* The minimum, maximum, likely, and unlikely maximum number of bytes of output either a formatting function or an individual directive can result in. */ @@ -684,7 +619,7 @@ fmtresult::type_max_digits (tree type, int base) static bool get_int_range (tree, HOST_WIDE_INT *, HOST_WIDE_INT *, bool, HOST_WIDE_INT, - class vr_values *vr_values); + const vr_values *); /* Description of a format directive. A directive is either a plain string or a conversion specification that starts with '%'. */ @@ -719,7 +654,7 @@ struct directive /* Format conversion function that given a directive and an argument returns the formatting result. */ - fmtresult (*fmtfunc) (const directive &, tree, vr_values *); + fmtresult (*fmtfunc) (const directive &, tree, const vr_values *); /* Return True when a the format flag CHR has been used. */ bool get_flag (char chr) const @@ -756,9 +691,9 @@ struct directive or 0, whichever is greater. For a non-constant ARG in some range set width to its range adjusting each bound to -1 if it's less. For an indeterminate ARG set width to [0, INT_MAX]. */ - void set_width (tree arg, vr_values *vr_values) + void set_width (tree arg, const vr_values *vr) { - get_int_range (arg, width, width + 1, true, 0, vr_values); + get_int_range (arg, width, width + 1, true, 0, vr); } /* Set both bounds of the precision range to VAL. */ @@ -772,9 +707,9 @@ struct directive or -1 whichever is greater. For a non-constant ARG in some range set precision to its range adjusting each bound to -1 if it's less. For an indeterminate ARG set precision to [-1, INT_MAX]. */ - void set_precision (tree arg, vr_values *vr_values) + void set_precision (tree arg, const vr_values *vr) { - get_int_range (arg, prec, prec + 1, false, -1, vr_values); + get_int_range (arg, prec, prec + 1, false, -1, vr); } /* Return true if both width and precision are known to be @@ -904,7 +839,7 @@ bytes_remaining (unsigned HOST_WIDE_INT navail, const format_result &res) /* Description of a call to a formatted function. */ -struct sprintf_dom_walker::call_info +struct call_info { /* Function call statement. */ gimple *callstmt; @@ -978,7 +913,7 @@ struct sprintf_dom_walker::call_info /* Return the result of formatting a no-op directive (such as '%n'). */ static fmtresult -format_none (const directive &, tree, vr_values *) +format_none (const directive &, tree, const vr_values *) { fmtresult res (0); return res; @@ -987,7 +922,7 @@ format_none (const directive &, tree, vr_values *) /* Return the result of formatting the '%%' directive. */ static fmtresult -format_percent (const directive &, tree, vr_values *) +format_percent (const directive &, tree, const vr_values *) { fmtresult res (1); return res; @@ -1047,7 +982,7 @@ build_intmax_type_nodes (tree *pintmax, tree *puintmax) static bool get_int_range (tree arg, HOST_WIDE_INT *pmin, HOST_WIDE_INT *pmax, bool absolute, HOST_WIDE_INT negbound, - class vr_values *vr_values) + const class vr_values *vr_values) { /* The type of the result. */ const_tree type = integer_type_node; @@ -1086,7 +1021,9 @@ get_int_range (tree arg, HOST_WIDE_INT *pmin, HOST_WIDE_INT *pmax, && TYPE_PRECISION (argtype) <= TYPE_PRECISION (type)) { /* Try to determine the range of values of the integer argument. */ - const value_range *vr = vr_values->get_value_range (arg); + const value_range *vr + = CONST_CAST (class vr_values *, vr_values)->get_value_range (arg); + if (range_int_cst_p (vr)) { HOST_WIDE_INT type_min @@ -1203,7 +1140,7 @@ adjust_range_for_overflow (tree dirtype, tree *argmin, tree *argmax) used when the directive argument or its value isn't known. */ static fmtresult -format_integer (const directive &dir, tree arg, vr_values *vr_values) +format_integer (const directive &dir, tree arg, const vr_values *vr_values) { tree intmax_type_node; tree uintmax_type_node; @@ -1386,7 +1323,9 @@ format_integer (const directive &dir, tree arg, vr_values *vr_values) { /* Try to determine the range of values of the integer argument (range information is not available for pointers). */ - const value_range *vr = vr_values->get_value_range (arg); + const value_range *vr + = CONST_CAST (class vr_values *, vr_values)->get_value_range (arg); + if (range_int_cst_p (vr)) { argmin = vr->min (); @@ -1836,7 +1775,7 @@ format_floating (const directive &dir, const HOST_WIDE_INT prec[2]) ARG. */ static fmtresult -format_floating (const directive &dir, tree arg, vr_values *) +format_floating (const directive &dir, tree arg, const vr_values *) { HOST_WIDE_INT prec[] = { dir.prec[0], dir.prec[1] }; tree type = (dir.modifier == FMT_LEN_L || dir.modifier == FMT_LEN_ll @@ -2030,21 +1969,33 @@ format_floating (const directive &dir, tree arg, vr_values *) Used by the format_string function below. */ static fmtresult -get_string_length (tree str, unsigned eltsize) +get_string_length (tree str, unsigned eltsize, const vr_values *vr) { if (!str) return fmtresult (); - /* Determine the length of the shortest and longest string referenced - by STR. Strings of unknown lengths are bounded by the sizes of - arrays that subexpressions of STR may refer to. Pointers that - aren't known to point any such arrays result in LENDATA.MAXLEN - set to SIZE_MAX. */ + /* Try to determine the dynamic string length first. */ c_strlen_data lendata = { }; - get_range_strlen (str, &lendata, eltsize); + if (eltsize == 1) + get_range_strlen_dynamic (str, &lendata, vr); + else + { + /* Determine the length of the shortest and longest string referenced + by STR. Strings of unknown lengths are bounded by the sizes of + arrays that subexpressions of STR may refer to. Pointers that + aren't known to point any such arrays result in LENDATA.MAXLEN + set to SIZE_MAX. */ + get_range_strlen (str, &lendata, eltsize); + } + + /* LENDATA.MAXBOUND is null when LENDATA.MIN corresponds to the shortest + string referenced by STR. Otherwise, if it's not equal to .MINLEN it + corresponds to the bound of the largest array STR refers to, if known, + or it's SIZE_MAX otherwise. */ - /* Return the default result when nothing is known about the string. */ - if (integer_all_onesp (lendata.maxbound) + /* Return the default result when nothing is known about the string. */ + if (lendata.maxbound + && integer_all_onesp (lendata.maxbound) && integer_all_onesp (lendata.maxlen)) return fmtresult (); @@ -2054,7 +2005,7 @@ get_string_length (tree str, unsigned eltsize) : 0); HOST_WIDE_INT max - = (tree_fits_uhwi_p (lendata.maxbound) + = (lendata.maxbound && tree_fits_uhwi_p (lendata.maxbound) ? tree_to_uhwi (lendata.maxbound) : HOST_WIDE_INT_M1U); @@ -2093,10 +2044,11 @@ get_string_length (tree str, unsigned eltsize) else { /* When the upper bound is unknown (it can be zero or excessive) - set the likely length to the greater of 1 and the length of - the shortest string and reset the lower bound to zero. */ + set the likely length to the greater of 1. If MAXBOUND is + set, also reset the length of the lower bound to zero. */ res.range.likely = res.range.min ? res.range.min : warn_level > 1; - res.range.min = 0; + if (lendata.maxbound) + res.range.min = 0; } res.range.unlikely = unbounded ? HOST_WIDE_INT_MAX : res.range.max; @@ -2110,7 +2062,7 @@ get_string_length (tree str, unsigned eltsize) vsprinf). */ static fmtresult -format_character (const directive &dir, tree arg, vr_values *vr_values) +format_character (const directive &dir, tree arg, const vr_values *vr_values) { fmtresult res; @@ -2186,7 +2138,7 @@ format_character (const directive &dir, tree arg, vr_values *vr_values) vsprinf). */ static fmtresult -format_string (const directive &dir, tree arg, vr_values *) +format_string (const directive &dir, tree arg, const vr_values *vr_values) { fmtresult res; @@ -2204,7 +2156,7 @@ format_string (const directive &dir, tree arg, vr_values *) gcc_checking_assert (count_by == 2 || count_by == 4); } - fmtresult slen = get_string_length (arg, count_by); + fmtresult slen = get_string_length (arg, count_by, vr_values); if (slen.range.min == slen.range.max && slen.range.min < HOST_WIDE_INT_MAX) { @@ -2376,7 +2328,7 @@ format_string (const directive &dir, tree arg, vr_values *) /* Format plain string (part of the format string itself). */ static fmtresult -format_plain (const directive &dir, tree, vr_values *) +format_plain (const directive &dir, tree, const vr_values *) { fmtresult res (dir.len); return res; @@ -2386,7 +2338,7 @@ format_plain (const directive &dir, tree, vr_values *) should be diagnosed given the AVAILable space in the destination. */ static bool -should_warn_p (const sprintf_dom_walker::call_info &info, +should_warn_p (const call_info &info, const result_range &avail, const result_range &result) { if (result.max <= avail.min) @@ -2457,7 +2409,7 @@ should_warn_p (const sprintf_dom_walker::call_info &info, static bool maybe_warn (substring_loc &dirloc, location_t argloc, - const sprintf_dom_walker::call_info &info, + const call_info &info, const result_range &avail_range, const result_range &res, const directive &dir) { @@ -2737,9 +2689,9 @@ maybe_warn (substring_loc &dirloc, location_t argloc, in *RES. Return true if the directive has been handled. */ static bool -format_directive (const sprintf_dom_walker::call_info &info, +format_directive (const call_info &info, format_result *res, const directive &dir, - class vr_values *vr_values) + const class vr_values *vr_values) { /* Offset of the beginning of the directive from the beginning of the format string. */ @@ -3086,10 +3038,10 @@ format_directive (const sprintf_dom_walker::call_info &info, the directive. */ static size_t -parse_directive (sprintf_dom_walker::call_info &info, +parse_directive (call_info &info, directive &dir, format_result *res, const char *str, unsigned *argno, - vr_values *vr_values) + const vr_values *vr_values) { const char *pcnt = strchr (str, target_percent); dir.beg = str; @@ -3526,9 +3478,8 @@ parse_directive (sprintf_dom_walker::call_info &info, on, false otherwise (e.g., when a unknown or unhandled directive was seen that caused the processing to be terminated early). */ -bool -sprintf_dom_walker::compute_format_length (call_info &info, - format_result *res) +static bool +compute_format_length (call_info &info, format_result *res, const vr_values *vr) { if (dump_file) { @@ -3564,12 +3515,10 @@ sprintf_dom_walker::compute_format_length (call_info &info, directive dir = directive (); dir.dirno = dirno; - size_t n = parse_directive (info, dir, res, pf, &argno, - evrp_range_analyzer.get_vr_values ()); + size_t n = parse_directive (info, dir, res, pf, &argno, vr); /* Return failure if the format function fails. */ - if (!format_directive (info, res, dir, - evrp_range_analyzer.get_vr_values ())) + if (!format_directive (info, res, dir, vr)) return false; /* Return success the directive is zero bytes long and it's @@ -3617,7 +3566,7 @@ get_destination_size (tree dest) of its return values. */ static bool -is_call_safe (const sprintf_dom_walker::call_info &info, +is_call_safe (const call_info &info, const format_result &res, bool under4k, unsigned HOST_WIDE_INT retval[2]) { @@ -3676,7 +3625,7 @@ is_call_safe (const sprintf_dom_walker::call_info &info, static bool try_substitute_return_value (gimple_stmt_iterator *gsi, - const sprintf_dom_walker::call_info &info, + const call_info &info, const format_result &res) { tree lhs = gimple_get_lhs (info.callstmt); @@ -3794,7 +3743,7 @@ try_substitute_return_value (gimple_stmt_iterator *gsi, static bool try_simplify_call (gimple_stmt_iterator *gsi, - const sprintf_dom_walker::call_info &info, + const call_info &info, const format_result &res) { unsigned HOST_WIDE_INT dummy[2]; @@ -3847,13 +3796,17 @@ get_user_idx_format (tree fndecl, unsigned *idx_args) return tree_to_uhwi (fmtarg) - 1; } -/* Determine if a GIMPLE CALL is to one of the sprintf-like built-in - functions and if so, handle it. Return true if the call is removed - and gsi_next should not be performed in the caller. */ +} /* Unnamed namespace. */ + +/* Determine if a GIMPLE call at *GSI is to one of the sprintf-like built-in + functions and if so, handle it. Return true if the call is removed and + gsi_next should not be performed in the caller. */ bool -sprintf_dom_walker::handle_gimple_call (gimple_stmt_iterator *gsi) +handle_printf_call (gimple_stmt_iterator *gsi, const vr_values *vr_values) { + init_target_to_host_charmap (); + call_info info = call_info (); info.callstmt = gsi_stmt (*gsi); @@ -4119,7 +4072,9 @@ sprintf_dom_walker::handle_gimple_call (gimple_stmt_iterator *gsi) /* Try to determine the range of values of the argument and use the greater of the two at level 1 and the smaller of them at level 2. */ - const value_range *vr = evrp_range_analyzer.get_value_range (size); + const value_range *vr + = CONST_CAST (class vr_values *, vr_values)->get_value_range (size); + if (range_int_cst_p (vr)) { unsigned HOST_WIDE_INT minsize = TREE_INT_CST_LOW (vr->min ()); @@ -4230,7 +4185,7 @@ sprintf_dom_walker::handle_gimple_call (gimple_stmt_iterator *gsi) never set to true again). */ res.posunder4k = posunder4k && dstptr; - bool success = compute_format_length (info, &res); + bool success = compute_format_length (info, &res, vr_values); if (res.warned) gimple_set_no_warning (info.callstmt, true); @@ -4256,71 +4211,3 @@ sprintf_dom_walker::handle_gimple_call (gimple_stmt_iterator *gsi) return call_removed; } - -edge -sprintf_dom_walker::before_dom_children (basic_block bb) -{ - evrp_range_analyzer.enter (bb); - for (gimple_stmt_iterator si = gsi_start_bb (bb); !gsi_end_p (si); ) - { - /* Iterate over statements, looking for function calls. */ - gimple *stmt = gsi_stmt (si); - - /* First record ranges generated by this statement. */ - evrp_range_analyzer.record_ranges_from_stmt (stmt, false); - - if (is_gimple_call (stmt) && handle_gimple_call (&si)) - /* If handle_gimple_call returns true, the iterator is - already pointing to the next statement. */ - continue; - - gsi_next (&si); - } - return NULL; -} - -void -sprintf_dom_walker::after_dom_children (basic_block bb) -{ - evrp_range_analyzer.leave (bb); -} - -/* Execute the pass for function FUN. */ - -unsigned int -pass_sprintf_length::execute (function *fun) -{ - init_target_to_host_charmap (); - - calculate_dominance_info (CDI_DOMINATORS); - bool use_scev = optimize > 0 && flag_printf_return_value; - if (use_scev) - { - loop_optimizer_init (LOOPS_NORMAL); - scev_initialize (); - } - - sprintf_dom_walker sprintf_dom_walker; - sprintf_dom_walker.walk (ENTRY_BLOCK_PTR_FOR_FN (fun)); - - if (use_scev) - { - scev_finalize (); - loop_optimizer_finalize (); - } - - /* Clean up object size info. */ - fini_object_sizes (); - return 0; -} - -} /* Unnamed namespace. */ - -/* Return a pointer to a pass object newly constructed from the context - CTXT. */ - -gimple_opt_pass * -make_pass_sprintf_length (gcc::context *ctxt) -{ - return new pass_sprintf_length (ctxt); -} diff --git a/gcc/passes.def b/gcc/passes.def index fe5a411..e50cf62 100644 --- a/gcc/passes.def +++ b/gcc/passes.def @@ -42,7 +42,7 @@ along with GCC; see the file COPYING3. If not see NEXT_PASS (pass_build_cfg); NEXT_PASS (pass_warn_function_return); NEXT_PASS (pass_expand_omp); - NEXT_PASS (pass_sprintf_length, false); + NEXT_PASS (pass_warn_printf); NEXT_PASS (pass_walloca, /*strict_mode_p=*/true); NEXT_PASS (pass_build_cgraph_edges); TERMINATE_PASS_LIST (all_lowering_passes) @@ -307,7 +307,6 @@ along with GCC; see the file COPYING3. If not see NEXT_PASS (pass_lower_vector_ssa); NEXT_PASS (pass_lower_switch); NEXT_PASS (pass_cse_reciprocals); - NEXT_PASS (pass_sprintf_length, true); NEXT_PASS (pass_reassoc, false /* insert_powi_p */); NEXT_PASS (pass_strength_reduction); NEXT_PASS (pass_split_paths); @@ -358,7 +357,7 @@ along with GCC; see the file COPYING3. If not see NEXT_PASS (pass_object_sizes); /* Fold remaining builtins. */ NEXT_PASS (pass_fold_builtins); - NEXT_PASS (pass_sprintf_length, true); + NEXT_PASS (pass_strlen); /* Copy propagation also copy-propagates constants, this is necessary to forward object-size and builtin folding results properly. */ NEXT_PASS (pass_copy_prop); diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c index 10948ef..b96ab5e 100644 --- a/gcc/print-rtl.c +++ b/gcc/print-rtl.c @@ -1815,7 +1815,7 @@ print_pattern (pretty_printer *pp, const_rtx x, int verbose) gcc_assert (strlen (print_rtx_head) < sizeof (indented_print_rtx_head) - 4); snprintf (indented_print_rtx_head, sizeof (indented_print_rtx_head), - "%s ", print_rtx_head); + "%s ", print_rtx_head); print_rtx_head = indented_print_rtx_head; for (int i = 0; i < seq->len (); i++) print_insn_with_notes (pp, seq->insn (i)); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fab9d33..9bdc2f9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -79,6 +79,76 @@ 2019-08-23 Martin Sebor + PR c++/83431 + * gcc.dg/strlenopt-63.c: New test. + * gcc.dg/pr79538.c: Adjust text of expected warning. + * gcc.dg/pr81292-1.c: Adjust pass name. + * gcc.dg/pr81292-2.c: Same. + * gcc.dg/pr81703.c: Same. + * gcc.dg/strcmpopt_2.c: Same. + * gcc.dg/strcmpopt_3.c: Same. + * gcc.dg/strcmpopt_4.c: Same. + * gcc.dg/strlenopt-1.c: Same. + * gcc.dg/strlenopt-10.c: Same. + * gcc.dg/strlenopt-11.c: Same. + * gcc.dg/strlenopt-13.c: Same. + * gcc.dg/strlenopt-14g.c: Same. + * gcc.dg/strlenopt-14gf.c: Same. + * gcc.dg/strlenopt-15.c: Same. + * gcc.dg/strlenopt-16g.c: Same. + * gcc.dg/strlenopt-17g.c: Same. + * gcc.dg/strlenopt-18g.c: Same. + * gcc.dg/strlenopt-19.c: Same. + * gcc.dg/strlenopt-1f.c: Same. + * gcc.dg/strlenopt-2.c: Same. + * gcc.dg/strlenopt-20.c: Same. + * gcc.dg/strlenopt-21.c: Same. + * gcc.dg/strlenopt-22.c: Same. + * gcc.dg/strlenopt-22g.c: Same. + * gcc.dg/strlenopt-24.c: Same. + * gcc.dg/strlenopt-25.c: Same. + * gcc.dg/strlenopt-26.c: Same. + * gcc.dg/strlenopt-27.c: Same. + * gcc.dg/strlenopt-28.c: Same. + * gcc.dg/strlenopt-29.c: Same. + * gcc.dg/strlenopt-2f.c: Same. + * gcc.dg/strlenopt-3.c: Same. + * gcc.dg/strlenopt-30.c: Same. + * gcc.dg/strlenopt-31g.c: Same. + * gcc.dg/strlenopt-32.c: Same. + * gcc.dg/strlenopt-33.c: Same. + * gcc.dg/strlenopt-33g.c: Same. + * gcc.dg/strlenopt-34.c: Same. + * gcc.dg/strlenopt-35.c: Same. + * gcc.dg/strlenopt-4.c: Same. + * gcc.dg/strlenopt-48.c: Same. + * gcc.dg/strlenopt-49.c: Same. + * gcc.dg/strlenopt-4g.c: Same. + * gcc.dg/strlenopt-4gf.c: Same. + * gcc.dg/strlenopt-5.c: Same. + * gcc.dg/strlenopt-50.c: Same. + * gcc.dg/strlenopt-51.c: Same. + * gcc.dg/strlenopt-52.c: Same. + * gcc.dg/strlenopt-53.c: Same. + * gcc.dg/strlenopt-54.c: Same. + * gcc.dg/strlenopt-55.c: Same. + * gcc.dg/strlenopt-56.c: Same. + * gcc.dg/strlenopt-6.c: Same. + * gcc.dg/strlenopt-61.c: Same. + * gcc.dg/strlenopt-7.c: Same. + * gcc.dg/strlenopt-8.c: Same. + * gcc.dg/strlenopt-9.c: Same. + * gcc.dg/strlenopt.h (snprintf, snprintf): Declare. + * gcc.dg/tree-ssa/builtin-snprintf-6.c: New test. + * gcc.dg/tree-ssa/builtin-snprintf-7.c: New test. + * gcc.dg/tree-ssa/builtin-snprintf-8.c: New test. + * gcc.dg/tree-ssa/builtin-snprintf-9.c: New test. + * gcc.dg/tree-ssa/builtin-sprintf-warn-21.c: New test. + * gcc.dg/tree-ssa/dump-4.c: New test. + * gcc.dg/tree-ssa/pr83501.c: Adjust pass name. + +2019-08-23 Martin Sebor + * gcc.dg/Warray-bounds-36.c: Make functions static to avoid failures with -fpic. * gcc.dg/Warray-bounds-41.c: Same. diff --git a/gcc/testsuite/gcc.dg/pr79538.c b/gcc/testsuite/gcc.dg/pr79538.c index 6cdab45..4f10d97 100644 --- a/gcc/testsuite/gcc.dg/pr79538.c +++ b/gcc/testsuite/gcc.dg/pr79538.c @@ -17,6 +17,6 @@ void f () { char des[3]; char src[] = "abcd"; - __builtin_sprintf (des, "%s", src); /* { dg-warning "directive writing up to 4 bytes into a region of size 3" } */ + __builtin_sprintf (des, "%s", src); /* { dg-warning "directive writing 4 bytes into a region of size 3" } */ return; } diff --git a/gcc/testsuite/gcc.dg/pr81292-1.c b/gcc/testsuite/gcc.dg/pr81292-1.c index 931e4c3..2a454df 100644 --- a/gcc/testsuite/gcc.dg/pr81292-1.c +++ b/gcc/testsuite/gcc.dg/pr81292-1.c @@ -32,4 +32,4 @@ main (void) return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/pr81292-2.c b/gcc/testsuite/gcc.dg/pr81292-2.c index c1c507f..252884a 100644 --- a/gcc/testsuite/gcc.dg/pr81292-2.c +++ b/gcc/testsuite/gcc.dg/pr81292-2.c @@ -32,4 +32,4 @@ main (void) return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 6 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 6 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/pr81703.c b/gcc/testsuite/gcc.dg/pr81703.c index 190f4a8..02edf26 100644 --- a/gcc/testsuite/gcc.dg/pr81703.c +++ b/gcc/testsuite/gcc.dg/pr81703.c @@ -9,4 +9,4 @@ unsigned g (void) return __builtin_strlen (d); } -/* { dg-final { scan-tree-dump-not "__builtin_strlen" "strlen" } } */ +/* { dg-final { scan-tree-dump-not "__builtin_strlen" "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strcmpopt_2.c b/gcc/testsuite/gcc.dg/strcmpopt_2.c index 0131b8f..57d8f65 100644 --- a/gcc/testsuite/gcc.dg/strcmpopt_2.c +++ b/gcc/testsuite/gcc.dg/strcmpopt_2.c @@ -64,4 +64,4 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "cmp_eq \\(" 8 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "cmp_eq \\(" 8 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strcmpopt_3.c b/gcc/testsuite/gcc.dg/strcmpopt_3.c index 86a0d7a..571646c 100644 --- a/gcc/testsuite/gcc.dg/strcmpopt_3.c +++ b/gcc/testsuite/gcc.dg/strcmpopt_3.c @@ -28,4 +28,4 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "strcmp" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strcmp" 0 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strcmpopt_4.c b/gcc/testsuite/gcc.dg/strcmpopt_4.c index d727bc3..4e26522 100644 --- a/gcc/testsuite/gcc.dg/strcmpopt_4.c +++ b/gcc/testsuite/gcc.dg/strcmpopt_4.c @@ -13,4 +13,4 @@ f1 (S * s) return result; } -/* { dg-final { scan-tree-dump-times "cmp_eq \\(" 1 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "cmp_eq \\(" 1 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-1.c b/gcc/testsuite/gcc.dg/strlenopt-1.c index 910ec67..24772c1 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-1.c +++ b/gcc/testsuite/gcc.dg/strlenopt-1.c @@ -36,9 +36,9 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-10.c b/gcc/testsuite/gcc.dg/strlenopt-10.c index 97167df..ce959c3 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-10.c +++ b/gcc/testsuite/gcc.dg/strlenopt-10.c @@ -69,14 +69,14 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */ /* avr has BIGGEST_ALIGNMENT 8, allowing fold_builtin_memory_op to expand the memcpy call at the end of fn2. */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 8 "strlen" { target { ! avr-*-* } } } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen" { target { avr-*-* } } } } */ -/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "\\*q_\[0-9\]* = 32;" 1 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(\[^\n\r\]*, 1\\)" 1 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 8 "strlen1" { target { ! avr-*-* } } } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen1" { target { avr-*-* } } } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "\\*q_\[0-9\]* = 32;" 1 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(\[^\n\r\]*, 1\\)" 1 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-11.c b/gcc/testsuite/gcc.dg/strlenopt-11.c index f7fa44b..abd9fae 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-11.c +++ b/gcc/testsuite/gcc.dg/strlenopt-11.c @@ -58,18 +58,18 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 3 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 3 "strlen1" } } */ /* avr has BIGGEST_ALIGNMENT 8, allowing fold_builtin_memory_op to expand the memcpy call at the end of fn1. */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen" { target { ! avr-*-* } } } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen" { target { avr-*-* } } } } */ -/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen1" { target { ! avr-*-* } } } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen1" { target { avr-*-* } } } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */ /* Where the memcpy is expanded, the assignemts to elements of l are propagated. */ -/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.0. = " 1 "strlen" { target { ! avr-*-* } } } } */ -/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.6. = " 1 "strlen" { target { ! avr-*-* } } } } */ -/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.9. = " 1 "strlen" { target { ! avr-*-* } } } } */ -/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;" 3 "strlen" { target { avr-*-* } } } } */ +/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.0. = " 1 "strlen1" { target { ! avr-*-* } } } } */ +/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.6. = " 1 "strlen1" { target { ! avr-*-* } } } } */ +/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.9. = " 1 "strlen1" { target { ! avr-*-* } } } } */ +/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;" 3 "strlen1" { target { avr-*-* } } } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-13.c b/gcc/testsuite/gcc.dg/strlenopt-13.c index 3502599..27ecc79 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-13.c +++ b/gcc/testsuite/gcc.dg/strlenopt-13.c @@ -55,19 +55,19 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen1" } } */ /* avr has BIGGEST_ALIGNMENT 8, allowing fold_builtin_memory_op to expand the memcpy call at the end of fn1. */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen" { target { ! avr-*-* } } } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen" { target { avr-*-* } } } } */ -/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen1" { target { ! avr-*-* } } } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen1" { target { avr-*-* } } } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */ /* Where the memcpy is expanded, the assignemts to elements of l are propagated. */ -/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.0. = " 1 "strlen" { target { ! avr-*-* } } } } */ -/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.1. = " 1 "strlen" { target { ! avr-*-* } } } } */ -/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.5. = " 1 "strlen" { target { ! avr-*-* } } } } */ -/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.6. = " 1 "strlen" { target { ! avr-*-* } } } } */ -/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;" 4 "strlen" { target { avr-*-* } } } } */ +/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.0. = " 1 "strlen1" { target { ! avr-*-* } } } } */ +/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.1. = " 1 "strlen1" { target { ! avr-*-* } } } } */ +/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.5. = " 1 "strlen1" { target { ! avr-*-* } } } } */ +/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.6. = " 1 "strlen1" { target { ! avr-*-* } } } } */ +/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;" 4 "strlen1" { target { avr-*-* } } } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-14g.c b/gcc/testsuite/gcc.dg/strlenopt-14g.c index 62a83bf..1368ed3 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-14g.c +++ b/gcc/testsuite/gcc.dg/strlenopt-14g.c @@ -107,10 +107,10 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "mempcpy \\(" 2 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "mempcpy \\(" 2 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-14gf.c b/gcc/testsuite/gcc.dg/strlenopt-14gf.c index 8b126fc..f7db2a8 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-14gf.c +++ b/gcc/testsuite/gcc.dg/strlenopt-14gf.c @@ -11,15 +11,15 @@ /* Compared to strlenopt-14gf.c, strcpy_chk with string literal as second argument isn't being optimized by builtins.c into memcpy. */ -/* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "__mempcpy_chk \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "mempcpy \\(" 2 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "__mempcpy_chk \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "mempcpy \\(" 2 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-15.c b/gcc/testsuite/gcc.dg/strlenopt-15.c index 827ea07..b72c096 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-15.c +++ b/gcc/testsuite/gcc.dg/strlenopt-15.c @@ -51,9 +51,9 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 3 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 2 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 3 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 2 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-16g.c b/gcc/testsuite/gcc.dg/strlenopt-16g.c index 0cf8410..816cbbc 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-16g.c +++ b/gcc/testsuite/gcc.dg/strlenopt-16g.c @@ -24,10 +24,10 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "mempcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "mempcpy \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-17g.c b/gcc/testsuite/gcc.dg/strlenopt-17g.c index 184e530..aa86f78 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-17g.c +++ b/gcc/testsuite/gcc.dg/strlenopt-17g.c @@ -47,10 +47,10 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 3 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "mempcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 3 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "mempcpy \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-18g.c b/gcc/testsuite/gcc.dg/strlenopt-18g.c index f734675..de692e0 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-18g.c +++ b/gcc/testsuite/gcc.dg/strlenopt-18g.c @@ -73,9 +73,9 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-19.c b/gcc/testsuite/gcc.dg/strlenopt-19.c index 022ba8b..814f51b 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-19.c +++ b/gcc/testsuite/gcc.dg/strlenopt-19.c @@ -72,9 +72,9 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-1f.c b/gcc/testsuite/gcc.dg/strlenopt-1f.c index 856774d..4e3abd9 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-1f.c +++ b/gcc/testsuite/gcc.dg/strlenopt-1f.c @@ -5,13 +5,13 @@ #define FORTIFY_SOURCE 2 #include "strlenopt-1.c" -/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-2.c b/gcc/testsuite/gcc.dg/strlenopt-2.c index fd59a3c..b09f7c1 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-2.c +++ b/gcc/testsuite/gcc.dg/strlenopt-2.c @@ -40,9 +40,9 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 5 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 5 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-20.c b/gcc/testsuite/gcc.dg/strlenopt-20.c index 7b483ea..79db12b 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-20.c +++ b/gcc/testsuite/gcc.dg/strlenopt-20.c @@ -86,9 +86,9 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-21.c b/gcc/testsuite/gcc.dg/strlenopt-21.c index 05b85a4..7924ff3 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-21.c +++ b/gcc/testsuite/gcc.dg/strlenopt-21.c @@ -57,9 +57,9 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 3 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 3 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-22.c b/gcc/testsuite/gcc.dg/strlenopt-22.c index b4ef772..2d127b1 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-22.c +++ b/gcc/testsuite/gcc.dg/strlenopt-22.c @@ -31,9 +31,9 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-22g.c b/gcc/testsuite/gcc.dg/strlenopt-22g.c index 9c5d020..1ecb85e 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-22g.c +++ b/gcc/testsuite/gcc.dg/strlenopt-22g.c @@ -5,9 +5,9 @@ #define USE_GNU #include "strlenopt-22.c" -/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-24.c b/gcc/testsuite/gcc.dg/strlenopt-24.c index 639501a..275b560 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-24.c +++ b/gcc/testsuite/gcc.dg/strlenopt-24.c @@ -13,4 +13,4 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-25.c b/gcc/testsuite/gcc.dg/strlenopt-25.c index 89b60e3..faed5be 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-25.c +++ b/gcc/testsuite/gcc.dg/strlenopt-25.c @@ -14,4 +14,4 @@ main () return len - len2; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-26.c b/gcc/testsuite/gcc.dg/strlenopt-26.c index 6bb0263..0385ace 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-26.c +++ b/gcc/testsuite/gcc.dg/strlenopt-26.c @@ -20,5 +20,5 @@ main (void) return fn1 (p, q); } -/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-27.c b/gcc/testsuite/gcc.dg/strlenopt-27.c index c539edb..e365593 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-27.c +++ b/gcc/testsuite/gcc.dg/strlenopt-27.c @@ -19,4 +19,4 @@ main (void) return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-28.c b/gcc/testsuite/gcc.dg/strlenopt-28.c index 03fb017..6bdbed7 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-28.c +++ b/gcc/testsuite/gcc.dg/strlenopt-28.c @@ -56,4 +56,4 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-29.c b/gcc/testsuite/gcc.dg/strlenopt-29.c index fb4b4c9..8922101 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-29.c +++ b/gcc/testsuite/gcc.dg/strlenopt-29.c @@ -24,4 +24,4 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-2f.c b/gcc/testsuite/gcc.dg/strlenopt-2f.c index 1e915da..5786f8a 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-2f.c +++ b/gcc/testsuite/gcc.dg/strlenopt-2f.c @@ -5,13 +5,13 @@ #define FORTIFY_SOURCE 2 #include "strlenopt-2.c" -/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 5 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 5 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-3.c b/gcc/testsuite/gcc.dg/strlenopt-3.c index f17779c..a748f01 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-3.c +++ b/gcc/testsuite/gcc.dg/strlenopt-3.c @@ -53,12 +53,12 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */ /* { dg-final { scan-tree-dump-times "return 0" 3 "optimized" } } */ /* { dg-final { scan-tree-dump-times "return 4" 1 "optimized" } } */ /* { dg-final { scan-tree-dump-times "return 3" 1 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-30.c b/gcc/testsuite/gcc.dg/strlenopt-30.c index a85df68..2a3098b 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-30.c +++ b/gcc/testsuite/gcc.dg/strlenopt-30.c @@ -60,4 +60,4 @@ _Bool f7(char *s) return (t1 == s); } -/* { dg-final { scan-tree-dump-times "__builtin_strncmp" 5 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "__builtin_strncmp" 5 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-31g.c b/gcc/testsuite/gcc.dg/strlenopt-31g.c index 45cc29c..4eff864 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-31g.c +++ b/gcc/testsuite/gcc.dg/strlenopt-31g.c @@ -4,6 +4,6 @@ #define USE_GNU #include "strlenopt-31.c" -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 2 "strlen" } } */ -/* { dg-final { scan-tree-dump-not "strlen \\(" "strlen" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 2 "strlen1" } } */ +/* { dg-final { scan-tree-dump-not "strlen \\(" "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-32.c b/gcc/testsuite/gcc.dg/strlenopt-32.c index 08eb6bc..4220314 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-32.c +++ b/gcc/testsuite/gcc.dg/strlenopt-32.c @@ -190,4 +190,4 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-33.c b/gcc/testsuite/gcc.dg/strlenopt-33.c index 1e1c4de..4903a91 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-33.c +++ b/gcc/testsuite/gcc.dg/strlenopt-33.c @@ -39,4 +39,4 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-33g.c b/gcc/testsuite/gcc.dg/strlenopt-33g.c index 7d24d2b..a814160 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-33g.c +++ b/gcc/testsuite/gcc.dg/strlenopt-33g.c @@ -40,5 +40,5 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-34.c b/gcc/testsuite/gcc.dg/strlenopt-34.c index c9433c0..1979370 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-34.c +++ b/gcc/testsuite/gcc.dg/strlenopt-34.c @@ -35,4 +35,4 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-35.c b/gcc/testsuite/gcc.dg/strlenopt-35.c index 03b3e13..d175fd7 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-35.c +++ b/gcc/testsuite/gcc.dg/strlenopt-35.c @@ -28,4 +28,4 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-4.c b/gcc/testsuite/gcc.dg/strlenopt-4.c index 802e4ca..1d0a6e6 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-4.c +++ b/gcc/testsuite/gcc.dg/strlenopt-4.c @@ -66,9 +66,9 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 3 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcpy \\(" 3 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcat \\(" 3 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 3 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 3 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcat \\(" 3 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-48.c b/gcc/testsuite/gcc.dg/strlenopt-48.c index 179edd8..c2d0ac6 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-48.c +++ b/gcc/testsuite/gcc.dg/strlenopt-48.c @@ -31,5 +31,5 @@ void h (void) abort(); } -/* { dg-final { scan-tree-dump-times "strlen" 0 "optimized" } } +/* { dg-final { scan-tree-dump-times "strlen1" 0 "optimized" } } { dg-final { scan-tree-dump-times "abort" 0 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-49.c b/gcc/testsuite/gcc.dg/strlenopt-49.c index f901fd1..bbea0e2 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-49.c +++ b/gcc/testsuite/gcc.dg/strlenopt-49.c @@ -45,7 +45,7 @@ int cmp88 (void) return cmp88; } -/* { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } } +/* { dg-final { scan-tree-dump-times "strlen1" 0 "gimple" } } { dg-final { scan-tree-dump-times "len0 = 0;" 1 "gimple" } } { dg-final { scan-tree-dump-times "len = 18;" 1 "gimple" } } { dg-final { scan-tree-dump-times "lenx = 8;" 1 "gimple" } } diff --git a/gcc/testsuite/gcc.dg/strlenopt-4g.c b/gcc/testsuite/gcc.dg/strlenopt-4g.c index 879d566..88dcec6 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-4g.c +++ b/gcc/testsuite/gcc.dg/strlenopt-4g.c @@ -5,9 +5,9 @@ #define USE_GNU #include "strlenopt-4.c" -/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 5 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 5 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-4gf.c b/gcc/testsuite/gcc.dg/strlenopt-4gf.c index 7f261b7..033661a 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-4gf.c +++ b/gcc/testsuite/gcc.dg/strlenopt-4gf.c @@ -6,13 +6,13 @@ #define FORTIFY_SOURCE 2 #include "strlenopt-4.c" -/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 5 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 5 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-5.c b/gcc/testsuite/gcc.dg/strlenopt-5.c index a24aea4..5a31322 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-5.c +++ b/gcc/testsuite/gcc.dg/strlenopt-5.c @@ -48,9 +48,9 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 2 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 2 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-50.c b/gcc/testsuite/gcc.dg/strlenopt-50.c index 1d1d368..8e7c9db 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-50.c +++ b/gcc/testsuite/gcc.dg/strlenopt-50.c @@ -112,5 +112,5 @@ void test_array_ref (void) T (&b[16], 0); T (&b[17], 0); T (&b[18], 0); T (&b[19], 0); } -/* { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } } +/* { dg-final { scan-tree-dump-times "strlen1" 0 "gimple" } } { dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated" 0 "ccp1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-51.c b/gcc/testsuite/gcc.dg/strlenopt-51.c index 3d879f1..22a8938 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-51.c +++ b/gcc/testsuite/gcc.dg/strlenopt-51.c @@ -84,4 +84,4 @@ void test_elim_a9_9 (unsigned i) T (0); T (1); T (2); T (3); T (4); T (5); T (6); T (7); T (8); } -/* { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "strlen1" 0 "gimple" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-52.c b/gcc/testsuite/gcc.dg/strlenopt-52.c index 03e063b..97b3da7 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-52.c +++ b/gcc/testsuite/gcc.dg/strlenopt-52.c @@ -284,5 +284,5 @@ void test_global_struct_struct_array (void) T (ssa[5].sa9[3].a6, 3); } -/* { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } } +/* { dg-final { scan-tree-dump-times "strlen1" 0 "gimple" } } { dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated" 0 "ccp1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-53.c b/gcc/testsuite/gcc.dg/strlenopt-53.c index baa680d..489c22b 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-53.c +++ b/gcc/testsuite/gcc.dg/strlenopt-53.c @@ -112,5 +112,5 @@ void test_array_ref (void) T (&b[16], 0); T (&b[17], 0); T (&b[18], 0); T (&b[19], 0); } -/* { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } } +/* { dg-final { scan-tree-dump-times "strlen1" 0 "gimple" } } { dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated" 0 "ccp1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-54.c b/gcc/testsuite/gcc.dg/strlenopt-54.c index c38e791..d4e57ff 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-54.c +++ b/gcc/testsuite/gcc.dg/strlenopt-54.c @@ -105,5 +105,5 @@ void elim_after_init_memcpy (void) T ("AB\000CD", 0, "ab\000c", 4, 2); } -/* { dg-final { scan-tree-dump-times "strlen" 0 "optimized" } } +/* { dg-final { scan-tree-dump-times "strlen1" 0 "optimized" } } { dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated" 0 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-55.c b/gcc/testsuite/gcc.dg/strlenopt-55.c index d5a0295..ea6fb22 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-55.c +++ b/gcc/testsuite/gcc.dg/strlenopt-55.c @@ -224,7 +224,7 @@ const void test_large_string_size (void) } -/* { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } } +/* { dg-final { scan-tree-dump-times "strlen1" 0 "gimple" } } { dg-final { scan-tree-dump-times "memcmp" 0 "gimple" } } { dg-final { scan-tree-dump-times "strcmp" 0 "gimple" } } { dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated" 0 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-56.c b/gcc/testsuite/gcc.dg/strlenopt-56.c index 39a532b..ffd02f1 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-56.c +++ b/gcc/testsuite/gcc.dg/strlenopt-56.c @@ -45,6 +45,6 @@ void test_contents (void) } -/* { dg-final { scan-tree-dump-times "strlen" 0 "gimple" } } +/* { dg-final { scan-tree-dump-times "strlen1" 0 "gimple" } } { dg-final { scan-tree-dump-times "strcmp" 0 "gimple" } } { dg-final { scan-tree-dump-times "abort" 0 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-6.c b/gcc/testsuite/gcc.dg/strlenopt-6.c index fbff14c..dcbe778 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-6.c +++ b/gcc/testsuite/gcc.dg/strlenopt-6.c @@ -77,9 +77,9 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-61.c b/gcc/testsuite/gcc.dg/strlenopt-61.c index 4f8e9c0..3ddfa2e 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-61.c +++ b/gcc/testsuite/gcc.dg/strlenopt-61.c @@ -215,4 +215,4 @@ void test_ta2 (void) } /* { dg-final { scan-tree-dump-not "failure" "optimized" } } - { dg-final { scan-tree-dump-not "strlen" "gimple" } } */ + { dg-final { scan-tree-dump-not "strlen1" "gimple" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-68.c b/gcc/testsuite/gcc.dg/strlenopt-68.c new file mode 100644 index 0000000..56d314e --- /dev/null +++ b/gcc/testsuite/gcc.dg/strlenopt-68.c @@ -0,0 +1,382 @@ +/* PR tree-optimization/83431 - Verify that snprintf (0, 0, "%s", + with an argument that's a conditional expression evaluates to + the expected result regardless of the order of the expression + operands. + { dg-do run } + { dg-options "-O2 -Wall" } */ + +#include "strlenopt.h" + +#define A(expr) \ + ((expr) \ + ? (void)0 \ + : (__builtin_printf ("assertion failed on line %i: %s\n", \ + __LINE__, #expr), \ + __builtin_abort ())) + +const char gs0[] = ""; +const char gs3[] = "123"; + +char gc; +char ga5[7]; + +struct S { char n, ma7[7], max[]; }; + + +__attribute__ ((noclone, noinline, noipa)) void +equal_4_gs0_gs3_ga5_m1 (int i) +{ + strcpy (ga5, "1234"); + const char *p = i < 0 ? gs0 : 0 < i ? gs3 : ga5; + + A (snprintf (0, 0, "%s", p) == 0); +} + +__attribute__ ((noclone, noinline, noipa)) void +equal_4_gs0_gs3_ga5_0 (int i) +{ + strcpy (ga5, "1234"); + const char *p = i < 0 ? gs0 : 0 < i ? gs3 : ga5; + + A (snprintf (0, 0, "%s", p) == 4); +} + +__attribute__ ((noclone, noinline, noipa)) void +equal_4_gs0_gs3_ga5_p1 (int i) +{ + strcpy (ga5, "1234"); + const char *p = i < 0 ? gs0 : 0 < i ? gs3 : ga5; + + A (snprintf (0, 0, "%s", p) == 3); +} + + +__attribute__ ((noclone, noinline, noipa)) void +equal_4_gs0_ga5_gs3_m1 (int i) +{ + strcpy (ga5, "1234"); + const char *p = i < 0 ? gs0 : 0 < i ? ga5 : gs3; + + A (snprintf (0, 0, "%s", p) == 0); +} + +__attribute__ ((noclone, noinline, noipa)) void +equal_4_gs0_ga5_gs3_0 (int i) +{ + strcpy (ga5, "1234"); + const char *p = i < 0 ? gs0 : 0 < i ? ga5 : gs3; + + A (snprintf (0, 0, "%s", p) == 3); +} + +__attribute__ ((noclone, noinline, noipa)) void +equal_4_gs0_ga5_gs3_p1 (int i) +{ + strcpy (ga5, "1234"); + const char *p = i < 0 ? gs0 : 0 < i ? ga5 : gs3; + + A (snprintf (0, 0, "%s", p) == 4); +} + + +__attribute__ ((noclone, noinline, noipa)) void +equal_4_ga5_gs0_gs3_m1 (int i) +{ + strcpy (ga5, "1234"); + const char *p = i < 0 ? ga5 : 0 < i ? gs0 : gs3; + + A (snprintf (0, 0, "%s", p) == 4); +} + +__attribute__ ((noclone, noinline, noipa)) void +equal_4_ga5_gs0_gs3_0 (int i) +{ + strcpy (ga5, "1234"); + const char *p = i < 0 ? ga5 : 0 < i ? gs0 : gs3; + + A (snprintf (0, 0, "%s", p) == 3); +} + +__attribute__ ((noclone, noinline, noipa)) void +equal_4_ga5_gs0_gs3_p1 (int i) +{ + strcpy (ga5, "1234"); + const char *p = i < 0 ? ga5 : 0 < i ? gs0 : gs3; + + A (snprintf (0, 0, "%s", p) == 0); +} + + +__attribute__ ((noclone, noinline, noipa)) void +equal_4_ga5_gs3_gs0_m1 (int i) +{ + strcpy (ga5, "1234"); + const char *p = i < 0 ? ga5 : 0 < i ? gs3 : gs0; + + A (snprintf (0, 0, "%s", p) == 4); +} + +__attribute__ ((noclone, noinline, noipa)) void +equal_4_ga5_gs3_gs0_0 (int i) +{ + strcpy (ga5, "1234"); + const char *p = i < 0 ? ga5 : 0 < i ? gs3 : gs0; + + A (snprintf (0, 0, "%s", p) == 0); +} + +__attribute__ ((noclone, noinline, noipa)) void +equal_4_ga5_gs3_gs0_p1 (int i) +{ + strcpy (ga5, "1234"); + const char *p = i < 0 ? ga5 : 0 < i ? gs3 : gs0; + + A (snprintf (0, 0, "%s", p) == 3); +} + + +__attribute__ ((noclone, noinline, noipa)) void +equal_4_gs3_gs0_ga5_m1 (int i) +{ + strcpy (ga5, "1234"); + const char *p = i < 0 ? gs3 : 0 < i ? gs0 : ga5; + + A (snprintf (0, 0, "%s", p) == 3); +} + +__attribute__ ((noclone, noinline, noipa)) void +equal_4_gs3_gs0_ga5_0 (int i) +{ + strcpy (ga5, "1234"); + const char *p = i < 0 ? gs3 : 0 < i ? gs0 : ga5; + + A (snprintf (0, 0, "%s", p) == 4); +} + +__attribute__ ((noclone, noinline, noipa)) void +equal_4_gs3_gs0_ga5_p1 (int i) +{ + strcpy (ga5, "1234"); + const char *p = i < 0 ? gs3 : 0 < i ? gs0 : ga5; + + A (snprintf (0, 0, "%s", p) == 0); +} + + +/* Similar to the above but with memcpy creating a string at least + four characters long, and the address of the NUL character. */ + +__attribute__ ((noclone, noinline, noipa)) void +min_4_gc_gs3_ga5_m1 (int i) +{ + gc = 0; + memcpy (ga5, "1234", 4); + const char *p = i < 0 ? &gc : 0 < i ? gs3 : ga5; + + A (snprintf (0, 0, "%s", p) == 0); +} + +__attribute__ ((noclone, noinline, noipa)) void +min_4_gc_gs3_ga5_0 (int i) +{ + gc = 0; + memcpy (ga5, "1234", 4); + const char *p = i < 0 ? &gc : 0 < i ? gs3 : ga5; + + A (snprintf (0, 0, "%s", p) == 4); +} + +__attribute__ ((noclone, noinline, noipa)) void +min_4_gc_gs3_ga5_p1 (int i) +{ + gc = 0; + memcpy (ga5, "1234", 4); + const char *p = i < 0 ? &gc : 0 < i ? gs3 : ga5; + + A (snprintf (0, 0, "%s", p) == 3); +} + + +__attribute__ ((noclone, noinline, noipa)) void +min_4_gc_ga5_gs3_m1 (int i) +{ + gc = 0; + memcpy (ga5, "1234", 4); + const char *p = i < 0 ? &gc : 0 < i ? ga5 : gs3; + + A (snprintf (0, 0, "%s", p) == 0); +} + +__attribute__ ((noclone, noinline, noipa)) void +min_4_gc_ga5_gs3_0 (int i) +{ + gc = 0; + memcpy (ga5, "1234", 4); + const char *p = i < 0 ? &gc : 0 < i ? ga5 : gs3; + + A (snprintf (0, 0, "%s", p) == 3); +} + +__attribute__ ((noclone, noinline, noipa)) void +min_4_gc_ga5_gs3_p1 (int i) +{ + gc = 0; + memcpy (ga5, "1234", 4); + const char *p = i < 0 ? &gc : 0 < i ? ga5 : gs3; + + A (snprintf (0, 0, "%s", p) == 4); +} + + +__attribute__ ((noclone, noinline, noipa)) void +min_4_ga5_gc_gs3_m1 (int i) +{ + gc = 0; + memcpy (ga5, "1234", 4); + const char *p = i < 0 ? ga5 : 0 < i ? &gc : gs3; + + A (snprintf (0, 0, "%s", p) == 4); +} + +__attribute__ ((noclone, noinline, noipa)) void +min_4_ga5_gc_gs3_0 (int i) +{ + gc = 0; + memcpy (ga5, "1234", 4); + const char *p = i < 0 ? ga5 : 0 < i ? &gc : gs3; + + A (snprintf (0, 0, "%s", p) == 3); +} + +__attribute__ ((noclone, noinline, noipa)) void +min_4_ga5_gc_gs3_p1 (int i) +{ + gc = 0; + memcpy (ga5, "1234", 4); + const char *p = i < 0 ? ga5 : 0 < i ? &gc : gs3; + + A (snprintf (0, 0, "%s", p) == 0); +} + + +__attribute__ ((noclone, noinline, noipa)) void +min_4_ga5_gs3_gc_m1 (int i) +{ + gc = 0; + memcpy (ga5, "1234", 4); + const char *p = i < 0 ? ga5 : 0 < i ? gs3 : &gc; + + A (snprintf (0, 0, "%s", p) == 4); +} + +__attribute__ ((noclone, noinline, noipa)) void +min_4_ga5_gs3_gc_0 (int i) +{ + gc = 0; + memcpy (ga5, "1234", 4); + const char *p = i < 0 ? ga5 : 0 < i ? gs3 : &gc; + + A (snprintf (0, 0, "%s", p) == 0); +} + +__attribute__ ((noclone, noinline, noipa)) void +min_4_ga5_gs3_gc_p1 (int i) +{ + gc = 0; + memcpy (ga5, "1234", 4); + const char *p = i < 0 ? ga5 : 0 < i ? gs3 : &gc; + + A (snprintf (0, 0, "%s", p) == 3); +} + + +__attribute__ ((noclone, noinline, noipa)) void +min_4_gs3_gc_ga5_m1 (int i) +{ + gc = 0; + memcpy (ga5, "1234", 4); + const char *p = i < 0 ? gs3 : 0 < i ? &gc : ga5; + + A (snprintf (0, 0, "%s", p) == 3); +} + +__attribute__ ((noclone, noinline, noipa)) void +min_4_gs3_gc_ga5_0 (int i) +{ + gc = 0; + memcpy (ga5, "1234", 4); + const char *p = i < 0 ? gs3 : 0 < i ? &gc : ga5; + + A (snprintf (0, 0, "%s", p) == 4); +} + +__attribute__ ((noclone, noinline, noipa)) void +min_4_gs3_gc_ga5_p1 (int i) +{ + gc = 0; + memcpy (ga5, "1234", 4); + const char *p = i < 0 ? gs3 : 0 < i ? &gc : ga5; + + A (snprintf (0, 0, "%s", p) == 0); +} + + +int main (void) +{ + equal_4_gs0_gs3_ga5_m1 (-1); + equal_4_gs0_gs3_ga5_0 ( 0); + equal_4_gs0_gs3_ga5_p1 (+1); + + equal_4_gs0_ga5_gs3_m1 (-1); + equal_4_gs0_ga5_gs3_0 ( 0); + equal_4_gs0_ga5_gs3_p1 (+1); + + equal_4_ga5_gs0_gs3_m1 (-1); + equal_4_ga5_gs0_gs3_0 ( 0); + equal_4_ga5_gs0_gs3_p1 (+1); + + equal_4_ga5_gs3_gs0_m1 (-1); + equal_4_ga5_gs3_gs0_0 ( 0); + equal_4_ga5_gs3_gs0_p1 (+1); + + equal_4_gs3_gs0_ga5_m1 (-1); + equal_4_gs3_gs0_ga5_0 ( 0); + equal_4_gs3_gs0_ga5_p1 (+1); + + /* Same as aabove but with memcpy creating a string at least four + characters long. */ + memset (ga5, 0, sizeof ga5); + min_4_gc_gs3_ga5_m1 (-1); + memset (ga5, 0, sizeof ga5); + min_4_gc_gs3_ga5_0 ( 0); + memset (ga5, 0, sizeof ga5); + min_4_gc_gs3_ga5_p1 (+1); + + memset (ga5, 0, sizeof ga5); + min_4_gc_ga5_gs3_m1 (-1); + memset (ga5, 0, sizeof ga5); + min_4_gc_ga5_gs3_0 ( 0); + memset (ga5, 0, sizeof ga5); + min_4_gc_ga5_gs3_p1 (+1); + + memset (ga5, 0, sizeof ga5); + min_4_ga5_gc_gs3_m1 (-1); + memset (ga5, 0, sizeof ga5); + min_4_ga5_gc_gs3_0 ( 0); + memset (ga5, 0, sizeof ga5); + min_4_ga5_gc_gs3_p1 (+1); + + memset (ga5, 0, sizeof ga5); + min_4_ga5_gs3_gc_m1 (-1); + memset (ga5, 0, sizeof ga5); + min_4_ga5_gs3_gc_0 ( 0); + memset (ga5, 0, sizeof ga5); + min_4_ga5_gs3_gc_p1 (+1); + + memset (ga5, 0, sizeof ga5); + min_4_gs3_gc_ga5_m1 (-1); + memset (ga5, 0, sizeof ga5); + min_4_gs3_gc_ga5_0 ( 0); + memset (ga5, 0, sizeof ga5); + min_4_gs3_gc_ga5_p1 (+1); +} diff --git a/gcc/testsuite/gcc.dg/strlenopt-7.c b/gcc/testsuite/gcc.dg/strlenopt-7.c index aa53d7e..ba62c03 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-7.c +++ b/gcc/testsuite/gcc.dg/strlenopt-7.c @@ -40,12 +40,12 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 2 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "\\*r_\[0-9\]* = 0;" 1 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 2 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "\\*r_\[0-9\]* = 0;" 1 "strlen1" } } */ /* { dg-final { scan-tree-dump-times "return 3;" 1 "optimized" } } */ /* { dg-final { scan-tree-dump-times "return 0;" 2 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-9.c b/gcc/testsuite/gcc.dg/strlenopt-9.c index e8ff102..df6b594 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-9.c +++ b/gcc/testsuite/gcc.dg/strlenopt-9.c @@ -98,10 +98,10 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 5 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 5 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */ /* { dg-final { scan-tree-dump-times "return 4;" 1 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt.h b/gcc/testsuite/gcc.dg/strlenopt.h index d25e08a..518d0cf 100644 --- a/gcc/testsuite/gcc.dg/strlenopt.h +++ b/gcc/testsuite/gcc.dg/strlenopt.h @@ -1,4 +1,4 @@ -/* This is a replacement of needed parts from stdlib.h and string.h +/* This is a replacement of needed parts from and for -foptimize-strlen testing, to ensure we are testing the builtins rather than whatever the OS has in its headers. */ @@ -25,6 +25,9 @@ void *mempcpy (void *__restrict, const void *__restrict, size_t); char *stpcpy (char *__restrict, const char *__restrict); #endif +int sprintf (char * __restrict, const char *__restrict, ...); +int snprintf (char * __restrict, size_t, const char *__restrict, ...); + #if defined(FORTIFY_SOURCE) && FORTIFY_SOURCE > 0 && __OPTIMIZE__ # define bos(ptr) __builtin_object_size (ptr, FORTIFY_SOURCE > 0) # define bos0(ptr) __builtin_object_size (ptr, 0) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-6.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-6.c new file mode 100644 index 0000000..0d9b275 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-6.c @@ -0,0 +1,139 @@ +/* Test to verify that snprintf can determine the length of a dynamically + constructed string argument and fold the result into a constant. + { dg-do compile } + { dg-options "-O2 -Wall -fdump-tree-optimized" } */ + +typedef __SIZE_TYPE__ size_t; + +char* strcpy (char * restrict, const char * restrict); +int sprintf (char * restrict, const char *restrict, ...); +int snprintf (char * restrict, size_t, const char *restrict, ...); + + +#define CONCAT(x, y) x ## y +#define CAT(x, y) CONCAT (x, y) +#define FAILNAME(name, counter) \ + CAT (CAT (CAT (call_ ## name ##_on_line_, __LINE__), _), counter) + +#define FAIL(name, counter) do { \ + extern void FAILNAME (name, counter) (void); \ + FAILNAME (name, counter)(); \ + } while (0) + +/* Macro to emit a call to funcation named + call_in_true_branch_not_eliminated_on_line_NNN() + for each call that's expected to be eliminated. The dg-final + scan-tree-dump-time directive at the bottom of the test verifies + that no such call appears in output. */ +#define ELIM(expr) \ + if (!(expr)) FAIL (in_true_branch_not_eliminated, __COUNTER__); else (void)0 + +#define ARGS(...) __VA_ARGS__ + +#define T(expect, init, fmt, ...) \ + do { \ + char a[] = init; \ + ELIM (expect == snprintf (0, 0, fmt, __VA_ARGS__)); \ + } while (0) + +/* Exercise a non-const local char array initialized by a string literal. */ +void test_assign_string (void) +{ + T (0, "", "%s", a); + T (1, "1", "%s", a); + T (4, "1234", "%s", a); + T (5, "123", "s=%s", a); + T (5, "1234", "s=%s", a + 1); + T (2, "1234", "s=%s", a + 4); + T (5, "12345", "s=%s", &a[2]); + T (5, "123456", "s=%.*s", 3, &a[2]); +} + +/* Exercise a non-const local char array initialized by an initializer + list. */ +void test_assign_init_list (void) +{ + T (0, ARGS ({ 0 }), "%s", a); + T (1, ARGS ({ 1, 0 }), "%s", a); + T (3, ARGS ({ [3] = 0, [1] = 2, [0] = 1, [2] = 3 }), "%s", a); + T (3, ARGS ({ [3] = 0, [1] = 2, [0] = 1, [2] = 3, [4] = 0 }), "%s", a); + T (4, ARGS ({ 1, 2, 3, 4, 0 }), "%s", a); + T (5, ARGS ({ 1, 2, 3, 0 }), "s=%s", a); + T (5, ARGS ({ 1, 2, 3, 4, 0 }), "s=%s", a + 1); + T (2, ARGS ({ 1, 2, 3, 4, 0 }), "s=%s", a + 4); + T (5, ARGS ({ 1, 2, 3, 4, 5, 0 }), "s=%s", &a[2]); + T (5, ARGS ({ 1, 2, 3, 4, 5, 6, 0 }), "s=%.*s", 3, &a[2]); +} + +#undef T +#define T(expect, init, fmt, ...) \ + do { \ + struct { int n; char a[sizeof init]; } \ + s = { sizeof init, init }; \ + ELIM (expect == snprintf (0, 0, fmt, __VA_ARGS__)); \ + } while (0) + +/* Exercise a non-const local struct initialized by an initializer + list. */ +void test_assign_aggregate (void) +{ + T (0, "", "%s", s.a); + T (1, "1", "%s", s.a); + T (4, "1234", "%s", s.a); + T (5, "123", "s=%s", s.a); + T (5, "1234", "s=%s", s.a + 1); + T (2, "1234", "s=%s", s.a + 4); + T (5, "12345", "s=%s", &s.a[2]); + T (5, "123456", "s=%.*s", 3, &s.a[2]); +} + + +#undef T +#define T(expect, init, fmt, ...) \ + do { \ + char a[sizeof init]; \ + strcpy (a, init); \ + ELIM (expect == snprintf (0, 0, fmt, __VA_ARGS__)); \ + } while (0) + +/* Exercise a local char array initialized by a call to strcpy. */ +void test_local_strcpy (void) +{ + T (0, "", "%s", a); + T (1, "1", "%s", a); + T (2, "12", "%s", a); + T (3, "123", "%s", a); + T (4, "1234", "%s", a); + T (5, "123", "s=%s", a); + T (5, "1234", "s=%s", a + 1); + T (2, "1234", "s=%s", a + 4); + T (5, "12345", "s=%s", &a[2]); + T (5, "123456", "s=%.*s", 3, &a[2]); +} + +#undef T +#define T(expect, init, fmt, ...) \ + do { \ + char a[n]; \ + strcpy (a, init); \ + ELIM (expect == snprintf (0, 0, fmt, __VA_ARGS__)); \ + } while (0) + +/* Exercise a VLA initialized by a call to strcpy. */ +void test_vla_strcpy (unsigned n) +{ + T (0, "", "%s", a); + T (1, "1", "%s", a); + T (2, "12", "%s", a); + T (3, "123", "%s", a); + T (4, "1234", "%s", a); + T (5, "123", "s=%s", a); + T (5, "1234", "s=%s", a + 1); + T (2, "1234", "s=%s", a + 4); + T (5, "12345", "s=%s", &a[2]); + T (5, "123456", "s=%.*s", 3, &a[2]); +} + +/* { dg-final { scan-tree-dump-times "printf" 0 "optimized" } } + { dg-final { scan-tree-dump-times "strlen" 0 "optimized" } } + { dg-final { scan-tree-dump-times "not_eliminated" 0 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-7.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-7.c new file mode 100644 index 0000000..bf5072e --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-7.c @@ -0,0 +1,152 @@ +/* Test to verify that snprintf can determine the correct range + of lengths of dynamically constructed string arguments. + { dg-do compile } + { dg-options "-O2 -Wall -fdump-tree-optimized" } */ + +typedef __SIZE_TYPE__ size_t; + +void* memcpy (void*, const void*, size_t); + +char* strcpy (char * restrict, const char * restrict); +int snprintf (char * restrict, size_t, const char *restrict, ...); + +void sink (void*, ...); + +#define CONCAT(x, y) x ## y +#define CAT(x, y) CONCAT (x, y) +#define FAILNAME(name, counter) \ + CAT (CAT (CAT (call_ ## name ##_on_line_, __LINE__), _), counter) + +#define FAIL(name, counter) do { \ + extern void FAILNAME (name, counter) (void); \ + FAILNAME (name, counter)(); \ + } while (0) + +/* Macro to emit a call to funcation named + call_in_true_branch_not_eliminated_on_line_NNN() + for each call that's expected to be eliminated. The dg-final + scan-tree-dump-time directive at the bottom of the test verifies + that no such call appears in output. */ +#define VERIFY_ELIM(expr) \ + if (!(expr)) FAIL (in_true_branch_not_eliminated, __COUNTER__); else (void)0 + +/* Macro to emit a call to a function named + call_made_in_{true,false}_branch_on_line_NNN() + for each call that's expected to be retained. The dg-final + scan-tree-dump-time directive at the bottom of the test verifies + that the expected number of both kinds of calls appears in output + (a pair for each line with the invocation of the KEEP() macro. */ +#define VERIFY_KEEP(expr) \ + if (expr) \ + FAIL (made_in_true_branch, __COUNTER__); \ + else \ + FAIL (made_in_false_branch, __COUNTER__) + +#define ARGS(...) __VA_ARGS__ + +/* Each test macro expands to a new function to get around bug 81776 + - missing sprintf optimization due to pointer escape analysis. */ +#define ELIM(expect, dst, init, fmt, ...) \ + void CAT (test_func_on_line_, __LINE__)(void) \ + { \ + memcpy (dst, init, sizeof (init) - 1); \ + const int res = snprintf (0, 0, fmt, __VA_ARGS__); \ + VERIFY_ELIM (expect res); \ + } typedef void dummy_typedef + +#define KEEP(expect, dst, init, fmt, ...) \ + void CAT (test_func_on_line_, __LINE__)(void) \ + { \ + memcpy (dst, init, sizeof (init) - 1); \ + const int ret = snprintf (0, 0, fmt, __VA_ARGS__); \ + VERIFY_KEEP (expect ret); \ + } typedef void dummy_typedef + + +/* Verify that conditions involving snprintf calls with a string + of some minimum but otherwise unbounded length stored in an array + of unknown bound are not folded unless the format string itself + restricts the maximum. The string could be longer than INT_MAX + making the snprintf call fail and return a negative value. */ + +extern char gax[]; + +KEEP (1 <=, gax, "1", "%s", gax); +KEEP (2 <=, gax, "12", "%s", gax); +KEEP (3 <=, gax, "123", "%s", gax); + +ELIM (3 ==, gax, "123", "%.3s", gax); +ELIM (5 ==, gax, "123", "%.3s%.2s", gax, gax); + + +/* Disabled. The global pointer passed to memcpy as the destination + might point at itself, i.e., gptr == &gptr is a valid argument to + memcpy. + +extern char *gptr; + +KEEP (1 <=, gptr, "1", "%s", gptr); +KEEP (2 <=, gptr, "12", "%s", gptr); +KEEP (3 <=, gptr, "123", "%s", gptr); + +ELIM (3 ==, gptr, "123", "%.3s", gptr); +ELIM (5 ==, gptr, "123", "%.3s%.2s", gptr, gptr); + +*/ + +/* Verify that conditions involving snprintf calls with a string + of some minimum but otherwise unbounded length stored in an array + of a known bound are folded. The longest string that can be + stored in such arrays is bounded by the size of the array. */ + +extern char ga4[4]; + +ELIM (0 <=, ga4, "\0", "%s", ga4); +ELIM (3 >=, ga4, "\0", "%s", ga4); + +ELIM (1 <=, ga4, "1", "%s", ga4); +ELIM (0 <=, ga4, "1", "%s", ga4 + 1); +ELIM (0 <=, ga4, "1", "%s", &ga4[1]); + +ELIM (3 >=, ga4, "1", "%s", ga4); +ELIM (2 >=, ga4, "1", "%s", ga4 + 1); +ELIM (2 >=, ga4, "1", "%s", &ga4[1]); + +ELIM (2 <=, ga4, "12", "%s", ga4); +ELIM (3 >=, ga4, "12", "%s", ga4); + +ELIM (3 <=, ga4, "123", "%s", ga4); +ELIM (3 ==, ga4, "123", "%.3s", ga4); +ELIM (5 ==, ga4, "123", "%.3s%.2s", ga4, ga4); + +/* Verify conditionals involving dynamically created strings of known + length stored in local arrays. */ + +#undef ELIM +#define ELIM(expect, N1, N2, init1, init2, fmt, ...) \ + void CAT (test_func_on_line_, __LINE__)(int i) \ + { \ + char a1[N1], a2[N2]; \ + memcpy (a1, init1, sizeof (init1) - 1); \ + memcpy (a2, init2, sizeof (init2) - 1); \ + const int res = snprintf (0, 0, fmt, __VA_ARGS__); \ + VERIFY_ELIM (expect res); \ + } typedef void dummy_typedef + +ELIM (0 ==, 2, 2, "\0", "\0", "%s", i ? a1 : a2); +ELIM (2 ==, 2, 2, "\0", "\0", "s=%s", i ? a1 : a2); + +ELIM (1 ==, 2, 2, "a\0", "b\0", "%s", i ? a1 : a2); +ELIM (3 ==, 2, 2, "a\0", "b\0", "s=%s", i ? a1 : a2); + +ELIM (2 ==, 3, 5, "ab\0", "cd\0", "%s", i ? a1 : a2); +ELIM (3 ==, 3, 5, "ab\0", "cd\0", "%3s", i ? a1 : a2); +ELIM (3 ==, 5, 5, "abcd\0", "efgh\0", "%.3s", i ? a1 : a2); + +ELIM (3 ==, 4, 1, "abc\0", "", "%s", i ? a1 : "def"); +ELIM (4 ==, 1, 5, "", "efgh\0", "%s", i ? "abcd" : a2); + +ELIM (4 ==, 5, 5, "abcd\0", "efgh\0", "%s", i < 0 ? a1 : 0 < i ? a2 : "ijkl"); + +/* { dg-final { scan-tree-dump-times "_not_eliminated" 0 "optimized" } } + { dg-final { scan-tree-dump-times "call_made_" 6 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-8.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-8.c new file mode 100644 index 0000000..95b0b44 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-8.c @@ -0,0 +1,41 @@ +/* Test to verify that snprintf can determine the correct range + of lengths of string arguments based on the results of prior + calls to strlen. + { dg-do compile } + { dg-options "-O2 -Wall -fdump-tree-optimized" } */ + +typedef __SIZE_TYPE__ size_t; + +void abort (void); +size_t strlen (const char *); +int snprintf (char * restrict, size_t, const char *restrict, ...); + +void one_str_exact (const char *str) +{ + if (1 == strlen (str)) + if (1 != snprintf (0, 0, "%s", str)) + abort (); +} + +void two_str_exact (const char *s1, const char *s2) +{ + if (1 == strlen (s1) && 2 == strlen (s2)) + if (3 != snprintf (0, 0, "%s%s", s1, s2)) + abort (); +} + +void one_str_maxlen (const char *str) +{ + if (2 >= strlen (str)) + if (2 < snprintf (0, 0, "%s", str)) + abort (); +} + +void two_str_maxlen (const char *s1, const char *s2) +{ + if (2 >= strlen (s1) && 3 >= strlen (s2)) + if (5 < snprintf (0, 0, "%s%s", s1, s2)) + abort (); +} + +/* { dg-final { scan-tree-dump-not "abort" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-9.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-9.c new file mode 100644 index 0000000..9c238ce --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-9.c @@ -0,0 +1,163 @@ +/* Test to verify that --param ssa_name_def_chain_limit can be used to + limit the maximum number of SSA_NAME assignments the built-in code + follows to determine the variable value/string length. + { dg-do compile } + { dg-options "-O2 -Wall --param ssa-name-def-chain-limit=4 -fdump-tree-optimized" } */ + +void abort (void); +int sprintf (char * restrict, const char *restrict, ...); + +void sink (const char*, ...); + +const char a0[] = ""; +const char a1[] = "1"; +const char a2[] = "12"; +const char a3[] = "123"; +const char a4[] = "1234"; +const char a5[] = "12345"; +const char a6[] = "123456"; +const char a7[] = "1234567"; +const char a8[] = "12345678"; +const char a9[] = "123456789"; + +int i0, i1, i2, i3, i4, i5, i6, i7, i8; + +void g1 (char *d) +{ + const char *p0 = i0 ? a0 : a1; + const char *p1 = i1 ? p0 : a2; + + sink (p0, p1); + + if (sprintf (d, "%s", p1) > 2) + abort (); +} + +void g2 (char *d) +{ + const char *p0 = i0 ? a0 : a1; + const char *p1 = i1 ? p0 : a2; + const char *p2 = i2 ? p1 : a3; + + sink (p0, p1, p2); + + if (sprintf (d, "%s", p2) > 3) + abort (); +} + +void g3 (char *d) +{ + const char *p0 = i0 ? a0 : a1; + const char *p1 = i1 ? p0 : a2; + const char *p2 = i2 ? p1 : a3; + const char *p3 = i3 ? p2 : a4; + + sink (p0, p1, p2, p3); + + if (sprintf (d, "%s", p3) > 4) + abort (); +} + +void g4 (char *d) +{ + const char *p0 = i0 ? a0 : a1; + const char *p1 = i1 ? p0 : a2; + const char *p2 = i2 ? p1 : a3; + const char *p3 = i3 ? p2 : a4; + const char *p4 = i4 ? p3 : a5; + + sink (p0, p1, p2, p3, p4); + + // p4 below is the result of the following five PHI assignments + // and with the limit set to 4 the sprintf call result is not + // determined: + // iftmp.0_7 = PHI <&a0(2), &a1(3)> + // iftmp.2_8 = PHI + // iftmp.4_9 = PHI + // iftmp.6_10 = PHI + // iftmp.8_17 = PHI + // p4 = iftmp.8_17 + extern void keep_g4 (void); + if (sprintf (d, "%s", p4) > 5) + keep_g4 (); +} + +void g5 (char *d) +{ + const char *p0 = i0 ? a0 : a1; + const char *p1 = i1 ? p0 : a2; + const char *p2 = i2 ? p1 : a3; + const char *p3 = i3 ? p2 : a4; + const char *p4 = i4 ? p3 : a5; + const char *p5 = i5 ? p4 : a6; + + sink (p0, p1, p2, p3, p4, p5); + + extern void keep_g5 (void); + if (sprintf (d, "%s", p5) > 6) + keep_g5 (); + + /* { dg-final { scan-tree-dump-times "keep_g5" 1 "optimized" } } */ +} + +void g6 (char *d) +{ + const char *p0 = i0 ? a0 : a1; + const char *p1 = i1 ? p0 : a2; + const char *p2 = i2 ? p1 : a3; + const char *p3 = i3 ? p2 : a4; + const char *p4 = i4 ? p3 : a5; + const char *p5 = i5 ? p4 : a6; + const char *p6 = i6 ? p5 : a7; + + sink (p0, p1, p2, p3, p4, p5, p6); + + extern void keep_g6 (void); + if (sprintf (d, "%s", p6) > 7) + keep_g6 (); + + /* { dg-final { scan-tree-dump-times "keep_g6" 1 "optimized" } } */ +} + +void g7 (char *d) +{ + const char *p0 = i0 ? a0 : a1; + const char *p1 = i1 ? p0 : a2; + const char *p2 = i2 ? p1 : a3; + const char *p3 = i3 ? p2 : a4; + const char *p4 = i4 ? p3 : a5; + const char *p5 = i5 ? p4 : a6; + const char *p6 = i6 ? p5 : a7; + const char *p7 = i7 ? p6 : a8; + + sink (p0, p1, p2, p3, p4, p5, p6, p7); + + extern void keep_g7 (void); + if (sprintf (d, "%s", p7) > 8) + keep_g7 (); + + /* { dg-final { scan-tree-dump-times "keep_g7" 1 "optimized" } } */ +} + +void g8 (char *d) +{ + const char *p0 = i0 ? a0 : a1; + const char *p1 = i1 ? p0 : a2; + const char *p2 = i2 ? p1 : a3; + const char *p3 = i3 ? p2 : a4; + const char *p4 = i4 ? p3 : a5; + const char *p5 = i5 ? p4 : a6; + const char *p6 = i6 ? p5 : a7; + const char *p7 = i7 ? p6 : a8; + const char *p8 = i8 ? p7 : a9; + + sink (p0, p1, p2, p3, p4, p5, p6, p7, p8); + + extern void keep_g8 (void); + if (sprintf (d, "%s", p8) > 9) + keep_g8 (); + + /* { dg-final { scan-tree-dump-times "keep_g8" 1 "optimized" } } */ +} + +/* { dg-final { scan-tree-dump-not "abort" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-warn-5.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-warn-5.c new file mode 100644 index 0000000..becba05 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-warn-5.c @@ -0,0 +1,140 @@ +/* Test to verify that --param ssa_name_def_chain_limit can be used to + limit the maximum number of SSA_NAME assignments the built-in code + follows. + { dg-do compile } + { dg-options "-O2 -Wall -Wformat-truncation=2 --param ssa-name-def-chain-limit=4 -fdump-tree-optimized" } */ + +typedef __SIZE_TYPE__ size_t; + +int snprintf (char * restrict, size_t, const char *restrict, ...); + +void sink (const char*, ...); + +const char a0[] = ""; +const char a1[] = "1"; +const char a2[] = "12"; +const char a3[] = "123"; +const char a4[] = "1234"; +const char a5[] = "12345"; +const char a6[] = "123456"; +const char a7[] = "1234567"; +const char a8[] = "12345678"; +const char a9[] = "123456789"; + +int i0, i1, i2, i3, i4, i5, i6, i7, i8; + +void g1 (char *d) +{ + const char *p0 = i0 ? a0 : a1; + const char *p1 = i1 ? p0 : a2; + + sink (p0, p1); + + snprintf (d, 1, "%s", p1); // { dg-warning "\\\[-Wformat-truncation" } +} + +void g2 (char *d) +{ + const char *p0 = i0 ? a0 : a1; + const char *p1 = i1 ? p0 : a2; + const char *p2 = i2 ? p1 : a3; + + sink (p0, p1, p2); + + snprintf (d, 2, "%s", p2); // { dg-warning "\\\[-Wformat-truncation" } +} + +void g3 (char *d) +{ + const char *p0 = i0 ? a0 : a1; + const char *p1 = i1 ? p0 : a2; + const char *p2 = i2 ? p1 : a3; + const char *p3 = i3 ? p2 : a4; + + sink (p0, p1, p2, p3); + + snprintf (d, 3, "%s", p3); // { dg-warning "\\\[-Wformat-truncation" } +} + +void g4 (char *d) +{ + const char *p0 = i0 ? a0 : a1; + const char *p1 = i1 ? p0 : a2; + const char *p2 = i2 ? p1 : a3; + const char *p3 = i3 ? p2 : a4; + const char *p4 = i4 ? p3 : a5; + + sink (p0, p1, p2, p3, p4); + + // p4 below is the result of the following five PHI assignments + // and with the limit set to 4 the snprintf call is not diagnosed + // iftmp.0_7 = PHI <&a0(2), &a1(3)> + // iftmp.2_8 = PHI + // iftmp.4_9 = PHI + // iftmp.6_10 = PHI + // iftmp.8_17 = PHI + // p4 = iftmp.8_17 + snprintf (d, 4, "%s", p4); +} + +void g5 (char *d) +{ + const char *p0 = i0 ? a0 : a1; + const char *p1 = i1 ? p0 : a2; + const char *p2 = i2 ? p1 : a3; + const char *p3 = i3 ? p2 : a4; + const char *p4 = i4 ? p3 : a5; + const char *p5 = i5 ? p4 : a6; + + sink (p0, p1, p2, p3, p4, p5); + + snprintf (d, 5, "%s", p5); +} + +void g6 (char *d) +{ + const char *p0 = i0 ? a0 : a1; + const char *p1 = i1 ? p0 : a2; + const char *p2 = i2 ? p1 : a3; + const char *p3 = i3 ? p2 : a4; + const char *p4 = i4 ? p3 : a5; + const char *p5 = i5 ? p4 : a6; + const char *p6 = i6 ? p5 : a7; + + sink (p0, p1, p2, p3, p4, p5, p6); + + snprintf (d, 6, "%s", p6); +} + +void g7 (char *d) +{ + const char *p0 = i0 ? a0 : a1; + const char *p1 = i1 ? p0 : a2; + const char *p2 = i2 ? p1 : a3; + const char *p3 = i3 ? p2 : a4; + const char *p4 = i4 ? p3 : a5; + const char *p5 = i5 ? p4 : a6; + const char *p6 = i6 ? p5 : a7; + const char *p7 = i7 ? p6 : a8; + + sink (p0, p1, p2, p3, p4, p5, p6, p7); + + snprintf (d, 7, "%s", p7); +} + +void g8 (char *d) +{ + const char *p0 = i0 ? a0 : a1; + const char *p1 = i1 ? p0 : a2; + const char *p2 = i2 ? p1 : a3; + const char *p3 = i3 ? p2 : a4; + const char *p4 = i4 ? p3 : a5; + const char *p5 = i5 ? p4 : a6; + const char *p6 = i6 ? p5 : a7; + const char *p7 = i7 ? p6 : a8; + const char *p8 = i8 ? p7 : a9; + + sink (p0, p1, p2, p3, p4, p5, p6, p7, p8); + + snprintf (d, 8, "%s", p8); +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-21.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-21.c new file mode 100644 index 0000000..41f932a --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-21.c @@ -0,0 +1,94 @@ +/* PR tree-optimization/83431 -Wformat-truncation may incorrectly report + truncation + { dg-do compile } + { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */ + +typedef __SIZE_TYPE__ size_t; + +extern int snprintf (char*, size_t, const char*, ...); +extern char* strcpy (char*, const char*); + +struct S +{ + char a9[9]; + char a5[5]; + int x; +}; + + +void test_assign_nowarn (struct S* s) +{ + int i = 0; + + { + char a9[9] = "1234"; + snprintf (s[i].a5, sizeof (s[i].a5), "%s", a9); /* { dg-bogus "\\\[-Wformat-truncation]" } */ + } + + { + ++i; + char a8[8] = "123"; + snprintf (s[i].a5, sizeof (s[i].a5), "%s\n", a8); /* { dg-bogus "\\\[-Wformat-truncation]" } */ + } + + { + ++i; + char a7[7] = "12"; + snprintf (s[i].a5, sizeof (s[i].a5), "[%s]", a7); /* { dg-bogus "\\\[-Wformat-truncation]" } */ + } + + { + ++i; + char a6[6] = "1"; + snprintf (s[i].a5, sizeof (s[i].a5), "[%s]\n", a6); /* { dg-bogus "\\\[-Wformat-truncation]" } */ + } +} + + +void test_strcpy_nowarn (struct S* s) +{ + int i = 0; + + strcpy (s[i].a9, "1234"); + snprintf (s[i].a5, sizeof (s[i].a5), "%s", s[i].a9); + + ++i; + strcpy (s[i].a9, "123"); + snprintf (s[i].a5, sizeof (s[i].a5), "%s\n", s[i].a9); /* { dg-bogus "\\\[-Wformat-truncation]" } */ + + ++i; + strcpy (s[i].a9, "12"); + snprintf (s[i].a5, sizeof (s[i].a5), "[%s]", s[i].a9); /* { dg-bogus "\\\[-Wformat-truncation]" } */ + + ++i; + strcpy (s[i].a9, "1"); + snprintf (s[i].a5, sizeof (s[i].a5), "[%s]\n", s[i].a9); /* { dg-bogus "\\\[-Wformat-truncation]" } */ +} + + +void test_warn (struct S* s) +{ + int i = 0; + strcpy (s[i].a9, "12345678"); + snprintf (s[i].a5, sizeof (s[i].a5), "%s", s[i].a9); /* { dg-warning "'%s' directive output truncated writing 8 bytes into a region of size 5" } */ + + ++i; + strcpy (s[i].a9, "1234567"); + snprintf (s[i].a5, sizeof (s[i].a5), "%s", s[i].a9); /* { dg-warning "'%s' directive output truncated writing 7 bytes into a region of size 5" } */ + + ++i; + strcpy (s[i].a9, "123456"); + snprintf (s[i].a5, sizeof (s[i].a5), "%s", s[i].a9); /* { dg-warning "'%s' directive output truncated writing 6 bytes into a region of size 5" } */ + + ++i; + strcpy (s[i].a9, "12345"); + snprintf (s[i].a5, sizeof (s[i].a5), "%s", s[i].a9); /* { dg-warning "'snprintf' output truncated before the last format character" } */ + + ++i; + strcpy (s[i].a9, "1234"); + snprintf (s[i].a5, sizeof (s[i].a5), "%s\n", s[i].a9); /* { dg-warning "output truncated before the last format character" } */ + + ++i; + strcpy (s[i].a9, "123"); + snprintf (s[i].a5, sizeof (s[i].a5), ">%s<", s[i].a9); /* { dg-warning "output truncated before the last format character" } */ +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/dump-4.c b/gcc/testsuite/gcc.dg/tree-ssa/dump-4.c new file mode 100644 index 0000000..9377ed4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/dump-4.c @@ -0,0 +1,11 @@ +/* PR middle-end/87052 - STRING_CST printing incomplete in Gimple dumps + { dg-do compile } + { dg-options "-fdump-tree-original" } */ + +void* f (char *d, int c) +{ + return __builtin_memchr ("1\0\0", c, 4); +} + +/* Veriy the full string appears in the dump: + { dg-final { scan-tree-dump "\"1\\\\x00\\\\x00\"" "original" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr83501.c b/gcc/testsuite/gcc.dg/tree-ssa/pr83501.c index d8d3bf6..a301d0d 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr83501.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr83501.c @@ -11,4 +11,4 @@ void f (void) __builtin_abort (); } -/* { dg-final { scan-tree-dump-not "__builtin_strlen" "strlen" } } */ +/* { dg-final { scan-tree-dump-not "__builtin_strlen" "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/strlen-2.c b/gcc/testsuite/gcc.dg/tree-ssa/strlen-2.c index 1bca06f..079ee74 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/strlen-2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/strlen-2.c @@ -12,4 +12,4 @@ void f3 (void) f (__builtin_strlen (s)); } -/* { dg-final { scan-tree-dump-times "strlen" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen" 0 "strlen1" } } */ diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index 1c8df3d..be7603a 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -419,6 +419,7 @@ extern gimple_opt_pass *make_pass_omp_target_link (gcc::context *ctxt); extern gimple_opt_pass *make_pass_oacc_device_lower (gcc::context *ctxt); extern gimple_opt_pass *make_pass_omp_device_lower (gcc::context *ctxt); extern gimple_opt_pass *make_pass_object_sizes (gcc::context *ctxt); +extern gimple_opt_pass *make_pass_warn_printf (gcc::context *ctxt); extern gimple_opt_pass *make_pass_strlen (gcc::context *ctxt); extern gimple_opt_pass *make_pass_fold_builtins (gcc::context *ctxt); extern gimple_opt_pass *make_pass_post_ipa_warn (gcc::context *ctxt); diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index ef2b6ae..5c5b838 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -55,6 +55,12 @@ along with GCC; see the file COPYING3. If not see #include "intl.h" #include "attribs.h" #include "calls.h" +#include "cfgloop.h" +#include "tree-ssa-loop.h" +#include "tree-scalar-evolution.h" + +#include "vr-values.h" +#include "gimple-ssa-evrp-analyze.h" /* A vector indexed by SSA_NAME_VERSION. 0 means unknown, positive value is an index into strinfo vector, negative value stands for @@ -64,6 +70,9 @@ static vec ssa_ver_to_stridx; /* Number of currently active string indexes plus one. */ static int max_stridx; +/* Set to true to optimize, false when just checking. */ +static bool strlen_optimize; + /* String information record. */ struct strinfo { @@ -154,7 +163,8 @@ struct decl_stridxlist_map /* Hash table for mapping decls to a chained list of offset -> idx mappings. */ -static hash_map *decl_to_stridxlist_htab; +typedef hash_map decl_to_stridxlist_htab_t; +static decl_to_stridxlist_htab_t *decl_to_stridxlist_htab; /* Hash table mapping strlen (or strnlen with constant bound and return smaller than bound) calls to stridx instances describing @@ -604,14 +614,21 @@ set_endptr_and_length (location_t loc, strinfo *si, tree endptr) si->full_string_p = true; } -/* Return string length, or NULL if it can't be computed. */ +/* Return the string length, or NULL if it can't be computed. + The length may but need not be constant. Instead, it might be + the result of a strlen() call. */ static tree get_string_length (strinfo *si) { + /* If the length has already been computed return it if it's exact + (i.e., the string is nul-terminated at NONZERO_CHARS), or return + null if it isn't. */ if (si->nonzero_chars) return si->full_string_p ? si->nonzero_chars : NULL; + /* If the string is the result of one of the built-in calls below + attempt to compute the length from the call statement. */ if (si->stmt) { gimple *stmt = si->stmt, *lenstmt; @@ -702,6 +719,336 @@ get_string_length (strinfo *si) return si->nonzero_chars; } +/* Dump strlen data to FP for statement STMT. When non-null, RVALS + points to EVRP info and is used to dump strlen range for non-constant + results. */ + +DEBUG_FUNCTION void +dump_strlen_info (FILE *fp, gimple *stmt, const vr_values *rvals) +{ + if (stmt) + { + fprintf (fp, "\nDumping strlen pass data after "); + print_gimple_expr (fp, stmt, TDF_LINENO); + fputc ('\n', fp); + } + else + fprintf (fp, "\nDumping strlen pass data\n"); + + fprintf (fp, "max_stridx = %i\n", max_stridx); + fprintf (fp, "ssa_ver_to_stridx has %u elements\n", + ssa_ver_to_stridx.length ()); + fprintf (fp, "stridx_to_strinfo"); + if (stridx_to_strinfo) + { + fprintf (fp, " has %u elements\n", stridx_to_strinfo->length ()); + for (unsigned i = 0; i != stridx_to_strinfo->length (); ++i) + { + if (strinfo *si = (*stridx_to_strinfo)[i]) + { + if (!si->idx) + continue; + fprintf (fp, " idx = %i", si->idx); + if (si->ptr) + { + fprintf (fp, ", ptr = "); + print_generic_expr (fp, si->ptr); + } + fprintf (fp, ", nonzero_chars = "); + print_generic_expr (fp, si->nonzero_chars); + if (TREE_CODE (si->nonzero_chars) == SSA_NAME) + { + value_range_kind rng = VR_UNDEFINED; + wide_int min, max; + if (rvals) + { + const value_range *vr + = CONST_CAST (class vr_values *, rvals) + ->get_value_range (si->nonzero_chars); + rng = vr->kind (); + if (range_int_cst_p (vr)) + { + min = wi::to_wide (vr->min ()); + max = wi::to_wide (vr->max ()); + } + else + rng = VR_UNDEFINED; + } + else + rng = get_range_info (si->nonzero_chars, &min, &max); + + if (rng == VR_RANGE || rng == VR_ANTI_RANGE) + { + fprintf (fp, " %s[%llu, %llu]", + rng == VR_RANGE ? "" : "~", + (long long) min.to_uhwi (), + (long long) max.to_uhwi ()); + } + } + fprintf (fp, " , refcount = %i", si->refcount); + if (si->stmt) + { + fprintf (fp, ", stmt = "); + print_gimple_expr (fp, si->stmt, 0); + } + if (si->writable) + fprintf (fp, ", writable"); + if (si->full_string_p) + fprintf (fp, ", full_string_p"); + if (strinfo *next = get_next_strinfo (si)) + { + fprintf (fp, ", {"); + do + fprintf (fp, "%i%s", next->idx, next->first ? ", " : ""); + while ((next = get_next_strinfo (next))); + fprintf (fp, "}"); + } + fputs ("\n", fp); + } + } + } + else + fprintf (fp, " = null\n"); + + fprintf (fp, "decl_to_stridxlist_htab"); + if (decl_to_stridxlist_htab) + { + fputs ("\n", fp); + typedef decl_to_stridxlist_htab_t::iterator iter_t; + for (iter_t it = decl_to_stridxlist_htab->begin (); + it != decl_to_stridxlist_htab->end (); ++it) + { + tree decl = (*it).first; + stridxlist *list = &(*it).second; + fprintf (fp, " decl = "); + print_generic_expr (fp, decl); + if (list) + { + fprintf (fp, ", offsets = {"); + for (; list; list = list->next) + fprintf (fp, "%lli%s", (long long) list->offset, + list->next ? ", " : ""); + fputs ("}", fp); + } + fputs ("\n", fp); + } + } + else + fprintf (fp, " = null\n"); + + if (laststmt.stmt) + { + fprintf (fp, "laststmt = "); + print_gimple_expr (fp, laststmt.stmt, 0); + fprintf (fp, ", len = "); + print_generic_expr (fp, laststmt.len); + fprintf (fp, ", stridx = %i\n", laststmt.stridx); + } +} + +/* Attempt to determine the length of the string SRC. On success, store + the length in *PDATA and return true. Otherwise, return false. + VISITED is a bitmap of visited PHI nodes. RVALS points to EVRP info + and PSSA_DEF_MAX to an SSA_NAME assignment limit used to prevent runaway + recursion. */ + +static bool +get_range_strlen_dynamic (tree src, c_strlen_data *pdata, bitmap *visited, + const vr_values *rvals, unsigned *pssa_def_max) +{ + int idx = get_stridx (src); + if (!idx) + { + if (TREE_CODE (src) == SSA_NAME) + { + gimple *def_stmt = SSA_NAME_DEF_STMT (src); + if (gimple_code (def_stmt) == GIMPLE_PHI) + { + if (!*visited) + *visited = BITMAP_ALLOC (NULL); + + if (!bitmap_set_bit (*visited, SSA_NAME_VERSION (src))) + return true; + + if (*pssa_def_max == 0) + return false; + + --*pssa_def_max; + + /* Iterate over the PHI arguments and determine the minimum + and maximum length/size of each and incorporate them into + the overall result. */ + gphi *phi = as_a (def_stmt); + for (unsigned i = 0; i != gimple_phi_num_args (phi); ++i) + { + tree arg = gimple_phi_arg_def (phi, i); + if (arg == gimple_phi_result (def_stmt)) + continue; + + c_strlen_data argdata = { }; + if (get_range_strlen_dynamic (arg, &argdata, visited, rvals, + pssa_def_max)) + { + /* Set the DECL of an unterminated array this argument + refers to if one hasn't been found yet. */ + if (!pdata->decl && argdata.decl) + pdata->decl = argdata.decl; + + if (!argdata.minlen + || (integer_zerop (argdata.minlen) + && integer_all_onesp (argdata.maxbound) + && integer_all_onesp (argdata.maxlen))) + { + /* Set the upper bound of the length to unbounded. */ + pdata->maxlen = build_all_ones_cst (size_type_node); + continue; + } + + /* Adjust the minimum and maximum length determined + so far and the upper bound on the array size. */ + if (!pdata->minlen + || tree_int_cst_lt (argdata.minlen, pdata->minlen)) + pdata->minlen = argdata.minlen; + if (!pdata->maxlen + || tree_int_cst_lt (pdata->maxlen, argdata.maxlen)) + pdata->maxlen = argdata.maxlen; + if (!pdata->maxbound + || (tree_int_cst_lt (pdata->maxbound, + argdata.maxbound) + && !integer_all_onesp (argdata.maxbound))) + pdata->maxbound = argdata.maxbound; + } + else + pdata->maxlen = build_all_ones_cst (size_type_node); + } + + return true; + } + } + + /* Return success regardless of the result and handle *PDATA + in the caller. */ + get_range_strlen (src, pdata, 1); + return true; + } + + if (idx < 0) + { + /* SRC is a string of constant length. */ + pdata->minlen = build_int_cst (size_type_node, ~idx); + pdata->maxlen = pdata->minlen; + pdata->maxbound = pdata->maxlen; + return true; + } + + if (strinfo *si = get_strinfo (idx)) + { + pdata->minlen = get_string_length (si); + if (!pdata->minlen + && si->nonzero_chars) + { + if (TREE_CODE (si->nonzero_chars) == INTEGER_CST) + pdata->minlen = si->nonzero_chars; + else if (TREE_CODE (si->nonzero_chars) == SSA_NAME) + { + const value_range *vr + = CONST_CAST (class vr_values *, rvals) + ->get_value_range (si->nonzero_chars); + if (vr->kind () == VR_RANGE + && range_int_cst_p (vr)) + { + pdata->minlen = vr->min (); + pdata->maxlen = vr->max (); + } + else + pdata->minlen = build_zero_cst (size_type_node); + } + else + pdata->minlen = build_zero_cst (size_type_node); + + tree base = si->ptr; + if (TREE_CODE (base) == ADDR_EXPR) + base = TREE_OPERAND (base, 0); + + HOST_WIDE_INT off; + poly_int64 poff; + base = get_addr_base_and_unit_offset (base, &poff); + if (base + && DECL_P (base) + && TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE + && TYPE_SIZE_UNIT (TREE_TYPE (base)) + && poff.is_constant (&off)) + { + tree basetype = TREE_TYPE (base); + tree size = TYPE_SIZE_UNIT (basetype); + ++off; /* Increment for the terminating nul. */ + pdata->maxlen = fold_build2 (MINUS_EXPR, size_type_node, size, + build_int_cst (size_type_node, off)); + pdata->maxbound = pdata->maxlen; + } + else + pdata->maxlen = build_all_ones_cst (size_type_node); + } + else if (TREE_CODE (pdata->minlen) == SSA_NAME) + { + const value_range *vr + = CONST_CAST (class vr_values *, rvals) + ->get_value_range (si->nonzero_chars); + if (vr->kind () == VR_RANGE + && range_int_cst_p (vr)) + { + pdata->minlen = vr->min (); + pdata->maxlen = vr->max (); + pdata->maxbound = pdata->maxlen; + } + else + { + pdata->minlen = build_zero_cst (size_type_node); + pdata->maxlen = build_all_ones_cst (size_type_node); + } + } + else + { + pdata->maxlen = pdata->minlen; + pdata->maxbound = pdata->minlen; + } + + return true; + } + + return false; +} + +/* Analogous to get_range_strlen but for dynamically created strings, + i.e., those created by calls to strcpy as opposed to just string + constants. + Try to obtain the range of the lengths of the string(s) referenced + by SRC, or the size of the largest array SRC refers to if the range + of lengths cannot be determined, and store all in *PDATA. RVALS + points to EVRP info. */ + +void +get_range_strlen_dynamic (tree src, c_strlen_data *pdata, + const vr_values *rvals) +{ + bitmap visited = NULL; + + unsigned limit = PARAM_VALUE (PARAM_SSA_NAME_DEF_CHAIN_LIMIT); + if (!get_range_strlen_dynamic (src, pdata, &visited, rvals, &limit)) + { + /* On failure extend the length range to an impossible maximum + (a valid MAXLEN must be less than PTRDIFF_MAX - 1). Other + members can stay unchanged regardless. */ + pdata->minlen = ssize_int (0); + pdata->maxlen = build_all_ones_cst (size_type_node); + } + else if (!pdata->minlen) + pdata->minlen = ssize_int (0); + + if (visited) + BITMAP_FREE (visited); +} + /* Invalidate string length information for strings whose length might change due to stores in stmt. */ @@ -4017,84 +4364,232 @@ is_char_type (tree type) && TYPE_PRECISION (type) == TYPE_PRECISION (char_type_node)); } +/* Check the built-in call at GSI for validity and optimize it. + Return true to let the caller advance *GSI to the statement + in the CFG and false otherwise. */ + +static bool +strlen_check_and_optimize_call (gimple_stmt_iterator *gsi, + const vr_values *rvals) +{ + gimple *stmt = gsi_stmt (*gsi); + + if (!flag_optimize_strlen + || !strlen_optimize + || !valid_builtin_call (stmt)) + { + /* When not optimizing we must be checking printf calls which + we do even for user-defined functions when they are declared + with attribute format. */ + handle_printf_call (gsi, rvals); + return true; + } + + tree callee = gimple_call_fndecl (stmt); + switch (DECL_FUNCTION_CODE (callee)) + { + case BUILT_IN_STRLEN: + case BUILT_IN_STRNLEN: + handle_builtin_strlen (gsi); + break; + case BUILT_IN_STRCHR: + handle_builtin_strchr (gsi); + break; + case BUILT_IN_STRCPY: + case BUILT_IN_STRCPY_CHK: + case BUILT_IN_STPCPY: + case BUILT_IN_STPCPY_CHK: + handle_builtin_strcpy (DECL_FUNCTION_CODE (callee), gsi); + break; + + case BUILT_IN_STRNCAT: + case BUILT_IN_STRNCAT_CHK: + handle_builtin_strncat (DECL_FUNCTION_CODE (callee), gsi); + break; + + case BUILT_IN_STPNCPY: + case BUILT_IN_STPNCPY_CHK: + case BUILT_IN_STRNCPY: + case BUILT_IN_STRNCPY_CHK: + handle_builtin_stxncpy (DECL_FUNCTION_CODE (callee), gsi); + break; + + case BUILT_IN_MEMCPY: + case BUILT_IN_MEMCPY_CHK: + case BUILT_IN_MEMPCPY: + case BUILT_IN_MEMPCPY_CHK: + handle_builtin_memcpy (DECL_FUNCTION_CODE (callee), gsi); + break; + case BUILT_IN_STRCAT: + case BUILT_IN_STRCAT_CHK: + handle_builtin_strcat (DECL_FUNCTION_CODE (callee), gsi); + break; + case BUILT_IN_MALLOC: + case BUILT_IN_CALLOC: + handle_builtin_malloc (DECL_FUNCTION_CODE (callee), gsi); + break; + case BUILT_IN_MEMSET: + if (handle_builtin_memset (gsi)) + return false; + break; + case BUILT_IN_MEMCMP: + if (handle_builtin_memcmp (gsi)) + return false; + break; + case BUILT_IN_STRCMP: + case BUILT_IN_STRNCMP: + if (handle_builtin_string_cmp (gsi)) + return false; + break; + default: + handle_printf_call (gsi, rvals); + break; + } + + return true; +} + +/* Handle an assignment statement at *GSI to a LHS of integral type. + If GSI's basic block needs clean-up of EH, set *CLEANUP_EH to true. */ + +static void +handle_integral_assign (gimple_stmt_iterator *gsi, bool *cleanup_eh) +{ + gimple *stmt = gsi_stmt (*gsi); + tree lhs = gimple_assign_lhs (stmt); + tree lhs_type = TREE_TYPE (lhs); + + enum tree_code code = gimple_assign_rhs_code (stmt); + if (code == COND_EXPR) + { + tree cond = gimple_assign_rhs1 (stmt); + enum tree_code cond_code = TREE_CODE (cond); + + if (cond_code == EQ_EXPR || cond_code == NE_EXPR) + fold_strstr_to_strncmp (TREE_OPERAND (cond, 0), + TREE_OPERAND (cond, 1), stmt); + } + else if (code == EQ_EXPR || code == NE_EXPR) + fold_strstr_to_strncmp (gimple_assign_rhs1 (stmt), + gimple_assign_rhs2 (stmt), stmt); + else if (gimple_assign_load_p (stmt) + && TREE_CODE (lhs_type) == INTEGER_TYPE + && TYPE_MODE (lhs_type) == TYPE_MODE (char_type_node) + && (TYPE_PRECISION (lhs_type) + == TYPE_PRECISION (char_type_node)) + && !gimple_has_volatile_ops (stmt)) + { + tree off = integer_zero_node; + unsigned HOST_WIDE_INT coff = 0; + int idx = 0; + tree rhs1 = gimple_assign_rhs1 (stmt); + if (code == MEM_REF) + { + idx = get_stridx (TREE_OPERAND (rhs1, 0)); + if (idx > 0) + { + strinfo *si = get_strinfo (idx); + if (si + && si->nonzero_chars + && TREE_CODE (si->nonzero_chars) == INTEGER_CST + && (wi::to_widest (si->nonzero_chars) + >= wi::to_widest (off))) + off = TREE_OPERAND (rhs1, 1); + else + /* This case is not useful. See if get_addr_stridx + returns something usable. */ + idx = 0; + } + } + if (idx <= 0) + idx = get_addr_stridx (rhs1, NULL_TREE, &coff); + if (idx > 0) + { + strinfo *si = get_strinfo (idx); + if (si + && si->nonzero_chars + && TREE_CODE (si->nonzero_chars) == INTEGER_CST) + { + widest_int w1 = wi::to_widest (si->nonzero_chars); + widest_int w2 = wi::to_widest (off) + coff; + if (w1 == w2 + && si->full_string_p) + { + if (dump_file && (dump_flags & TDF_DETAILS) != 0) + { + fprintf (dump_file, "Optimizing: "); + print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); + } + + /* Reading the final '\0' character. */ + tree zero = build_int_cst (lhs_type, 0); + gimple_set_vuse (stmt, NULL_TREE); + gimple_assign_set_rhs_from_tree (gsi, zero); + *cleanup_eh + |= maybe_clean_or_replace_eh_stmt (stmt, + gsi_stmt (*gsi)); + stmt = gsi_stmt (*gsi); + update_stmt (stmt); + + if (dump_file && (dump_flags & TDF_DETAILS) != 0) + { + fprintf (dump_file, "into: "); + print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); + } + } + else if (w1 > w2) + { + /* Reading a character before the final '\0' + character. Just set the value range to ~[0, 0] + if we don't have anything better. */ + wide_int min, max; + signop sign = TYPE_SIGN (lhs_type); + int prec = TYPE_PRECISION (lhs_type); + value_range_kind vr = get_range_info (lhs, &min, &max); + if (vr == VR_VARYING + || (vr == VR_RANGE + && min == wi::min_value (prec, sign) + && max == wi::max_value (prec, sign))) + set_range_info (lhs, VR_ANTI_RANGE, + wi::zero (prec), wi::zero (prec)); + } + } + } + } + + if (strlen_to_stridx) + { + tree rhs1 = gimple_assign_rhs1 (stmt); + if (stridx_strlenloc *ps = strlen_to_stridx->get (rhs1)) + strlen_to_stridx->put (lhs, stridx_strlenloc (*ps)); + } +} + /* Attempt to check for validity of the performed access a single statement at *GSI using string length knowledge, and to optimize it. If the given basic block needs clean-up of EH, CLEANUP_EH is set to true. */ static bool -strlen_check_and_optimize_stmt (gimple_stmt_iterator *gsi, bool *cleanup_eh) +check_and_optimize_stmt (gimple_stmt_iterator *gsi, bool *cleanup_eh, + const vr_values *rvals) { gimple *stmt = gsi_stmt (*gsi); if (is_gimple_call (stmt)) { - tree callee = gimple_call_fndecl (stmt); - if (valid_builtin_call (stmt)) - switch (DECL_FUNCTION_CODE (callee)) - { - case BUILT_IN_STRLEN: - case BUILT_IN_STRNLEN: - handle_builtin_strlen (gsi); - break; - case BUILT_IN_STRCHR: - handle_builtin_strchr (gsi); - break; - case BUILT_IN_STRCPY: - case BUILT_IN_STRCPY_CHK: - case BUILT_IN_STPCPY: - case BUILT_IN_STPCPY_CHK: - handle_builtin_strcpy (DECL_FUNCTION_CODE (callee), gsi); - break; - - case BUILT_IN_STRNCAT: - case BUILT_IN_STRNCAT_CHK: - handle_builtin_strncat (DECL_FUNCTION_CODE (callee), gsi); - break; - - case BUILT_IN_STPNCPY: - case BUILT_IN_STPNCPY_CHK: - case BUILT_IN_STRNCPY: - case BUILT_IN_STRNCPY_CHK: - handle_builtin_stxncpy (DECL_FUNCTION_CODE (callee), gsi); - break; - - case BUILT_IN_MEMCPY: - case BUILT_IN_MEMCPY_CHK: - case BUILT_IN_MEMPCPY: - case BUILT_IN_MEMPCPY_CHK: - handle_builtin_memcpy (DECL_FUNCTION_CODE (callee), gsi); - break; - case BUILT_IN_STRCAT: - case BUILT_IN_STRCAT_CHK: - handle_builtin_strcat (DECL_FUNCTION_CODE (callee), gsi); - break; - case BUILT_IN_MALLOC: - case BUILT_IN_CALLOC: - handle_builtin_malloc (DECL_FUNCTION_CODE (callee), gsi); - break; - case BUILT_IN_MEMSET: - if (handle_builtin_memset (gsi)) - return false; - break; - case BUILT_IN_MEMCMP: - if (handle_builtin_memcmp (gsi)) - return false; - break; - case BUILT_IN_STRCMP: - case BUILT_IN_STRNCMP: - if (handle_builtin_string_cmp (gsi)) - return false; - break; - default: - break; - } + if (!strlen_check_and_optimize_call (gsi, rvals)) + return false; } + else if (!flag_optimize_strlen || !strlen_optimize) + return true; else if (is_gimple_assign (stmt) && !gimple_clobber_p (stmt)) { + /* Handle non-clobbering assignment. */ tree lhs = gimple_assign_lhs (stmt); + tree lhs_type = TREE_TYPE (lhs); - if (TREE_CODE (lhs) == SSA_NAME && POINTER_TYPE_P (TREE_TYPE (lhs))) + if (TREE_CODE (lhs) == SSA_NAME && POINTER_TYPE_P (lhs_type)) { if (gimple_assign_single_p (stmt) || (gimple_assign_cast_p (stmt) @@ -4106,117 +4601,10 @@ strlen_check_and_optimize_stmt (gimple_stmt_iterator *gsi, bool *cleanup_eh) else if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR) handle_pointer_plus (gsi); } - else if (TREE_CODE (lhs) == SSA_NAME && INTEGRAL_TYPE_P (TREE_TYPE (lhs))) - { - enum tree_code code = gimple_assign_rhs_code (stmt); - if (code == COND_EXPR) - { - tree cond = gimple_assign_rhs1 (stmt); - enum tree_code cond_code = TREE_CODE (cond); - - if (cond_code == EQ_EXPR || cond_code == NE_EXPR) - fold_strstr_to_strncmp (TREE_OPERAND (cond, 0), - TREE_OPERAND (cond, 1), stmt); - } - else if (code == EQ_EXPR || code == NE_EXPR) - fold_strstr_to_strncmp (gimple_assign_rhs1 (stmt), - gimple_assign_rhs2 (stmt), stmt); - else if (gimple_assign_load_p (stmt) - && TREE_CODE (TREE_TYPE (lhs)) == INTEGER_TYPE - && TYPE_MODE (TREE_TYPE (lhs)) == TYPE_MODE (char_type_node) - && (TYPE_PRECISION (TREE_TYPE (lhs)) - == TYPE_PRECISION (char_type_node)) - && !gimple_has_volatile_ops (stmt)) - { - tree off = integer_zero_node; - unsigned HOST_WIDE_INT coff = 0; - int idx = 0; - tree rhs1 = gimple_assign_rhs1 (stmt); - if (code == MEM_REF) - { - idx = get_stridx (TREE_OPERAND (rhs1, 0)); - if (idx > 0) - { - strinfo *si = get_strinfo (idx); - if (si - && si->nonzero_chars - && TREE_CODE (si->nonzero_chars) == INTEGER_CST - && (wi::to_widest (si->nonzero_chars) - >= wi::to_widest (off))) - off = TREE_OPERAND (rhs1, 1); - else - /* This case is not useful. See if get_addr_stridx - returns something usable. */ - idx = 0; - } - } - if (idx <= 0) - idx = get_addr_stridx (rhs1, NULL_TREE, &coff); - if (idx > 0) - { - strinfo *si = get_strinfo (idx); - if (si - && si->nonzero_chars - && TREE_CODE (si->nonzero_chars) == INTEGER_CST) - { - widest_int w1 = wi::to_widest (si->nonzero_chars); - widest_int w2 = wi::to_widest (off) + coff; - if (w1 == w2 - && si->full_string_p) - { - if (dump_file && (dump_flags & TDF_DETAILS) != 0) - { - fprintf (dump_file, "Optimizing: "); - print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); - } - - /* Reading the final '\0' character. */ - tree zero = build_int_cst (TREE_TYPE (lhs), 0); - gimple_set_vuse (stmt, NULL_TREE); - gimple_assign_set_rhs_from_tree (gsi, zero); - *cleanup_eh - |= maybe_clean_or_replace_eh_stmt (stmt, - gsi_stmt (*gsi)); - stmt = gsi_stmt (*gsi); - update_stmt (stmt); - - if (dump_file && (dump_flags & TDF_DETAILS) != 0) - { - fprintf (dump_file, "into: "); - print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); - } - } - else if (w1 > w2) - { - /* Reading a character before the final '\0' - character. Just set the value range to ~[0, 0] - if we don't have anything better. */ - wide_int min, max; - tree type = TREE_TYPE (lhs); - enum value_range_kind vr - = get_range_info (lhs, &min, &max); - if (vr == VR_VARYING - || (vr == VR_RANGE - && min == wi::min_value (TYPE_PRECISION (type), - TYPE_SIGN (type)) - && max == wi::max_value (TYPE_PRECISION (type), - TYPE_SIGN (type)))) - set_range_info (lhs, VR_ANTI_RANGE, - wi::zero (TYPE_PRECISION (type)), - wi::zero (TYPE_PRECISION (type))); - } - } - } - } - - if (strlen_to_stridx) - { - tree rhs1 = gimple_assign_rhs1 (stmt); - if (stridx_strlenloc *ps = strlen_to_stridx->get (rhs1)) - strlen_to_stridx->put (lhs, stridx_strlenloc (*ps)); - } - } - else if (TREE_CODE (lhs) != SSA_NAME && !TREE_SIDE_EFFECTS (lhs)) + else if (TREE_CODE (lhs) == SSA_NAME && INTEGRAL_TYPE_P (lhs_type)) + /* Handle assignment to a character. */ + handle_integral_assign (gsi, cleanup_eh); + else if (TREE_CODE (lhs) != SSA_NAME && !TREE_SIDE_EFFECTS (lhs)) { tree type = TREE_TYPE (lhs); if (TREE_CODE (type) == ARRAY_TYPE) @@ -4312,12 +4700,18 @@ class strlen_dom_walker : public dom_walker { public: strlen_dom_walker (cdi_direction direction) - : dom_walker (direction), m_cleanup_cfg (false) + : dom_walker (direction), + evrp (false), + m_cleanup_cfg (false) {} virtual edge before_dom_children (basic_block); virtual void after_dom_children (basic_block); + /* EVRP analyzer used for printf argument range processing, and + to track strlen results across integer variable assignments. */ + evrp_range_analyzer evrp; + /* Flag that will trigger TODO_cleanup_cfg to be returned in strlen execute function. */ bool m_cleanup_cfg; @@ -4329,6 +4723,8 @@ public: edge strlen_dom_walker::before_dom_children (basic_block bb) { + evrp.enter (bb); + basic_block dombb = get_immediate_dominator (CDI_DOMINATORS, bb); if (dombb == NULL) @@ -4402,8 +4798,16 @@ strlen_dom_walker::before_dom_children (basic_block bb) /* Attempt to optimize individual statements. */ for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); ) - if (strlen_check_and_optimize_stmt (&gsi, &cleanup_eh)) - gsi_next (&gsi); + { + gimple *stmt = gsi_stmt (gsi); + + /* First record ranges generated by this statement so they + can be used by printf argument processing. */ + evrp.record_ranges_from_stmt (stmt, false); + + if (check_and_optimize_stmt (&gsi, &cleanup_eh, evrp.get_vr_values ())) + gsi_next (&gsi); + } if (cleanup_eh && gimple_purge_dead_eh_edges (bb)) m_cleanup_cfg = true; @@ -4420,6 +4824,8 @@ strlen_dom_walker::before_dom_children (basic_block bb) void strlen_dom_walker::after_dom_children (basic_block bb) { + evrp.leave (bb); + if (bb->aux) { stridx_to_strinfo = ((vec *) bb->aux); @@ -4437,39 +4843,13 @@ strlen_dom_walker::after_dom_children (basic_block bb) } } -/* Main entry point. */ - namespace { -const pass_data pass_data_strlen = -{ - GIMPLE_PASS, /* type */ - "strlen", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - TV_TREE_STRLEN, /* tv_id */ - ( PROP_cfg | PROP_ssa ), /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - 0, /* todo_flags_finish */ -}; - -class pass_strlen : public gimple_opt_pass +static unsigned int +printf_strlen_execute (function *fun, bool warn_only) { -public: - pass_strlen (gcc::context *ctxt) - : gimple_opt_pass (pass_data_strlen, ctxt) - {} + strlen_optimize = !warn_only; - /* opt_pass methods: */ - virtual bool gate (function *) { return flag_optimize_strlen != 0; } - virtual unsigned int execute (function *); - -}; // class pass_strlen - -unsigned int -pass_strlen::execute (function *fun) -{ gcc_assert (!strlen_to_stridx); if (warn_stringop_overflow || warn_stringop_truncation) strlen_to_stridx = new hash_map (); @@ -4479,10 +4859,17 @@ pass_strlen::execute (function *fun) calculate_dominance_info (CDI_DOMINATORS); + bool use_scev = optimize > 0 && flag_printf_return_value; + if (use_scev) + { + loop_optimizer_init (LOOPS_NORMAL); + scev_initialize (); + } + /* String length optimization is implemented as a walk of the dominator tree and a forward walk of statements within each block. */ strlen_dom_walker walker (CDI_DOMINATORS); - walker.walk (fun->cfg->x_entry_block_ptr); + walker.walk (ENTRY_BLOCK_PTR_FOR_FN (fun)); ssa_ver_to_stridx.release (); strinfo_pool.release (); @@ -4503,12 +4890,114 @@ pass_strlen::execute (function *fun) strlen_to_stridx = NULL; } + if (use_scev) + { + scev_finalize (); + loop_optimizer_finalize (); + } + + /* Clean up object size info. */ + fini_object_sizes (); + return walker.m_cleanup_cfg ? TODO_cleanup_cfg : 0; } +/* This file defines two passes: one for warnings that runs only when + optimization is disabled, and another that implements optimizations + and also issues warnings. */ + +const pass_data pass_data_warn_printf = +{ + GIMPLE_PASS, /* type */ + "warn-printf", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + TV_NONE, /* tv_id */ + /* Normally an optimization pass would require PROP_ssa but because + this pass runs early, with no optimization, to do sprintf format + checking, it only requires PROP_cfg. */ + PROP_cfg, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ +}; + +class pass_warn_printf : public gimple_opt_pass +{ +public: + pass_warn_printf (gcc::context *ctxt) + : gimple_opt_pass (pass_data_warn_printf, ctxt) + {} + + virtual bool gate (function *); + virtual unsigned int execute (function *fun) + { + return printf_strlen_execute (fun, true); + } +}; + + +/* Return true to run the warning pass only when not optimizing and + iff either -Wformat-overflow or -Wformat-truncation is specified. */ + +bool +pass_warn_printf::gate (function *) +{ + return !optimize && (warn_format_overflow > 0 || warn_format_trunc > 0); +} + +const pass_data pass_data_strlen = +{ + GIMPLE_PASS, /* type */ + "strlen", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + TV_TREE_STRLEN, /* tv_id */ + PROP_cfg | PROP_ssa, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ +}; + +class pass_strlen : public gimple_opt_pass +{ +public: + pass_strlen (gcc::context *ctxt) + : gimple_opt_pass (pass_data_strlen, ctxt) + {} + + opt_pass * clone () { return new pass_strlen (m_ctxt); } + + virtual bool gate (function *); + virtual unsigned int execute (function *fun) + { + return printf_strlen_execute (fun, false); + } +}; + +/* Return true to run the pass only when the sprintf and/or strlen + optimizations are enabled and -Wformat-overflow or -Wformat-truncation + are specified. */ + +bool +pass_strlen::gate (function *) +{ + return ((warn_format_overflow > 0 + || warn_format_trunc > 0 + || flag_optimize_strlen > 0 + || flag_printf_return_value) + && optimize > 0); +} + } // anon namespace gimple_opt_pass * +make_pass_warn_printf (gcc::context *ctxt) +{ + return new pass_warn_printf (ctxt); +} + +gimple_opt_pass * make_pass_strlen (gcc::context *ctxt) { return new pass_strlen (ctxt); diff --git a/gcc/tree-ssa-strlen.h b/gcc/tree-ssa-strlen.h index 395c74e..4d43fc6 100644 --- a/gcc/tree-ssa-strlen.h +++ b/gcc/tree-ssa-strlen.h @@ -25,4 +25,11 @@ extern bool is_strlen_related_p (tree, tree); extern bool maybe_diag_stxncpy_trunc (gimple_stmt_iterator, tree, tree); extern tree set_strlen_range (tree, wide_int, wide_int, tree = NULL_TREE); +struct c_strlen_data; +class vr_values; +extern void get_range_strlen_dynamic (tree , c_strlen_data *, const vr_values *); + +/* APIs internal to strlen pass. Defined in in gimple-ssa-sprintf.c. */ +extern bool handle_printf_call (gimple_stmt_iterator *, const vr_values *); + #endif // GCC_TREE_SSA_STRLEN_H diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 4145bcc..5ec4d17 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -369,7 +369,7 @@ value_range_base::singleton_p (tree *result) const tree value_range_base::type () const { - gcc_assert (m_min || undefined_p ()); + gcc_assert (m_min); return TREE_TYPE (min ()); } diff --git a/gcc/vr-values.c b/gcc/vr-values.c index 6f9a361..96c764c 100644 --- a/gcc/vr-values.c +++ b/gcc/vr-values.c @@ -234,7 +234,7 @@ vr_values::update_value_range (const_tree var, value_range *new_vr) called, if we are anyway, keep it VARYING. */ if (old_vr->varying_p ()) { - new_vr->set_varying (new_vr->type ()); + new_vr->set_varying (TREE_TYPE (var)); is_new = false; } else if (new_vr->undefined_p ()) -- cgit v1.1 From 0e883151165b2039469cb2fdcf33c7f8f59782c0 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Mon, 26 Aug 2019 21:18:30 +0200 Subject: i386.c (emit_i387_cw_initialization): Fix masking operand value. * config/i386/i386.c (emit_i387_cw_initialization) : Fix masking operand value. From-SVN: r274934 --- gcc/ChangeLog | 7 ++++++- gcc/config/i386/i386.c | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 852382e..3772757 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,9 @@ -2019-08-23 Martin Sebor +2019-08-26 Uroš Bizjak + + * config/i386/i386.c (emit_i387_cw_initialization) + : Fix masking operand value. + +2019-08-26 Martin Sebor PR c++/83431 * gimple-ssa-sprintf.c (pass_data_sprintf_length): Remove object. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index c712c03..f3b3a9a 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -13785,7 +13785,7 @@ emit_i387_cw_initialization (int mode) { case I387_CW_ROUNDEVEN: /* round to nearest */ - emit_insn (gen_andhi3 (reg, reg, GEN_INT (0x0c00))); + emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00))); slot = SLOT_CW_ROUNDEVEN; break; -- cgit v1.1 From 4d67cae5e6671aaa433b6d6a96c9da47cfd71b45 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 26 Aug 2019 19:55:41 +0000 Subject: compiler: generalize cleanup of unresolved placeholder pointer types This change extends the work in https://golang.org/cl/51131 to include placeholder pointer types created for Go function types, which can also be left dangling/unresolved in some instances. This fixes an assert in Llvm_backend::materializeComposite. Test case can be found in https://golang.org/cl/191743. Updates golang/go#33020. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/191744 From-SVN: r274935 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/types.cc | 17 +++++++++-------- gcc/go/gofrontend/types.h | 2 +- 3 files changed, 11 insertions(+), 10 deletions(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 73c7534..4f08f23 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -c9ca1c6bf887c752cc75cf1ddaec8ddd1ec962d4 +58c0fc64d91edc53ef9828b85cf3dc86aeb94e12 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index b46525d..20f8f27 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -1138,6 +1138,7 @@ Type::get_backend_placeholder(Gogo* gogo) // A Go function type is a pointer to a struct type. Location loc = this->function_type()->location(); bt = gogo->backend()->placeholder_pointer_type("", loc, false); + Type::placeholder_pointers.push_back(this); } break; @@ -1145,8 +1146,7 @@ Type::get_backend_placeholder(Gogo* gogo) { Location loc = Linemap::unknown_location(); bt = gogo->backend()->placeholder_pointer_type("", loc, false); - Pointer_type* pt = this->convert(); - Type::placeholder_pointers.push_back(pt); + Type::placeholder_pointers.push_back(this); } break; @@ -5474,10 +5474,11 @@ Pointer_type::do_import(Import* imp) Type::Pointer_type_table Type::pointer_types; -// A list of placeholder pointer types. We keep this so we can ensure -// they are finalized. +// A list of placeholder pointer types; items on this list will be either be +// Pointer_type or Function_type. We keep this so we can ensure they are +// finalized. -std::vector Type::placeholder_pointers; +std::vector Type::placeholder_pointers; // Make a pointer type. @@ -5513,11 +5514,11 @@ Type::finish_pointer_types(Gogo* gogo) // placeholder pointer types as we finalized existing ones. for (size_t i = 0; i < Type::placeholder_pointers.size(); i++) { - Pointer_type* pt = Type::placeholder_pointers[i]; - Type_btypes::iterator tbti = Type::type_btypes.find(pt); + Type* typ = Type::placeholder_pointers[i]; + Type_btypes::iterator tbti = Type::type_btypes.find(typ); if (tbti != Type::type_btypes.end() && tbti->second.is_placeholder) { - pt->finish_backend(gogo, tbti->second.btype); + typ->finish_backend(gogo, tbti->second.btype); tbti->second.is_placeholder = false; } } diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h index 2b51df5..0978701 100644 --- a/gcc/go/gofrontend/types.h +++ b/gcc/go/gofrontend/types.h @@ -1409,7 +1409,7 @@ class Type static Pointer_type_table pointer_types; // List of placeholder pointer types. - static std::vector placeholder_pointers; + static std::vector placeholder_pointers; // The type classification. Type_classification classification_; -- cgit v1.1 From 7a56096cc43d969a180f965a0e6bb07941978fea Mon Sep 17 00:00:00 2001 From: Thomas Koenig Date: Mon, 26 Aug 2019 20:05:32 +0000 Subject: re PR fortran/91390 (treatment of extra parameter in a subroutine call) 2019-08-26 Thomas Koenig PR fortran/91390 PR fortran/91473 * frontend-passes.c (gfc_check_externals): Make gfc_errors_to_warnings conditional on -fallow-argument-mismatch. * invoke.texi: Document -fallow-argument-mismatch. * lang.opt: Add -fallow-argument-mismatch. 2019-08-26 Thomas Koenig PR fortran/91390 PR fortran/91473 * gfortran.dg/used_before_typed_4.f90: Change warning to error. * gfortran.dg/argument_checking_20.f90: New test. From-SVN: r274937 --- gcc/fortran/ChangeLog | 9 +++++++++ gcc/fortran/frontend-passes.c | 4 ++-- gcc/fortran/invoke.texi | 16 ++++++++++++---- gcc/fortran/lang.opt | 4 ++++ gcc/testsuite/ChangeLog | 7 +++++++ gcc/testsuite/gfortran.dg/used_before_typed_4.f90 | 2 +- 6 files changed, 35 insertions(+), 7 deletions(-) (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index abdf9e6..643a7d0 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,12 @@ +2019-08-26 Thomas Koenig + + PR fortran/91390 + PR fortran/91473 + * frontend-passes.c (gfc_check_externals): Make + gfc_errors_to_warnings conditional on -fallow-argument-mismatch. + * invoke.texi: Document -fallow-argument-mismatch. + * lang.opt: Add -fallow-argument-mismatch. + 2019-08-24 Thomas Koenig PR fortran/91390 diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c index fa41667..86debab 100644 --- a/gcc/fortran/frontend-passes.c +++ b/gcc/fortran/frontend-passes.c @@ -5477,9 +5477,9 @@ gfc_check_externals (gfc_namespace *ns) gfc_clear_error (); - /* Turn errors into warnings if -std=legacy is given by the user. */ + /* Turn errors into warnings if the user indicated this. */ - if (!pedantic && !(gfc_option.warn_std & GFC_STD_LEGACY)) + if (!pedantic && flag_allow_argument_mismatch) gfc_errors_to_warnings (true); gfc_code_walker (&ns->code, check_externals_code, check_externals_expr, NULL); diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi index 1039c608..0b8abc5 100644 --- a/gcc/fortran/invoke.texi +++ b/gcc/fortran/invoke.texi @@ -116,12 +116,12 @@ by type. Explanations are in the following sections. @table @emph @item Fortran Language Options @xref{Fortran Dialect Options,,Options controlling Fortran dialect}. -@gccoptlist{-fall-intrinsics -fallow-invalid-boz -fbackslash -fcray-pointer @gol --fd-lines-as-code -fd-lines-as-comments -fdec -fdec-structure @gol --fdec-intrinsic-ints -fdec-static -fdec-math -fdec-include @gol +@gccoptlist{-fall-intrinsics -fallow-argument-mismatch -fallow-invalid-boz @gol +-fbackslash -fcray-pointer -fd-lines-as-code -fd-lines-as-comments -fdec @gol +-fdec-structure-fdec-intrinsic-ints -fdec-static -fdec-math -fdec-include @gol -fdec-format-defaults -fdec-blank-format-item -fdefault-double-8 @gol -fdefault-integer-8 -fdefault-real-8 -fdefault-real-10 -fdefault-real-16 @gol --fdollar-ok @gol -ffixed-line-length-@var{n} -ffixed-line-length-none @gol +-fdollar-ok -ffixed-line-length-@var{n} -ffixed-line-length-none @gol -fpad-source -ffree-form -ffree-line-length-@var{n} -ffree-line-length-none @gol -fimplicit-none -finteger-4-integer-8 -fmax-identifier-length @gol -fmodule-private -ffixed-form -fno-range-check -fopenacc -fopenmp @gol @@ -232,6 +232,14 @@ available with @command{gfortran}. As a consequence, @option{-Wintrinsics-std} will be ignored and no user-defined procedure with the same name as any intrinsic will be called except when it is explicitly declared @code{EXTERNAL}. +@item -fallow-argument-mismatch +@opindex @code{fallow-argument-mismatch} +Some code contains calls to external procedures whith mismatches +between the calls and the procedure definition, or with mismatches +between different calls. Such code is non-conforming, and will usually +be flagged with an error. This options degrades the error to a +warning. This option is implied by @option{-std=legacy}. + @item -fallow-invalid-boz @opindex @code{allow-invalid-boz} A BOZ literal constant can occur in a limited number of context in diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt index 85113a7..1b3364b 100644 --- a/gcc/fortran/lang.opt +++ b/gcc/fortran/lang.opt @@ -365,6 +365,10 @@ d Fortran Joined ; Documented in common.opt +fallow-argument-mismatch +Fortran Var(flag_allow_argument_mismatch) LangEnabledBy(Fortran,std=legacy) +Accept argument mismatches in procedure calls. + faggressive-function-elimination Fortran Var(flag_aggressive_function_elimination) Eliminate multiple function invocations also for impure functions. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9bdc2f9..5f60dc0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2019-08-26 Thomas Koenig + + PR fortran/91390 + PR fortran/91473 + * gfortran.dg/used_before_typed_4.f90: Change warning to error. + * gfortran.dg/argument_checking_20.f90: New test. + 2019-08-26 Marek Polacek PR c++/91545 - ICE in constexpr store evaluation. diff --git a/gcc/testsuite/gfortran.dg/used_before_typed_4.f90 b/gcc/testsuite/gfortran.dg/used_before_typed_4.f90 index ff8a1fc..0604cfe 100644 --- a/gcc/testsuite/gfortran.dg/used_before_typed_4.f90 +++ b/gcc/testsuite/gfortran.dg/used_before_typed_4.f90 @@ -22,5 +22,5 @@ END SUBROUTINE test PROGRAM main IMPLICIT NONE INTEGER :: arr1(42), arr2(42) - CALL test (3, arr1, 2, arr2) ! { dg-warning "Type mismatch in argument" } + CALL test (3, arr1, 2, arr2) ! { dg-error "Type mismatch in argument" } END PROGRAM main -- cgit v1.1 From e80f40684f4f214923da3a4aea7b31063649635e Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Tue, 27 Aug 2019 00:16:37 +0000 Subject: Daily bump. From-SVN: r274944 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 07f9b34..3f31c4a 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20190826 +20190827 -- cgit v1.1 From 72bb85f8d180725a84b17fb9e6a7a66d4d649af3 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Tue, 27 Aug 2019 09:39:34 +0200 Subject: Fix new clang warnings. 2019-08-27 Martin Liska * cgraph.c (cgraph_node::remove): Remove dead assignment before loop. * config/i386/i386-features.c (scalar_chain::emit_conversion_insns): Enclose in anonymous namespace. * config/i386/x86-tune-costs.h (struct processor_costs): Wrap hard_register initialization in braces. * tree-vrp.h (value_range_base::supports_type_p): Return false for function with boolean return type. From-SVN: r274945 --- gcc/ChangeLog | 11 +++++++++ gcc/cgraph.c | 2 +- gcc/config/i386/i386-features.c | 4 ++++ gcc/config/i386/x86-tune-costs.h | 48 ++++++++++++++++++++++++++++++++++++++++ gcc/tree-vrp.h | 2 +- 5 files changed, 65 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3772757..856ce68 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2019-08-27 Martin Liska + + * cgraph.c (cgraph_node::remove): Remove dead assignment before + loop. + * config/i386/i386-features.c (scalar_chain::emit_conversion_insns): + Enclose in anonymous namespace. + * config/i386/x86-tune-costs.h (struct processor_costs): Wrap + hard_register initialization in braces. + * tree-vrp.h (value_range_base::supports_type_p): Return false + for function with boolean return type. + 2019-08-26 Uroš Bizjak * config/i386/i386.c (emit_i387_cw_initialization) diff --git a/gcc/cgraph.c b/gcc/cgraph.c index ea8ab38..843891e 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -1783,7 +1783,7 @@ cgraph_node::remove (void) */ force_output = false; forced_by_abi = false; - cgraph_node *next = nested; + cgraph_node *next; for (cgraph_node *n = nested; n; n = next) { next = n->next_nested; diff --git a/gcc/config/i386/i386-features.c b/gcc/config/i386/i386-features.c index 8f12bd2..5891584 100644 --- a/gcc/config/i386/i386-features.c +++ b/gcc/config/i386/i386-features.c @@ -274,6 +274,8 @@ xlogue_layout::get_stub_rtx (enum xlogue_stub stub) unsigned scalar_chain::max_id = 0; +namespace { + /* Initialize new chain. */ scalar_chain::scalar_chain (enum machine_mode smode_, enum machine_mode vmode_) @@ -622,6 +624,8 @@ scalar_chain::emit_conversion_insns (rtx insns, rtx_insn *after) emit_insn_after (insns, BB_HEAD (new_bb)); } +} // anon namespace + /* Generate the canonical SET_SRC to move GPR to a VMODE vector register, zeroing the upper parts. */ diff --git a/gcc/config/i386/x86-tune-costs.h b/gcc/config/i386/x86-tune-costs.h index ad9ea4b..3381b8b 100644 --- a/gcc/config/i386/x86-tune-costs.h +++ b/gcc/config/i386/x86-tune-costs.h @@ -36,6 +36,7 @@ static stringop_algs ix86_size_memset[2] = { const struct processor_costs ix86_size_cost = {/* costs for tuning for size */ + { /* Start of register allocator costs. integer->integer move cost is 2. */ 2, /* cost for loading QImode using movzbl */ {2, 2, 2}, /* cost of loading integer registers @@ -59,6 +60,7 @@ struct processor_costs ix86_size_cost = {/* costs for tuning for size */ in 32,64,128,256 and 512-bit */ 3, 3, /* SSE->integer and integer->SSE moves */ /* End of register allocator costs. */ + }, COSTS_N_BYTES (2), /* cost of an add instruction */ COSTS_N_BYTES (3), /* cost of a lea instruction */ @@ -138,6 +140,7 @@ static stringop_algs i386_memset[2] = { static const struct processor_costs i386_cost = { /* 386 specific costs */ + { /* Start of register allocator costs. integer->integer move cost is 2. */ 4, /* cost for loading QImode using movzbl */ {2, 4, 2}, /* cost of loading integer registers @@ -161,6 +164,7 @@ struct processor_costs i386_cost = { /* 386 specific costs */ in 32,64,128,256 and 512-bit */ 3, 3, /* SSE->integer and integer->SSE moves */ /* End of register allocator costs. */ + }, COSTS_N_INSNS (1), /* cost of an add instruction */ COSTS_N_INSNS (1), /* cost of a lea instruction */ @@ -237,6 +241,7 @@ static stringop_algs i486_memset[2] = { static const struct processor_costs i486_cost = { /* 486 specific costs */ + { /* Start of register allocator costs. integer->integer move cost is 2. */ 4, /* cost for loading QImode using movzbl */ {2, 4, 2}, /* cost of loading integer registers @@ -260,6 +265,7 @@ struct processor_costs i486_cost = { /* 486 specific costs */ in 32,64,128,256 and 512-bit */ 3, 3, /* SSE->integer and integer->SSE moves */ /* End of register allocator costs. */ + }, COSTS_N_INSNS (1), /* cost of an add instruction */ COSTS_N_INSNS (1), /* cost of a lea instruction */ @@ -338,6 +344,7 @@ static stringop_algs pentium_memset[2] = { static const struct processor_costs pentium_cost = { + { /* Start of register allocator costs. integer->integer move cost is 2. */ 6, /* cost for loading QImode using movzbl */ {2, 4, 2}, /* cost of loading integer registers @@ -361,6 +368,7 @@ struct processor_costs pentium_cost = { in 32,64,128,256 and 512-bit */ 3, 3, /* SSE->integer and integer->SSE moves */ /* End of register allocator costs. */ + }, COSTS_N_INSNS (1), /* cost of an add instruction */ COSTS_N_INSNS (1), /* cost of a lea instruction */ @@ -430,6 +438,7 @@ struct processor_costs pentium_cost = { static const struct processor_costs lakemont_cost = { + { /* Start of register allocator costs. integer->integer move cost is 2. */ 6, /* cost for loading QImode using movzbl */ {2, 4, 2}, /* cost of loading integer registers @@ -453,6 +462,7 @@ struct processor_costs lakemont_cost = { in 32,64,128,256 and 512-bit */ 3, 3, /* SSE->integer and integer->SSE moves */ /* End of register allocator costs. */ + }, COSTS_N_INSNS (1), /* cost of an add instruction */ COSTS_N_INSNS (1) + 1, /* cost of a lea instruction */ @@ -537,6 +547,7 @@ static stringop_algs pentiumpro_memset[2] = { DUMMY_STRINGOP_ALGS}; static const struct processor_costs pentiumpro_cost = { + { /* Start of register allocator costs. integer->integer move cost is 2. */ 2, /* cost for loading QImode using movzbl */ {4, 4, 4}, /* cost of loading integer registers @@ -560,6 +571,7 @@ struct processor_costs pentiumpro_cost = { in 32,64,128,256 and 512-bit */ 3, 3, /* SSE->integer and integer->SSE moves */ /* End of register allocator costs. */ + }, COSTS_N_INSNS (1), /* cost of an add instruction */ COSTS_N_INSNS (1), /* cost of a lea instruction */ @@ -635,6 +647,7 @@ static stringop_algs geode_memset[2] = { DUMMY_STRINGOP_ALGS}; static const struct processor_costs geode_cost = { + { /* Start of register allocator costs. integer->integer move cost is 2. */ 2, /* cost for loading QImode using movzbl */ {2, 2, 2}, /* cost of loading integer registers @@ -658,6 +671,7 @@ struct processor_costs geode_cost = { in 32,64,128,256 and 512-bit */ 6, 6, /* SSE->integer and integer->SSE moves */ /* End of register allocator costs. */ + }, COSTS_N_INSNS (1), /* cost of an add instruction */ COSTS_N_INSNS (1), /* cost of a lea instruction */ @@ -733,6 +747,7 @@ static stringop_algs k6_memset[2] = { DUMMY_STRINGOP_ALGS}; static const struct processor_costs k6_cost = { + { /* Start of register allocator costs. integer->integer move cost is 2. */ 3, /* cost for loading QImode using movzbl */ {4, 5, 4}, /* cost of loading integer registers @@ -756,6 +771,7 @@ struct processor_costs k6_cost = { in 32,64,128,256 and 512-bit */ 6, 6, /* SSE->integer and integer->SSE moves */ /* End of register allocator costs. */ + }, COSTS_N_INSNS (1), /* cost of an add instruction */ COSTS_N_INSNS (2), /* cost of a lea instruction */ @@ -837,6 +853,7 @@ static stringop_algs athlon_memset[2] = { DUMMY_STRINGOP_ALGS}; static const struct processor_costs athlon_cost = { + { /* Start of register allocator costs. integer->integer move cost is 2. */ 4, /* cost for loading QImode using movzbl */ {3, 4, 3}, /* cost of loading integer registers @@ -860,6 +877,7 @@ struct processor_costs athlon_cost = { in 32,64,128,256 and 512-bit */ 5, 5, /* SSE->integer and integer->SSE moves */ /* End of register allocator costs. */ + }, COSTS_N_INSNS (1), /* cost of an add instruction */ COSTS_N_INSNS (2), /* cost of a lea instruction */ @@ -943,6 +961,7 @@ static stringop_algs k8_memset[2] = { {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}}; static const struct processor_costs k8_cost = { + { /* Start of register allocator costs. integer->integer move cost is 2. */ 4, /* cost for loading QImode using movzbl */ {3, 4, 3}, /* cost of loading integer registers @@ -966,6 +985,7 @@ struct processor_costs k8_cost = { in 32,64,128,256 and 512-bit */ 5, 5, /* SSE->integer and integer->SSE moves */ /* End of register allocator costs. */ + }, COSTS_N_INSNS (1), /* cost of an add instruction */ COSTS_N_INSNS (2), /* cost of a lea instruction */ @@ -1053,6 +1073,7 @@ static stringop_algs amdfam10_memset[2] = { {libcall, {{48, unrolled_loop, false}, {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}}; struct processor_costs amdfam10_cost = { + { /* Start of register allocator costs. integer->integer move cost is 2. */ 4, /* cost for loading QImode using movzbl */ {3, 4, 3}, /* cost of loading integer registers @@ -1085,6 +1106,7 @@ struct processor_costs amdfam10_cost = { MOVD reg32, xmmreg Double FADD 3 1/1 1/1 */ /* End of register allocator costs. */ + }, COSTS_N_INSNS (1), /* cost of an add instruction */ COSTS_N_INSNS (2), /* cost of a lea instruction */ @@ -1173,6 +1195,7 @@ static stringop_algs bdver_memset[2] = { {-1, libcall, false}}}}; const struct processor_costs bdver_cost = { + { /* Start of register allocator costs. integer->integer move cost is 2. */ 8, /* cost for loading QImode using movzbl */ {8, 8, 8}, /* cost of loading integer registers @@ -1196,6 +1219,7 @@ const struct processor_costs bdver_cost = { in 32,64,128,256 and 512-bit */ 16, 20, /* SSE->integer and integer->SSE moves */ /* End of register allocator costs. */ + }, COSTS_N_INSNS (1), /* cost of an add instruction */ COSTS_N_INSNS (1), /* cost of a lea instruction */ @@ -1285,6 +1309,7 @@ static stringop_algs znver1_memset[2] = { {libcall, {{48, unrolled_loop, false}, {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}}; struct processor_costs znver1_cost = { + { /* Start of register allocator costs. integer->integer move cost is 2. */ /* reg-reg moves are done by renaming and thus they are even cheaper than @@ -1315,6 +1340,7 @@ struct processor_costs znver1_cost = { in 32,64,128,256 and 512-bit. */ 6, 6, /* SSE->integer and integer->SSE moves. */ /* End of register allocator costs. */ + }, COSTS_N_INSNS (1), /* cost of an add instruction. */ COSTS_N_INSNS (1), /* cost of a lea instruction. */ @@ -1420,6 +1446,7 @@ static stringop_algs znver2_memset[2] = { {-1, libcall, false}}}}; struct processor_costs znver2_cost = { + { /* Start of register allocator costs. integer->integer move cost is 2. */ /* reg-reg moves are done by renaming and thus they are even cheaper than @@ -1452,6 +1479,7 @@ struct processor_costs znver2_cost = { 6, 6, /* SSE->integer and integer->SSE moves. */ /* End of register allocator costs. */ + }, COSTS_N_INSNS (1), /* cost of an add instruction. */ COSTS_N_INSNS (1), /* cost of a lea instruction. */ @@ -1560,6 +1588,7 @@ static stringop_algs skylake_memset[2] = { static const struct processor_costs skylake_cost = { + { /* Start of register allocator costs. integer->integer move cost is 2. */ 6, /* cost for loading QImode using movzbl */ {4, 4, 4}, /* cost of loading integer registers @@ -1583,6 +1612,7 @@ struct processor_costs skylake_cost = { in 32,64,128,256 and 512-bit */ 2, 2, /* SSE->integer and integer->SSE moves */ /* End of register allocator costs. */ + }, COSTS_N_INSNS (1), /* cost of an add instruction */ COSTS_N_INSNS (1)+1, /* cost of a lea instruction */ @@ -1665,6 +1695,7 @@ static stringop_algs btver1_memset[2] = { {libcall, {{48, unrolled_loop, false}, {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}}; const struct processor_costs btver1_cost = { + { /* Start of register allocator costs. integer->integer move cost is 2. */ 8, /* cost for loading QImode using movzbl */ {6, 8, 6}, /* cost of loading integer registers @@ -1688,6 +1719,7 @@ const struct processor_costs btver1_cost = { in 32,64,128,256 and 512-bit */ 14, 14, /* SSE->integer and integer->SSE moves */ /* End of register allocator costs. */ + }, COSTS_N_INSNS (1), /* cost of an add instruction */ COSTS_N_INSNS (2), /* cost of a lea instruction */ @@ -1766,6 +1798,7 @@ static stringop_algs btver2_memset[2] = { {libcall, {{48, unrolled_loop, false}, {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}}; const struct processor_costs btver2_cost = { + { /* Start of register allocator costs. integer->integer move cost is 2. */ 8, /* cost for loading QImode using movzbl */ {8, 8, 6}, /* cost of loading integer registers @@ -1789,6 +1822,7 @@ const struct processor_costs btver2_cost = { in 32,64,128,256 and 512-bit */ 14, 14, /* SSE->integer and integer->SSE moves */ /* End of register allocator costs. */ + }, COSTS_N_INSNS (1), /* cost of an add instruction */ COSTS_N_INSNS (2), /* cost of a lea instruction */ @@ -1866,6 +1900,7 @@ static stringop_algs pentium4_memset[2] = { static const struct processor_costs pentium4_cost = { + { /* Start of register allocator costs. integer->integer move cost is 2. */ 5, /* cost for loading QImode using movzbl */ {4, 5, 4}, /* cost of loading integer registers @@ -1889,6 +1924,7 @@ struct processor_costs pentium4_cost = { in 32,64,128,256 and 512-bit */ 20, 12, /* SSE->integer and integer->SSE moves */ /* End of register allocator costs. */ + }, COSTS_N_INSNS (1), /* cost of an add instruction */ COSTS_N_INSNS (3), /* cost of a lea instruction */ @@ -1969,6 +2005,7 @@ static stringop_algs nocona_memset[2] = { static const struct processor_costs nocona_cost = { + { /* Start of register allocator costs. integer->integer move cost is 2. */ 4, /* cost for loading QImode using movzbl */ {4, 4, 4}, /* cost of loading integer registers @@ -1992,6 +2029,7 @@ struct processor_costs nocona_cost = { in 32,64,128,256 and 512-bit */ 20, 12, /* SSE->integer and integer->SSE moves */ /* End of register allocator costs. */ + }, COSTS_N_INSNS (1), /* cost of an add instruction */ COSTS_N_INSNS (1), /* cost of a lea instruction */ @@ -2070,6 +2108,7 @@ static stringop_algs atom_memset[2] = { {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}}; static const struct processor_costs atom_cost = { + { /* Start of register allocator costs. integer->integer move cost is 2. */ 6, /* cost for loading QImode using movzbl */ {6, 6, 6}, /* cost of loading integer registers @@ -2093,6 +2132,7 @@ struct processor_costs atom_cost = { in 32,64,128,256 and 512-bit */ 8, 6, /* SSE->integer and integer->SSE moves */ /* End of register allocator costs. */ + }, COSTS_N_INSNS (1), /* cost of an add instruction */ COSTS_N_INSNS (1) + 1, /* cost of a lea instruction */ @@ -2171,6 +2211,7 @@ static stringop_algs slm_memset[2] = { {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}}; static const struct processor_costs slm_cost = { + { /* Start of register allocator costs. integer->integer move cost is 2. */ 8, /* cost for loading QImode using movzbl */ {8, 8, 8}, /* cost of loading integer registers @@ -2194,6 +2235,7 @@ struct processor_costs slm_cost = { in 32,64,128,256 and 512-bit */ 8, 6, /* SSE->integer and integer->SSE moves */ /* End of register allocator costs. */ + }, COSTS_N_INSNS (1), /* cost of an add instruction */ COSTS_N_INSNS (1) + 1, /* cost of a lea instruction */ @@ -2272,6 +2314,7 @@ static stringop_algs intel_memset[2] = { {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}}; static const struct processor_costs intel_cost = { + { /* Start of register allocator costs. integer->integer move cost is 2. */ 6, /* cost for loading QImode using movzbl */ {4, 4, 4}, /* cost of loading integer registers @@ -2295,6 +2338,7 @@ struct processor_costs intel_cost = { in 32,64,128,256 and 512-bit */ 4, 4, /* SSE->integer and integer->SSE moves */ /* End of register allocator costs. */ + }, COSTS_N_INSNS (1), /* cost of an add instruction */ COSTS_N_INSNS (1) + 1, /* cost of a lea instruction */ @@ -2377,6 +2421,7 @@ static stringop_algs generic_memset[2] = { {-1, libcall, false}}}}; static const struct processor_costs generic_cost = { + { /* Start of register allocator costs. integer->integer move cost is 2. */ 6, /* cost for loading QImode using movzbl */ {6, 6, 6}, /* cost of loading integer registers @@ -2400,6 +2445,7 @@ struct processor_costs generic_cost = { in 32,64,128,256 and 512-bit */ 6, 6, /* SSE->integer and integer->SSE moves */ /* End of register allocator costs. */ + }, COSTS_N_INSNS (1), /* cost of an add instruction */ /* Setting cost to 2 makes our current implementation of synth_mult result in @@ -2487,6 +2533,7 @@ static stringop_algs core_memset[2] = { static const struct processor_costs core_cost = { + { /* Start of register allocator costs. integer->integer move cost is 2. */ 6, /* cost for loading QImode using movzbl */ {4, 4, 4}, /* cost of loading integer registers @@ -2510,6 +2557,7 @@ struct processor_costs core_cost = { in 32,64,128,256 and 512-bit */ 2, 2, /* SSE->integer and integer->SSE moves */ /* End of register allocator costs. */ + }, COSTS_N_INSNS (1), /* cost of an add instruction */ /* On all chips taken into consideration lea is 2 cycles and more. With diff --git a/gcc/tree-vrp.h b/gcc/tree-vrp.h index c879a8c..cf236fa 100644 --- a/gcc/tree-vrp.h +++ b/gcc/tree-vrp.h @@ -265,7 +265,7 @@ value_range_base::supports_type_p (tree type) { if (type && (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))) return type; - return NULL; + return false; } extern void register_edge_assert_for (tree, edge, enum tree_code, -- cgit v1.1 From a7e73b4158f528600ef97aca29201ddc92b3439f Mon Sep 17 00:00:00 2001 From: Richard Earnshaw Date: Tue, 27 Aug 2019 10:05:51 +0000 Subject: [arm/aarch64] Add comments warning that stack-protector initializer insns shouldn't be split Following the publication of https://kb.cert.org/vuls/id/129209/ I've been having a look at GCC's implementation for Arm and AArch64. I haven't identified any issues yet, but it's a bit early to be completely sure. One observation, however, is that the instruction sequence that initializes the stack canary might be vulnerable to producing a reusable value if it were ever split early. I don't think we ever would, because the memory locations involved with the stack protector are all marked volatile to ensure that the values are only loaded at the point in time when the test is intended to happen, and that also has the effect of making it unlikely that the value would be reused without reloading. Nevertheless, defence in depth is probably warranted here. So this patch just adds some comments warning that the patterns should not be split. * config/arm/arm.md (stack_protect_set_insn): Add security-related comment. * config/aarch64/aarch64.md (stack_protect_set_): Likewise. From-SVN: r274946 --- gcc/ChangeLog | 6 ++++++ gcc/config/aarch64/aarch64.md | 4 +++- gcc/config/arm/arm.md | 6 ++++-- 3 files changed, 13 insertions(+), 3 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 856ce68..b7c0fbe 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-08-27 Richard Earnshaw + + * config/arm/arm.md (stack_protect_set_insn): Add security-related + comment. + * config/aarch64/aarch64.md (stack_protect_set_): Likewise. + 2019-08-27 Martin Liska * cgraph.c (cgraph_node::remove): Remove dead assignment before diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 9a07f63..88e04df 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -7016,13 +7016,15 @@ } [(set_attr "type" "mrs")]) +;; DO NOT SPLIT THIS PATTERN. It is important for security reasons that the +;; canary value does not live beyond the life of this sequence. (define_insn "stack_protect_set_" [(set (match_operand:PTR 0 "memory_operand" "=m") (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")] UNSPEC_SP_SET)) (set (match_scratch:PTR 2 "=&r") (const_int 0))] "" - "ldr\\t%2, %1\;str\\t%2, %0\;mov\t%2,0" + "ldr\\t%2, %1\;str\\t%2, %0\;mov\t%2, 0" [(set_attr "length" "12") (set_attr "type" "multiple")]) diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index ed49c4b..f138d31 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -8208,6 +8208,8 @@ [(set_attr "arch" "t1,32")] ) +;; DO NOT SPLIT THIS INSN. It's important for security reasons that the +;; canary value does not live beyond the life of this sequence. (define_insn "*stack_protect_set_insn" [(set (match_operand:SI 0 "memory_operand" "=m,m") (unspec:SI [(mem:SI (match_operand:SI 1 "register_operand" "+&l,&r"))] @@ -8215,8 +8217,8 @@ (clobber (match_dup 1))] "" "@ - ldr\\t%1, [%1]\;str\\t%1, %0\;movs\t%1,#0 - ldr\\t%1, [%1]\;str\\t%1, %0\;mov\t%1,#0" + ldr\\t%1, [%1]\;str\\t%1, %0\;movs\t%1, #0 + ldr\\t%1, [%1]\;str\\t%1, %0\;mov\t%1, #0" [(set_attr "length" "8,12") (set_attr "conds" "clob,nocond") (set_attr "type" "multiple") -- cgit v1.1 From 6c14d008122fcee4157be79a60f8d6685869ad19 Mon Sep 17 00:00:00 2001 From: Robin Dapp Date: Tue, 27 Aug 2019 12:08:58 +0000 Subject: re PR testsuite/91549 (gcc.dg/wrapped-binop-simplify.c fails starting with r274925) PR testsuite/91549 gcc/testsuite/ChangeLog: * gcc.dg/wrapped-binop-simplify.c: Test only on x86, s390 with lp64. From-SVN: r274951 --- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/wrapped-binop-simplify.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5f60dc0..d0a30f9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-08-27 Robin Dapp + + PR testsuite/91549 + * gcc.dg/wrapped-binop-simplify.c: Test only on x86, s390 with lp64. + 2019-08-26 Thomas Koenig PR fortran/91390 diff --git a/gcc/testsuite/gcc.dg/wrapped-binop-simplify.c b/gcc/testsuite/gcc.dg/wrapped-binop-simplify.c index 44d85c0..a5d953b 100644 --- a/gcc/testsuite/gcc.dg/wrapped-binop-simplify.c +++ b/gcc/testsuite/gcc.dg/wrapped-binop-simplify.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target { { i?86-*-* x86_64-*-* s390*-*-* } && lp64 } } } */ /* { dg-options "-O2 -fdump-tree-vrp2-details" } */ /* { dg-final { scan-tree-dump-times "gimple_simplified to" 4 "vrp2" } } */ -- cgit v1.1 From 6a07489267e55084c3d5e88b4e9591be25bf2bf6 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 27 Aug 2019 14:37:30 +0200 Subject: re PR c++/91415 (Invalid warning for C++17 sequencing of shift operator E1<= cxx17 mode handle it like COMPOUND_EXPR rather than normal expression. * g++.dg/warn/sequence-pt-4.C: New test. From-SVN: r274952 --- gcc/c-family/ChangeLog | 7 +++++++ gcc/c-family/c-common.c | 13 ++++++++++++- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/warn/sequence-pt-4.C | 21 +++++++++++++++++++++ 4 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/warn/sequence-pt-4.C (limited to 'gcc') diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 2ab1c98..0376a7b 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,10 @@ +2019-08-27 Jakub Jelinek + + PR c++/91415 + * c-common.c (verify_tree): For LSHIFT_EXPR, RSHIFT_EXPR, + COMPONENT_REF and ARRAY_REF in cxx_dialect >= cxx17 mode handle it + like COMPOUND_EXPR rather than normal expression. + 2019-08-23 Iain Sandoe PR pch/61250 diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index d516dea..61ee754 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -1889,6 +1889,7 @@ verify_tree (tree x, struct tlist **pbefore_sp, struct tlist **pno_sp, case COMPOUND_EXPR: case TRUTH_ANDIF_EXPR: case TRUTH_ORIF_EXPR: + sequenced_binary: tmp_before = tmp_nosp = tmp_list2 = tmp_list3 = 0; verify_tree (TREE_OPERAND (x, 0), &tmp_before, &tmp_nosp, NULL_TREE); warn_for_collisions (tmp_nosp); @@ -2031,8 +2032,18 @@ verify_tree (tree x, struct tlist **pbefore_sp, struct tlist **pno_sp, x = TREE_OPERAND (x, 0); goto restart; } - gcc_fallthrough (); + goto do_default; + + case LSHIFT_EXPR: + case RSHIFT_EXPR: + case COMPONENT_REF: + case ARRAY_REF: + if (cxx_dialect >= cxx17) + goto sequenced_binary; + goto do_default; + default: + do_default: /* For other expressions, simply recurse on their operands. Manual tail recursion for unary expressions. Other non-expressions need not be processed. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d0a30f9..64970b2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-08-27 Jakub Jelinek + + PR c++/91415 + * g++.dg/warn/sequence-pt-4.C: New test. + 2019-08-27 Robin Dapp PR testsuite/91549 diff --git a/gcc/testsuite/g++.dg/warn/sequence-pt-4.C b/gcc/testsuite/g++.dg/warn/sequence-pt-4.C new file mode 100644 index 0000000..e8b1e2c --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/sequence-pt-4.C @@ -0,0 +1,21 @@ +/* More sequence point warning tests */ +/* { dg-do compile } */ +/* { dg-options "-Wsequence-point" } */ + +struct S { int a[10]; }; +void bar (int, int, int, int, int, int, int, int); + +int +foo (int i, int x[10][10], int y[10], struct S z[10], struct S *w[10]) +{ + int b = x[i++][i++]; /* { dg-warning "undefined" "sequence point warning" { target c++14_down } } */ + int c = i++ << i++; /* { dg-warning "undefined" "sequence point warning" { target c++14_down } } */ + int d = i++ >> i++; /* { dg-warning "undefined" "sequence point warning" { target c++14_down } } */ + int e = i++ && i++; + int f = i++ ? i++ : i++; + int g = (i++, i++); + int h = z[i++].a[i++]; /* { dg-warning "undefined" "sequence point warning" { target c++14_down } } */ + int j = w[i++]->a[i++]; /* { dg-warning "undefined" "sequence point warning" { target c++14_down } } */ + bar (b, c, d, e, f,g, h, j); + return i; +} -- cgit v1.1 From b5a6addb5b60ff6232d1e11367b44f969d2a3e8f Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 27 Aug 2019 12:46:07 +0000 Subject: 2019-08-27 Richard Biener * config/i386/i386-features.h (general_scalar_chain::~general_scalar_chain): Add. (general_scalar_chain::insns_conv): New bitmap. (general_scalar_chain::n_sse_to_integer): New. (general_scalar_chain::n_integer_to_sse): Likewise. (general_scalar_chain::make_vector_copies): Adjust signature. * config/i386/i386-features.c (general_scalar_chain::general_scalar_chain): Outline, initialize new members. (general_scalar_chain::~general_scalar_chain): New. (general_scalar_chain::mark_dual_mode_def): Record insns we need to insert conversions at and count them. (general_scalar_chain::compute_convert_gain): Account for conversion instructions at chain boundary. (general_scalar_chain::make_vector_copies): Generate a single copy for a def by a specific insn. (general_scalar_chain::convert_registers): First populate defs_map, then make copies at out-of chain insns. From-SVN: r274953 --- gcc/ChangeLog | 21 +++++ gcc/config/i386/i386-features.c | 172 +++++++++++++++++++++------------------- gcc/config/i386/i386-features.h | 9 ++- 3 files changed, 119 insertions(+), 83 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b7c0fbe..65f9db9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +2019-08-27 Richard Biener + + * config/i386/i386-features.h + (general_scalar_chain::~general_scalar_chain): Add. + (general_scalar_chain::insns_conv): New bitmap. + (general_scalar_chain::n_sse_to_integer): New. + (general_scalar_chain::n_integer_to_sse): Likewise. + (general_scalar_chain::make_vector_copies): Adjust signature. + * config/i386/i386-features.c + (general_scalar_chain::general_scalar_chain): Outline, + initialize new members. + (general_scalar_chain::~general_scalar_chain): New. + (general_scalar_chain::mark_dual_mode_def): Record insns + we need to insert conversions at and count them. + (general_scalar_chain::compute_convert_gain): Account + for conversion instructions at chain boundary. + (general_scalar_chain::make_vector_copies): Generate a single + copy for a def by a specific insn. + (general_scalar_chain::convert_registers): First populate + defs_map, then make copies at out-of chain insns. + 2019-08-27 Richard Earnshaw * config/arm/arm.md (stack_protect_set_insn): Add security-related diff --git a/gcc/config/i386/i386-features.c b/gcc/config/i386/i386-features.c index 5891584..9505b4a 100644 --- a/gcc/config/i386/i386-features.c +++ b/gcc/config/i386/i386-features.c @@ -320,6 +320,20 @@ scalar_chain::add_to_queue (unsigned insn_uid) bitmap_set_bit (queue, insn_uid); } +general_scalar_chain::general_scalar_chain (enum machine_mode smode_, + enum machine_mode vmode_) + : scalar_chain (smode_, vmode_) +{ + insns_conv = BITMAP_ALLOC (NULL); + n_sse_to_integer = 0; + n_integer_to_sse = 0; +} + +general_scalar_chain::~general_scalar_chain () +{ + BITMAP_FREE (insns_conv); +} + /* For DImode conversion, mark register defined by DEF as requiring conversion. */ @@ -328,15 +342,27 @@ general_scalar_chain::mark_dual_mode_def (df_ref def) { gcc_assert (DF_REF_REG_DEF_P (def)); - if (bitmap_bit_p (defs_conv, DF_REF_REGNO (def))) - return; - + /* Record the def/insn pair so we can later efficiently iterate over + the defs to convert on insns not in the chain. */ + bool reg_new = bitmap_set_bit (defs_conv, DF_REF_REGNO (def)); + if (!bitmap_bit_p (insns, DF_REF_INSN_UID (def))) + { + if (!bitmap_set_bit (insns_conv, DF_REF_INSN_UID (def)) + && !reg_new) + return; + n_integer_to_sse++; + } + else + { + if (!reg_new) + return; + n_sse_to_integer++; + } + if (dump_file) fprintf (dump_file, " Mark r%d def in insn %d as requiring both modes in chain #%d\n", DF_REF_REGNO (def), DF_REF_INSN_UID (def), chain_id); - - bitmap_set_bit (defs_conv, DF_REF_REGNO (def)); } /* For TImode conversion, it is unused. */ @@ -523,7 +549,7 @@ general_scalar_chain::compute_convert_gain () || GET_CODE (src) == ASHIFTRT || GET_CODE (src) == LSHIFTRT) { - if (CONST_INT_P (XEXP (src, 0))) + if (CONST_INT_P (XEXP (src, 0))) igain -= vector_const_cost (XEXP (src, 0)); igain += m * ix86_cost->shift_const - ix86_cost->sse_op; if (INTVAL (XEXP (src, 1)) >= 32) @@ -588,9 +614,12 @@ general_scalar_chain::compute_convert_gain () if (dump_file) fprintf (dump_file, " Instruction conversion gain: %d\n", gain); - /* ??? What about integer to SSE? */ - EXECUTE_IF_SET_IN_BITMAP (defs_conv, 0, insn_uid, bi) - cost += DF_REG_DEF_COUNT (insn_uid) * ix86_cost->sse_to_integer; + /* Cost the integer to sse and sse to integer moves. */ + cost += n_sse_to_integer * ix86_cost->sse_to_integer; + /* ??? integer_to_sse but we only have that in the RA cost table. + Assume sse_to_integer/integer_to_sse are the same which they + are at the moment. */ + cost += n_integer_to_sse * ix86_cost->sse_to_integer; if (dump_file) fprintf (dump_file, " Registers conversion cost: %d\n", cost); @@ -649,85 +678,64 @@ gen_gpr_to_xmm_move_src (enum machine_mode vmode, rtx gpr) and replace its uses in a chain. */ void -general_scalar_chain::make_vector_copies (unsigned regno) +general_scalar_chain::make_vector_copies (rtx_insn *insn, rtx reg) { - rtx reg = regno_reg_rtx[regno]; - rtx vreg = gen_reg_rtx (smode); - df_ref ref; - - defs_map.put (reg, vreg); + rtx vreg = *defs_map.get (reg); - /* For each insn defining REGNO, see if it is defined by an insn - not part of the chain but with uses in insns part of the chain - and insert a copy in that case. */ - for (ref = DF_REG_DEF_CHAIN (regno); ref; ref = DF_REF_NEXT_REG (ref)) + start_sequence (); + if (!TARGET_INTER_UNIT_MOVES_TO_VEC) { - if (bitmap_bit_p (insns, DF_REF_INSN_UID (ref))) - continue; - df_link *use; - for (use = DF_REF_CHAIN (ref); use; use = use->next) - if (!DF_REF_REG_MEM_P (use->ref) - && bitmap_bit_p (insns, DF_REF_INSN_UID (use->ref))) - break; - if (!use) - continue; - - start_sequence (); - if (!TARGET_INTER_UNIT_MOVES_TO_VEC) + rtx tmp = assign_386_stack_local (smode, SLOT_STV_TEMP); + if (smode == DImode && !TARGET_64BIT) { - rtx tmp = assign_386_stack_local (smode, SLOT_STV_TEMP); - if (smode == DImode && !TARGET_64BIT) - { - emit_move_insn (adjust_address (tmp, SImode, 0), - gen_rtx_SUBREG (SImode, reg, 0)); - emit_move_insn (adjust_address (tmp, SImode, 4), - gen_rtx_SUBREG (SImode, reg, 4)); - } - else - emit_move_insn (copy_rtx (tmp), reg); - emit_insn (gen_rtx_SET (gen_rtx_SUBREG (vmode, vreg, 0), - gen_gpr_to_xmm_move_src (vmode, tmp))); + emit_move_insn (adjust_address (tmp, SImode, 0), + gen_rtx_SUBREG (SImode, reg, 0)); + emit_move_insn (adjust_address (tmp, SImode, 4), + gen_rtx_SUBREG (SImode, reg, 4)); } - else if (!TARGET_64BIT && smode == DImode) + else + emit_move_insn (copy_rtx (tmp), reg); + emit_insn (gen_rtx_SET (gen_rtx_SUBREG (vmode, vreg, 0), + gen_gpr_to_xmm_move_src (vmode, tmp))); + } + else if (!TARGET_64BIT && smode == DImode) + { + if (TARGET_SSE4_1) { - if (TARGET_SSE4_1) - { - emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, vreg, 0), - CONST0_RTX (V4SImode), - gen_rtx_SUBREG (SImode, reg, 0))); - emit_insn (gen_sse4_1_pinsrd (gen_rtx_SUBREG (V4SImode, vreg, 0), - gen_rtx_SUBREG (V4SImode, vreg, 0), - gen_rtx_SUBREG (SImode, reg, 4), - GEN_INT (2))); - } - else - { - rtx tmp = gen_reg_rtx (DImode); - emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, vreg, 0), - CONST0_RTX (V4SImode), - gen_rtx_SUBREG (SImode, reg, 0))); - emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, tmp, 0), - CONST0_RTX (V4SImode), - gen_rtx_SUBREG (SImode, reg, 4))); - emit_insn (gen_vec_interleave_lowv4si - (gen_rtx_SUBREG (V4SImode, vreg, 0), - gen_rtx_SUBREG (V4SImode, vreg, 0), - gen_rtx_SUBREG (V4SImode, tmp, 0))); - } + emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, vreg, 0), + CONST0_RTX (V4SImode), + gen_rtx_SUBREG (SImode, reg, 0))); + emit_insn (gen_sse4_1_pinsrd (gen_rtx_SUBREG (V4SImode, vreg, 0), + gen_rtx_SUBREG (V4SImode, vreg, 0), + gen_rtx_SUBREG (SImode, reg, 4), + GEN_INT (2))); } else - emit_insn (gen_rtx_SET (gen_rtx_SUBREG (vmode, vreg, 0), - gen_gpr_to_xmm_move_src (vmode, reg))); - rtx_insn *seq = get_insns (); - end_sequence (); - rtx_insn *insn = DF_REF_INSN (ref); - emit_conversion_insns (seq, insn); - - if (dump_file) - fprintf (dump_file, - " Copied r%d to a vector register r%d for insn %d\n", - regno, REGNO (vreg), INSN_UID (insn)); + { + rtx tmp = gen_reg_rtx (DImode); + emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, vreg, 0), + CONST0_RTX (V4SImode), + gen_rtx_SUBREG (SImode, reg, 0))); + emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, tmp, 0), + CONST0_RTX (V4SImode), + gen_rtx_SUBREG (SImode, reg, 4))); + emit_insn (gen_vec_interleave_lowv4si + (gen_rtx_SUBREG (V4SImode, vreg, 0), + gen_rtx_SUBREG (V4SImode, vreg, 0), + gen_rtx_SUBREG (V4SImode, tmp, 0))); + } } + else + emit_insn (gen_rtx_SET (gen_rtx_SUBREG (vmode, vreg, 0), + gen_gpr_to_xmm_move_src (vmode, reg))); + rtx_insn *seq = get_insns (); + end_sequence (); + emit_conversion_insns (seq, insn); + + if (dump_file) + fprintf (dump_file, + " Copied r%d to a vector register r%d for insn %d\n", + REGNO (reg), REGNO (vreg), INSN_UID (insn)); } /* Copy the definition SRC of INSN inside the chain to DST for @@ -1158,7 +1166,11 @@ general_scalar_chain::convert_registers () bitmap_iterator bi; unsigned id; EXECUTE_IF_SET_IN_BITMAP (defs_conv, 0, id, bi) - make_vector_copies (id); + defs_map.put (regno_reg_rtx[id], gen_reg_rtx (smode)); + EXECUTE_IF_SET_IN_BITMAP (insns_conv, 0, id, bi) + for (df_ref ref = DF_INSN_UID_DEFS (id); ref; ref = DF_REF_NEXT_LOC (ref)) + if (bitmap_bit_p (defs_conv, DF_REF_REGNO (ref))) + make_vector_copies (DF_REF_INSN (ref), DF_REF_REAL_REG (ref)); } /* Convert whole chain creating required register diff --git a/gcc/config/i386/i386-features.h b/gcc/config/i386/i386-features.h index 8381efe..09fe340 100644 --- a/gcc/config/i386/i386-features.h +++ b/gcc/config/i386/i386-features.h @@ -167,16 +167,19 @@ class scalar_chain class general_scalar_chain : public scalar_chain { public: - general_scalar_chain (enum machine_mode smode_, enum machine_mode vmode_) - : scalar_chain (smode_, vmode_) {} + general_scalar_chain (enum machine_mode smode_, enum machine_mode vmode_); + ~general_scalar_chain (); int compute_convert_gain (); private: hash_map defs_map; + bitmap insns_conv; + unsigned n_sse_to_integer; + unsigned n_integer_to_sse; void mark_dual_mode_def (df_ref def); void convert_insn (rtx_insn *insn); void convert_op (rtx *op, rtx_insn *insn); void convert_reg (rtx_insn *insn, rtx dst, rtx src); - void make_vector_copies (unsigned regno); + void make_vector_copies (rtx_insn *, rtx); void convert_registers (); int vector_const_cost (rtx exp); }; -- cgit v1.1 From 433f84bffa4744b01da49f4eee28a1f1ddf30793 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 27 Aug 2019 14:25:04 +0000 Subject: libgo: rebuild runtime.inc if mkruntimeinc.sh changes The Makefile was missing a dependency. Also remove runtime.inc.raw in mostlyclean. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/191958 From-SVN: r274956 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 4f08f23..18127de 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -58c0fc64d91edc53ef9828b85cf3dc86aeb94e12 +a6ddd0e1208a7d229c10be630c1110b3914038f5 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From f443634381265059d98dd130fe2c65f319ff49e0 Mon Sep 17 00:00:00 2001 From: Mark Eggleston Date: Tue, 27 Aug 2019 14:46:23 +0000 Subject: Options documentation fixes. Ensure that options lists fit cleanly inside the margins of a PDF page. Reword description of option -ffrontend-loop-interchange so that it fits cleanly inside the margins of a PDF page. Add options to those enabled by -fdec. From-SVN: r274958 --- gcc/fortran/ChangeLog | 9 +++++++++ gcc/fortran/invoke.texi | 53 +++++++++++++++++++++++++------------------------ 2 files changed, 36 insertions(+), 26 deletions(-) (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 643a7d0..3d8e49a 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,12 @@ +2019-08-27 Mark Eggleston + + * invoke.texi: Ensure that the option lists fit within the + margins of a PDF page. Re-worded description of + '-ffrontend-loop-interchange' so that it fits with the margins + of a PDF page. Add '-fdec-include', '-fdec-blank-format-item' + and '-fdec-format-defaults' to list of options that are enabled + by '-fdec'. + 2019-08-26 Thomas Koenig PR fortran/91390 diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi index 0b8abc5..6521e25 100644 --- a/gcc/fortran/invoke.texi +++ b/gcc/fortran/invoke.texi @@ -120,13 +120,14 @@ by type. Explanations are in the following sections. -fbackslash -fcray-pointer -fd-lines-as-code -fd-lines-as-comments -fdec @gol -fdec-structure-fdec-intrinsic-ints -fdec-static -fdec-math -fdec-include @gol -fdec-format-defaults -fdec-blank-format-item -fdefault-double-8 @gol --fdefault-integer-8 -fdefault-real-8 -fdefault-real-10 -fdefault-real-16 @gol --fdollar-ok -ffixed-line-length-@var{n} -ffixed-line-length-none @gol --fpad-source -ffree-form -ffree-line-length-@var{n} -ffree-line-length-none @gol --fimplicit-none -finteger-4-integer-8 -fmax-identifier-length @gol --fmodule-private -ffixed-form -fno-range-check -fopenacc -fopenmp @gol --freal-4-real-10 -freal-4-real-16 -freal-4-real-8 -freal-8-real-10 @gol --freal-8-real-16 -freal-8-real-4 -std=@var{std} -ftest-forall-temp +-fdefault-integer-8 -fdefault-real-8 -fdefault-real-10 @gol +-fdefault-real-16 -fdollar-ok -ffixed-line-length-@var{n} @gol +-ffixed-line-length-none -fpad-source -ffree-form @gol +-ffree-line-length-@var{n} -ffree-line-length-none -fimplicit-none @gol +-finteger-4-integer-8 -fmax-identifier-length -fmodule-private @gol +-ffixed-form -fno-range-check -fopenacc -fopenmp -freal-4-real-10 @gol +-freal-4-real-16 -freal-4-real-8 -freal-8-real-10 -freal-8-real-16 @gol +-freal-8-real-4 -std=@var{std} -ftest-forall-temp } @item Preprocessing Options @@ -144,14 +145,15 @@ by type. Explanations are in the following sections. @item Error and Warning Options @xref{Error and Warning Options,,Options to request or suppress errors and warnings}. -@gccoptlist{-Waliasing -Wall -Wampersand -Wargument-mismatch -Warray-bounds +@gccoptlist{-Waliasing -Wall -Wampersand -Wargument-mismatch -Warray-bounds @gol -Wc-binding-type -Wcharacter-truncation -Wconversion @gol -Wdo-subscript -Wfunction-elimination -Wimplicit-interface @gol --Wimplicit-procedure -Wintrinsic-shadow -Wuse-without-only -Wintrinsics-std @gol --Wline-truncation -Wno-align-commons -Wno-tabs -Wreal-q-constant @gol --Wsurprising -Wunderflow -Wunused-parameter -Wrealloc-lhs @gol --Wrealloc-lhs-all -Wfrontend-loop-interchange -Wtarget-lifetime @gol --fmax-errors=@var{n} -fsyntax-only -pedantic -pedantic-errors @gol +-Wimplicit-procedure -Wintrinsic-shadow -Wuse-without-only @gol +-Wintrinsics-std -Wline-truncation -Wno-align-commons -Wno-tabs @gol +-Wreal-q-constant -Wsurprising -Wunderflow -Wunused-parameter @gol +-Wrealloc-lhs -Wrealloc-lhs-all -Wfrontend-loop-interchange @gol +-Wtarget-lifetime -fmax-errors=@var{n} -fsyntax-only -pedantic @gol +-pedantic-errors @gol } @item Debugging Options @@ -185,19 +187,16 @@ and warnings}. -fbounds-check -ftail-call-workaround -ftail-call-workaround=@var{n} @gol -fcheck-array-temporaries @gol -fcheck=@var{} @gol --fcoarray=@var{} -fexternal-blas -ff2c --ffrontend-loop-interchange @gol --ffrontend-optimize @gol +-fcoarray=@var{} -fexternal-blas -ff2c @gol +-ffrontend-loop-interchange -ffrontend-optimize @gol -finit-character=@var{n} -finit-integer=@var{n} -finit-local-zero @gol --finit-derived @gol --finit-logical=@var{} +-finit-derived -finit-logical=@var{} @gol -finit-real=@var{} @gol --finline-matmul-limit=@var{n} @gol --fmax-array-constructor=@var{n} -fmax-stack-var-size=@var{n} --fno-align-commons @gol --fno-automatic -fno-protect-parens -fno-underscoring @gol --fsecond-underscore -fpack-derived -frealloc-lhs -frecursive @gol --frepack-arrays -fshort-enums -fstack-arrays +-finline-matmul-limit=@var{n} -fmax-array-constructor=@var{n} @gol +-fmax-stack-var-size=@var{n} -fno-align-commons -fno-automatic @gol +-fno-protect-parens -fno-underscoring -fsecond-underscore @gol +-fpack-derived -frealloc-lhs -frecursive -frepack-arrays @gol +-fshort-enums -fstack-arrays } @end table @@ -268,6 +267,8 @@ full documentation. Other flags enabled by this switch are: @option{-fdollar-ok} @option{-fcray-pointer} @option{-fdec-structure} @option{-fdec-intrinsic-ints} @option{-fdec-static} @option{-fdec-math} +@option{-fdec-include} @option{-fdec-blank-format-item} +@option{-fdec-format-defaults} If @option{-fd-lines-as-code}/@option{-fd-lines-as-comments} are unset, then @option{-fdec} also sets @option{-fd-lines-as-comments}. @@ -970,8 +971,8 @@ may be problematic. This currently includes @option{-Wcompare-reals}, @opindex @code{Wfrontend-loop-interchange} @cindex warnings, loop interchange @cindex loop interchange, warning -Enable warning for loop interchanges performed by the -@option{-ffrontend-loop-interchange} option. +Warn when using @option{-ffrontend-loop-interchange} for performing loop +interchanges. @item -Wimplicit-interface @opindex @code{Wimplicit-interface} -- cgit v1.1 From c8935981ff34d8ed32f81b37aa7a68edf4c53efe Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Tue, 27 Aug 2019 16:18:27 +0000 Subject: re PR c++/83431 (-Wformat-truncation may incorrectly report truncation) gcc/testsuite/ChangeLog: PR c++/83431 PR testsuite/91562 * gcc.dg/strlenopt-8.c: Adjust pass/dump name. From-SVN: r274961 --- gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/gcc.dg/strlenopt-8.c | 10 +++++----- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 64970b2..9bc1a3f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2019-08-27 Martin Sebor + + PR c++/83431 + PR testsuite/91562 + * gcc.dg/strlenopt-8.c: Adjust pass/dump name. + 2019-08-27 Jakub Jelinek PR c++/91415 diff --git a/gcc/testsuite/gcc.dg/strlenopt-8.c b/gcc/testsuite/gcc.dg/strlenopt-8.c index f43b809..b47a23b 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-8.c +++ b/gcc/testsuite/gcc.dg/strlenopt-8.c @@ -43,8 +43,8 @@ main () return 0; } -/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ +/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ +/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */ -- cgit v1.1 From c1441faf150e00d2090e268cf78390cbd2636859 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Tue, 27 Aug 2019 19:23:59 +0200 Subject: re PR target/91528 (ICE in ix86_expand_prologue at i386.c:7844 since r274481) PR target/91528 * config/i386/i386-features.c (convert_scalars_to_vector): Update crtl->stack_realign_needed, crtl->stack_realign_tried and crtl->stack_realign_processed. Update crtl->drap_reg by calling targetm.calls.get_drap_rtx. If drap_rtx is non-null then Update crtl->args.internal_arg_pointer and call fixup_tail_calls. testsuite/ChangeLog: PR target/91528 * gcc.target/i386/pr91528.c: New test. From-SVN: r274962 --- gcc/ChangeLog | 9 +++++++++ gcc/config/i386/i386-features.c | 26 ++++++++++++++++++++++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.target/i386/pr91528.c | 14 ++++++++++++++ 4 files changed, 54 insertions(+) create mode 100644 gcc/testsuite/gcc.target/i386/pr91528.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 65f9db9..39459d0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2019-08-27 Uroš Bizjak + + PR target/91528 + * config/i386/i386-features.c (convert_scalars_to_vector): + Update crtl->stack_realign_needed, crtl->stack_realign_tried and + crtl->stack_realign_processed. Update crtl->drap_reg by calling + targetm.calls.get_drap_rtx. If drap_rtx is non-null then + Update crtl->args.internal_arg_pointer and call fixup_tail_calls. + 2019-08-27 Richard Biener * config/i386/i386-features.h diff --git a/gcc/config/i386/i386-features.c b/gcc/config/i386/i386-features.c index 9505b4a..6eb1482 100644 --- a/gcc/config/i386/i386-features.c +++ b/gcc/config/i386/i386-features.c @@ -1651,6 +1651,32 @@ convert_scalars_to_vector (bool timode_p) crtl->stack_alignment_needed = 128; if (crtl->stack_alignment_estimated < 128) crtl->stack_alignment_estimated = 128; + + crtl->stack_realign_needed + = INCOMING_STACK_BOUNDARY < crtl->stack_alignment_estimated; + crtl->stack_realign_tried = crtl->stack_realign_needed; + + crtl->stack_realign_processed = true; + + if (!crtl->drap_reg) + { + rtx drap_rtx = targetm.calls.get_drap_rtx (); + + /* stack_realign_drap and drap_rtx must match. */ + gcc_assert ((stack_realign_drap != 0) == (drap_rtx != NULL)); + + /* Do nothing if NULL is returned, + which means DRAP is not needed. */ + if (drap_rtx != NULL) + { + crtl->args.internal_arg_pointer = drap_rtx; + + /* Call fixup_tail_calls to clean up + REG_EQUIV note if DRAP is needed. */ + fixup_tail_calls (); + } + } + /* Fix up DECL_RTL/DECL_INCOMING_RTL of arguments. */ if (TARGET_64BIT) for (tree parm = DECL_ARGUMENTS (current_function_decl); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9bc1a3f..c9185e5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-08-27 Uroš Bizjak + + PR target/91528 + * gcc.target/i386/pr91528.c: New test. + 2019-08-27 Martin Sebor PR c++/83431 diff --git a/gcc/testsuite/gcc.target/i386/pr91528.c b/gcc/testsuite/gcc.target/i386/pr91528.c new file mode 100644 index 0000000..add2111 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr91528.c @@ -0,0 +1,14 @@ +/* PR target/91528 */ +/* { dg-do compile { target ia32 } } */ +/* { dg-options "-Os -mavx512vbmi2 -mforce-drap" } */ + +extern long int labs (long int j); + +int +main () +{ + long *a = (long *)"empty"; + int i = 1441516387; + a[i] = labs (a[i]); + return 0; +} -- cgit v1.1 From 340d34bf76dd9455ab07ea849168bf2503d5edef Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Tue, 27 Aug 2019 19:37:03 +0200 Subject: sse4_1-round-roundeven-1.c (dg-options): Add -mfpmath=sse. * gcc.target/i386/sse4_1-round-roundeven-1.c (dg-options): Add -mfpmath=sse. * gcc.target/i386/sse4_1-round-roundeven-2.c (dg-options): Ditto. From-SVN: r274964 --- gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/gcc.target/i386/sse4_1-round-roundeven-1.c | 2 +- gcc/testsuite/gcc.target/i386/sse4_1-round-roundeven-2.c | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c9185e5..a8149f7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,11 @@ 2019-08-27 Uroš Bizjak + * gcc.target/i386/sse4_1-round-roundeven-1.c (dg-options): + Add -mfpmath=sse. + * gcc.target/i386/sse4_1-round-roundeven-2.c (dg-options): Ditto. + +2019-08-27 Uroš Bizjak + PR target/91528 * gcc.target/i386/pr91528.c: New test. diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-round-roundeven-1.c b/gcc/testsuite/gcc.target/i386/sse4_1-round-roundeven-1.c index 3633263..778063e 100644 --- a/gcc/testsuite/gcc.target/i386/sse4_1-round-roundeven-1.c +++ b/gcc/testsuite/gcc.target/i386/sse4_1-round-roundeven-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -msse4.1" } */ +/* { dg-options "-O2 -msse4.1 -mfpmath=sse" } */ __attribute__((noinline, noclone)) double f1 (double x) diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-round-roundeven-2.c b/gcc/testsuite/gcc.target/i386/sse4_1-round-roundeven-2.c index 9505796..6715a28 100644 --- a/gcc/testsuite/gcc.target/i386/sse4_1-round-roundeven-2.c +++ b/gcc/testsuite/gcc.target/i386/sse4_1-round-roundeven-2.c @@ -1,6 +1,6 @@ /* { dg-do run } */ /* { dg-require-effective-target sse4 } */ -/* { dg-options "-O2 -msse4.1" } */ +/* { dg-options "-O2 -msse4.1 -mfpmath=sse" } */ #include "sse4_1-check.h" #include "sse4_1-round-roundeven-1.c" -- cgit v1.1 From 2bd86b95f76315f102c52a81453ef375c97e8f1b Mon Sep 17 00:00:00 2001 From: Harald Anlauf Date: Tue, 27 Aug 2019 19:16:33 +0000 Subject: re PR fortran/91496 (!GCC$ directives error if mistyped or unknown) 2019-08-27 Harald Anlauf PR fortran/91496 * gfortran.h: Extend struct gfc_iterator for loop annotations. * array.c (gfc_copy_iterator): Copy loop annotations by IVDEP, VECTOR, and NOVECTOR pragmas. * decl.c (gfc_match_gcc_ivdep, gfc_match_gcc_vector) (gfc_match_gcc_novector): New matcher functions handling IVDEP, VECTOR, and NOVECTOR pragmas. * match.h: Declare prototypes of matcher functions handling IVDEP, VECTOR, and NOVECTOR pragmas. * parse.c (decode_gcc_attribute, parse_do_block) (parse_executable): Decode IVDEP, VECTOR, and NOVECTOR pragmas; emit warning for unrecognized pragmas instead of error. * trans-stmt.c (gfc_trans_simple_do, gfc_trans_do): Add code to emit annotations for IVDEP, VECTOR, and NOVECTOR pragmas. * gfortran.texi: Document IVDEP, VECTOR, and NOVECTOR pragmas. PR fortran/91496 * gfortran.dg/pr91496.f90: New testcase. From-SVN: r274966 --- gcc/fortran/ChangeLog | 18 ++++++++++++ gcc/fortran/array.c | 3 ++ gcc/fortran/decl.c | 55 +++++++++++++++++++++++++++++++++++ gcc/fortran/gfortran.h | 6 ++++ gcc/fortran/gfortran.texi | 49 +++++++++++++++++++++++++++++++ gcc/fortran/match.h | 5 +++- gcc/fortran/parse.c | 34 +++++++++++++++++++++- gcc/fortran/trans-stmt.c | 27 +++++++++++++++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gfortran.dg/pr91496.f90 | 38 ++++++++++++++++++++++++ 10 files changed, 238 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/pr91496.f90 (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 3d8e49a..4ef8106 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,21 @@ +2019-08-27 Harald Anlauf + + PR fortran/91496 + * gfortran.h: Extend struct gfc_iterator for loop annotations. + * array.c (gfc_copy_iterator): Copy loop annotations by IVDEP, + VECTOR, and NOVECTOR pragmas. + * decl.c (gfc_match_gcc_ivdep, gfc_match_gcc_vector) + (gfc_match_gcc_novector): New matcher functions handling IVDEP, + VECTOR, and NOVECTOR pragmas. + * match.h: Declare prototypes of matcher functions handling IVDEP, + VECTOR, and NOVECTOR pragmas. + * parse.c (decode_gcc_attribute, parse_do_block) + (parse_executable): Decode IVDEP, VECTOR, and NOVECTOR pragmas; + emit warning for unrecognized pragmas instead of error. + * trans-stmt.c (gfc_trans_simple_do, gfc_trans_do): Add code to + emit annotations for IVDEP, VECTOR, and NOVECTOR pragmas. + * gfortran.texi: Document IVDEP, VECTOR, and NOVECTOR pragmas. + 2019-08-27 Mark Eggleston * invoke.texi: Ensure that the option lists fit within the diff --git a/gcc/fortran/array.c b/gcc/fortran/array.c index 396dd97..b958e89 100644 --- a/gcc/fortran/array.c +++ b/gcc/fortran/array.c @@ -2185,6 +2185,9 @@ gfc_copy_iterator (gfc_iterator *src) dest->end = gfc_copy_expr (src->end); dest->step = gfc_copy_expr (src->step); dest->unroll = src->unroll; + dest->ivdep = src->ivdep; + dest->vector = src->vector; + dest->novector = src->novector; return dest; } diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c index 5f12fe1..d5c8c33 100644 --- a/gcc/fortran/decl.c +++ b/gcc/fortran/decl.c @@ -99,6 +99,11 @@ bool gfc_matching_function; /* Set upon parsing a !GCC$ unroll n directive for use in the next loop. */ int directive_unroll = -1; +/* Set upon parsing supported !GCC$ pragmas for use in the next loop. */ +bool directive_ivdep = false; +bool directive_vector = false; +bool directive_novector = false; + /* Map of middle-end built-ins that should be vectorized. */ hash_map *gfc_vectorized_builtins; @@ -11528,3 +11533,53 @@ gfc_match_gcc_builtin (void) return MATCH_YES; } + +/* Match an !GCC$ IVDEP statement. + When we come here, we have already matched the !GCC$ IVDEP string. */ + +match +gfc_match_gcc_ivdep (void) +{ + if (gfc_match_eos () == MATCH_YES) + { + directive_ivdep = true; + return MATCH_YES; + } + + gfc_error ("Syntax error in !GCC$ IVDEP directive at %C"); + return MATCH_ERROR; +} + +/* Match an !GCC$ VECTOR statement. + When we come here, we have already matched the !GCC$ VECTOR string. */ + +match +gfc_match_gcc_vector (void) +{ + if (gfc_match_eos () == MATCH_YES) + { + directive_vector = true; + directive_novector = false; + return MATCH_YES; + } + + gfc_error ("Syntax error in !GCC$ VECTOR directive at %C"); + return MATCH_ERROR; +} + +/* Match an !GCC$ NOVECTOR statement. + When we come here, we have already matched the !GCC$ NOVECTOR string. */ + +match +gfc_match_gcc_novector (void) +{ + if (gfc_match_eos () == MATCH_YES) + { + directive_novector = true; + directive_vector = false; + return MATCH_YES; + } + + gfc_error ("Syntax error in !GCC$ NOVECTOR directive at %C"); + return MATCH_ERROR; +} diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 7f54897..d2f40df 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -2418,6 +2418,9 @@ typedef struct { gfc_expr *var, *start, *end, *step; unsigned short unroll; + bool ivdep; + bool vector; + bool novector; } gfc_iterator; @@ -2794,6 +2797,9 @@ gfc_finalizer; bool gfc_in_match_data (void); match gfc_match_char_spec (gfc_typespec *); extern int directive_unroll; +extern bool directive_ivdep; +extern bool directive_vector; +extern bool directive_novector; /* SIMD clause enum. */ enum gfc_simd_clause diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi index 4515b9d..22d42f4 100644 --- a/gcc/fortran/gfortran.texi +++ b/gcc/fortran/gfortran.texi @@ -3559,6 +3559,9 @@ as this requires the new array descriptor. * ATTRIBUTES directive:: * UNROLL directive:: * BUILTIN directive:: +* IVDEP directive:: +* VECTOR directive:: +* NOVECTOR directive:: @end menu @node ATTRIBUTES directive @@ -3670,6 +3673,52 @@ for the built-in that should be vectorized. Example usage: The purpose of the directive is to provide an API among the GCC compiler and the GNU C Library which would define vector implementations of math routines. + +@node IVDEP directive +@subsection IVDEP directive + +The syntax of the directive is + +@code{!GCC$ ivdep} + +This directive tells the compiler to ignore vector dependencies in the +following loop. It must be placed immediately before a @code{DO} loop +and applies only to the loop that follows. + +Sometimes the compiler may not have sufficient information to decide +whether a particular loop is vectorizable due to potential +dependencies between iterations. The purpose of the directive is to +tell the compiler that vectorization is safe. + +This directive is intended for annotation of existing code. For new +code it is recommended to consider OpenMP SIMD directives as potential +alternative. + + +@node VECTOR directive +@subsection VECTOR directive + +The syntax of the directive is + +@code{!GCC$ vector} + +This directive tells the compiler to vectorize the following loop. It +must be placed immediately before a @code{DO} loop and applies only to +the loop that follows. + + +@node NOVECTOR directive +@subsection NOVECTOR directive + +The syntax of the directive is + +@code{!GCC$ novector} + +This directive tells the compiler to not vectorize the following loop. +It must be placed immediately before a @code{DO} loop and applies only +to the loop that follows. + + @node Non-Fortran Main Program @section Non-Fortran Main Program diff --git a/gcc/fortran/match.h b/gcc/fortran/match.h index ac47d99..29854ee 100644 --- a/gcc/fortran/match.h +++ b/gcc/fortran/match.h @@ -246,8 +246,11 @@ match gfc_match_contiguous (void); match gfc_match_dimension (void); match gfc_match_external (void); match gfc_match_gcc_attributes (void); -match gfc_match_gcc_unroll (void); match gfc_match_gcc_builtin (void); +match gfc_match_gcc_ivdep (void); +match gfc_match_gcc_novector (void); +match gfc_match_gcc_unroll (void); +match gfc_match_gcc_vector (void); match gfc_match_import (void); match gfc_match_intent (void); match gfc_match_intrinsic (void); diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c index 31466d2..8950b6a 100644 --- a/gcc/fortran/parse.c +++ b/gcc/fortran/parse.c @@ -1079,12 +1079,20 @@ decode_gcc_attribute (void) match ("attributes", gfc_match_gcc_attributes, ST_ATTR_DECL); match ("unroll", gfc_match_gcc_unroll, ST_NONE); match ("builtin", gfc_match_gcc_builtin, ST_NONE); + match ("ivdep", gfc_match_gcc_ivdep, ST_NONE); + match ("vector", gfc_match_gcc_vector, ST_NONE); + match ("novector", gfc_match_gcc_novector, ST_NONE); /* All else has failed, so give up. See if any of the matchers has stored an error message of some sort. */ if (!gfc_error_check ()) - gfc_error_now ("Unclassifiable GCC directive at %C"); + { + if (pedantic) + gfc_error_now ("Unclassifiable GCC directive at %C"); + else + gfc_warning_now (0, "Unclassifiable GCC directive at %C, ignored"); + } reject_statement (); @@ -4672,6 +4680,21 @@ parse_do_block (void) new_st.ext.iterator->unroll = directive_unroll; directive_unroll = -1; } + if (directive_ivdep) + { + new_st.ext.iterator->ivdep = directive_ivdep; + directive_ivdep = false; + } + if (directive_vector) + { + new_st.ext.iterator->vector = directive_vector; + directive_vector = false; + } + if (directive_novector) + { + new_st.ext.iterator->novector = directive_novector; + directive_novector = false; + } } else stree = NULL; @@ -5433,6 +5456,15 @@ parse_executable (gfc_statement st) if (directive_unroll != -1) gfc_error ("% directive does not commence a loop at %C"); + if (directive_ivdep) + gfc_error ("% directive does not commence a loop at %C"); + + if (directive_vector) + gfc_error ("% directive does not commence a loop at %C"); + + if (directive_novector) + gfc_error ("% directive does not commence a loop at %C"); + st = next_statement (); } } diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c index 7c36563..3606880 100644 --- a/gcc/fortran/trans-stmt.c +++ b/gcc/fortran/trans-stmt.c @@ -2173,6 +2173,19 @@ gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar, build_int_cst (integer_type_node, annot_expr_unroll_kind), build_int_cst (integer_type_node, code->ext.iterator->unroll)); + if (code->ext.iterator->ivdep && cond != error_mark_node) + cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, + build_int_cst (integer_type_node, annot_expr_ivdep_kind), + integer_zero_node); + if (code->ext.iterator->vector && cond != error_mark_node) + cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, + build_int_cst (integer_type_node, annot_expr_vector_kind), + integer_zero_node); + if (code->ext.iterator->novector && cond != error_mark_node) + cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, + build_int_cst (integer_type_node, annot_expr_no_vector_kind), + integer_zero_node); + /* The loop exit. */ tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label); TREE_USED (exit_label) = 1; @@ -2503,6 +2516,20 @@ gfc_trans_do (gfc_code * code, tree exit_cond) = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, build_int_cst (integer_type_node, annot_expr_unroll_kind), build_int_cst (integer_type_node, code->ext.iterator->unroll)); + + if (code->ext.iterator->ivdep && cond != error_mark_node) + cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, + build_int_cst (integer_type_node, annot_expr_ivdep_kind), + integer_zero_node); + if (code->ext.iterator->vector && cond != error_mark_node) + cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, + build_int_cst (integer_type_node, annot_expr_vector_kind), + integer_zero_node); + if (code->ext.iterator->novector && cond != error_mark_node) + cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, + build_int_cst (integer_type_node, annot_expr_no_vector_kind), + integer_zero_node); + tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label); tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, cond, tmp, build_empty_stmt (loc)); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a8149f7..37133de 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-08-27 Harald Anlauf + + PR fortran/91496 + * gfortran.dg/pr91496.f90: New testcase. + 2019-08-27 Uroš Bizjak * gcc.target/i386/sse4_1-round-roundeven-1.c (dg-options): diff --git a/gcc/testsuite/gfortran.dg/pr91496.f90 b/gcc/testsuite/gfortran.dg/pr91496.f90 new file mode 100644 index 0000000..cb31674 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr91496.f90 @@ -0,0 +1,38 @@ +! { dg-do compile } +! { dg-options "-fdump-tree-original" } +! +subroutine foo (a, b, c, n) + implicit none + real a(*), b(*), c(*) + integer :: i, n + external bar +!DIR$ unroll (4) +!GCC$ unroll 4 + do i = 1, n + a(i) = b(i) + c(i) + end do +!DIR$ ivdep +!GCC$ ivdep + do i = 1, n + a(i) = b(i) + c(i) + end do +!DIR$ vector +!GCC$ vector + do i = 1, n + a(i) = b(i) + c(i) + end do +!DIR$ novector +!GCC$ novector + do i = 1, n + a(i) = b(i) + c(i) + end do +!GCC$ ivdep +!GCC$ vector + do i = 1, n + a(i) = b(i) + c(i) + end do +!DIR$ noinline +!GCC$ noinline ! { dg-warning "Unclassifiable GCC directive" } + call bar (a) +end subroutine foo +! { dg-final { scan-tree-dump-times "ANNOTATE_EXPR" 6 "original" } } -- cgit v1.1 From 2d8ba44101028f4be534a20a0d2146695e1dc4fd Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Tue, 27 Aug 2019 17:03:45 -0600 Subject: tree-ssa-strlen.c (printf_strlen_execute): Initialize the loop optimizer and SCEV before sizing ssa_ver_to_stridx. * tree-ssa-strlen.c (printf_strlen_execute): Initialize the loop optimizer and SCEV before sizing ssa_ver_to_stridx. * gcc.c-torture/compile/20190827-1.c: New test. From-SVN: r274975 --- gcc/ChangeLog | 5 ++ gcc/testsuite/ChangeLog | 4 + gcc/testsuite/gcc.c-torture/compile/20190827-1.c | 104 +++++++++++++++++++++++ gcc/tree-ssa-strlen.c | 16 ++-- 4 files changed, 122 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/20190827-1.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 39459d0..1d9d6cf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-08-27 Jeff Law + + * tree-ssa-strlen.c (printf_strlen_execute): Initialize + the loop optimizer and SCEV before sizing ssa_ver_to_stridx. + 2019-08-27 Uroš Bizjak PR target/91528 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 37133de..2560faf 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-08-27 Jeff Law + + * gcc.c-torture/compile/20190827-1.c: New test. + 2019-08-27 Harald Anlauf PR fortran/91496 diff --git a/gcc/testsuite/gcc.c-torture/compile/20190827-1.c b/gcc/testsuite/gcc.c-torture/compile/20190827-1.c new file mode 100644 index 0000000..f095617 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/20190827-1.c @@ -0,0 +1,104 @@ +typedef unsigned char __u8; +typedef __u8 u8; +typedef u8 u_int8_t; +typedef unsigned int gfp_t; + +struct list_head +{ + struct list_head *next, *prev; +}; +extern int strcmp (const char *, const char *); +enum +{ + NFPROTO_UNSPEC = 0, + NFPROTO_INET = 1, + NFPROTO_IPV4 = 2, + NFPROTO_ARP = 3, + NFPROTO_NETDEV = 5, + NFPROTO_BRIDGE = 7, + NFPROTO_IPV6 = 10, + NFPROTO_DECNET = 12, + NFPROTO_NUMPROTO, +}; + +struct xt_target +{ + struct list_head list; + const char name[29]; + u_int8_t revision; +}; + +struct xt_af +{ + struct list_head target; +}; + +static struct xt_af *xt; + +struct xt_af * kcalloc (int, int, int); + +static int +target_revfn (u8 af, const char *name, u8 revision, int *bestp) +{ + const struct xt_target *t; + int have_rev = 0; + + for (t = ( + { + void *__mptr = (void *)((&xt[af].target)->next); + ((typeof (*t) *) (__mptr - + __builtin_offsetof (typeof (*t), list)));} + ); &t->list != (&xt[af].target); t = ( + { + void *__mptr = + (void *)((t)->list.next); + ((typeof (*(t)) *) (__mptr - + __builtin_offsetof + (typeof + (*(t)), + list)));} + )) + { + if (strcmp (t->name, name) == 0) + { + if (t->revision > *bestp) + *bestp = t->revision; + if (t->revision == revision) + have_rev = 1; + } + } + + if (af != NFPROTO_UNSPEC && !have_rev) + return target_revfn (NFPROTO_UNSPEC, name, revision, bestp); + + return have_rev; +} + +int +xt_find_revision (u8 af, const char *name, u8 revision, int target, int *err) +{ + int have_rev, best = -1; + + have_rev = target_revfn (af, name, revision, &best); + + + if (best == -1) + { + *err = -2; + return 0; + } + +} + + +static int __attribute__ ((__section__ (".init.text"))) + __attribute__ ((__cold__)) xt_init (void) +{ + xt = + kcalloc (NFPROTO_NUMPROTO, sizeof (struct xt_af), + (((gfp_t) (0x400u | 0x800u)) | ((gfp_t) 0x40u) | + ((gfp_t) 0x80u))); +} + +int init_module (void) __attribute__ ((__copy__ (xt_init))) + __attribute__ ((alias ("xt_init")));; diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index 5c5b838..d38352a 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -4850,13 +4850,6 @@ printf_strlen_execute (function *fun, bool warn_only) { strlen_optimize = !warn_only; - gcc_assert (!strlen_to_stridx); - if (warn_stringop_overflow || warn_stringop_truncation) - strlen_to_stridx = new hash_map (); - - ssa_ver_to_stridx.safe_grow_cleared (num_ssa_names); - max_stridx = 1; - calculate_dominance_info (CDI_DOMINATORS); bool use_scev = optimize > 0 && flag_printf_return_value; @@ -4866,6 +4859,15 @@ printf_strlen_execute (function *fun, bool warn_only) scev_initialize (); } + gcc_assert (!strlen_to_stridx); + if (warn_stringop_overflow || warn_stringop_truncation) + strlen_to_stridx = new hash_map (); + + /* This has to happen after initializing the loop optimizer + and initializing SCEV as they create new SSA_NAMEs. */ + ssa_ver_to_stridx.safe_grow_cleared (num_ssa_names); + max_stridx = 1; + /* String length optimization is implemented as a walk of the dominator tree and a forward walk of statements within each block. */ strlen_dom_walker walker (CDI_DOMINATORS); -- cgit v1.1 From 407b92bcfb34f352b6aad7b629bf365c02114469 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Tue, 27 Aug 2019 23:31:44 +0000 Subject: PR tree-optimization/91567 - Spurious -Wformat-overflow warnings building glibc (32-bit only) gcc/ChangeLog: PR tree-optimization/91567 * gimple-ssa-sprintf.c (get_string_length): Handle more forms of lengths of unknown strings. * vr-values.c (vr_values::extract_range_basic): Set strlen upper bound to PTRDIFF_MAX - 2. gcc/testsuite/ChangeLog: PR tree-optimization/91567 * gcc.dg/tree-ssa/builtin-snprintf-6.c: Xfail a subset of assertions on targets other than x86_64 to work around PR 83543. * gcc.dg/tree-ssa/builtin-sprintf-warn-22.c: New test. From-SVN: r274976 --- gcc/ChangeLog | 8 +++ gcc/gimple-ssa-sprintf.c | 19 +++++-- gcc/testsuite/ChangeLog | 7 +++ gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-6.c | 7 +++ .../gcc.dg/tree-ssa/builtin-sprintf-warn-22.c | 58 ++++++++++++++++++++++ gcc/vr-values.c | 7 ++- 6 files changed, 101 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-22.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1d9d6cf..1213e95 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2019-08-27 Martin Sebor + + PR tree-optimization/91567 + * gimple-ssa-sprintf.c (get_string_length): Handle more forms of lengths + of unknown strings. + * vr-values.c (vr_values::extract_range_basic): Set strlen upper bound + to PTRDIFF_MAX - 2. + 2019-08-27 Jeff Law * tree-ssa-strlen.c (printf_strlen_execute): Initialize diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c index 6a39a71..b11d798 100644 --- a/gcc/gimple-ssa-sprintf.c +++ b/gcc/gimple-ssa-sprintf.c @@ -1994,10 +1994,21 @@ get_string_length (tree str, unsigned eltsize, const vr_values *vr) or it's SIZE_MAX otherwise. */ /* Return the default result when nothing is known about the string. */ - if (lendata.maxbound - && integer_all_onesp (lendata.maxbound) - && integer_all_onesp (lendata.maxlen)) - return fmtresult (); + if (lendata.maxbound) + { + if (integer_all_onesp (lendata.maxbound) + && integer_all_onesp (lendata.maxlen)) + return fmtresult (); + + if (!tree_fits_uhwi_p (lendata.maxbound) + || !tree_fits_uhwi_p (lendata.maxlen)) + return fmtresult (); + + unsigned HOST_WIDE_INT lenmax = tree_to_uhwi (max_object_size ()) - 2; + if (lenmax <= tree_to_uhwi (lendata.maxbound) + && lenmax <= tree_to_uhwi (lendata.maxlen)) + return fmtresult (); + } HOST_WIDE_INT min = (tree_fits_uhwi_p (lendata.minlen) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2560faf..cd6fb7f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2019-08-27 Martin Sebor + + PR tree-optimization/91567 + * gcc.dg/tree-ssa/builtin-snprintf-6.c: Xfail a subset of assertions + on targets other than x86_64 to work around PR 83543. + * gcc.dg/tree-ssa/builtin-sprintf-warn-22.c: New test. + 2019-08-27 Jeff Law * gcc.c-torture/compile/20190827-1.c: New test. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-6.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-6.c index 0d9b275..df0e6b7 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-6.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-6.c @@ -65,6 +65,10 @@ void test_assign_init_list (void) T (5, ARGS ({ 1, 2, 3, 4, 5, 6, 0 }), "s=%.*s", 3, &a[2]); } +#if __x86_64__ + +/* Enabled only on x86_64 to work around PR 83543. */ + #undef T #define T(expect, init, fmt, ...) \ do { \ @@ -87,6 +91,9 @@ void test_assign_aggregate (void) T (5, "123456", "s=%.*s", 3, &s.a[2]); } +/* { dg-final { scan-tree-dump-times "Function test_assign_aggregate" 1 "optimized" { xfail { { ! x86_64-*-* } || { ilp32 } } } } } */ + +#endif /* x86_64 */ #undef T #define T(expect, init, fmt, ...) \ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-22.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-22.c new file mode 100644 index 0000000..6fd1bca --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-22.c @@ -0,0 +1,58 @@ +/* PR tree-optimization/91567 - Spurious -Wformat-overflow warnings building + glibc (32-bit only) + { dg-do compile } + { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */ + +typedef __SIZE_TYPE__ size_t; + +extern int sprintf (char*, const char*, ...); +extern size_t strlen (const char*); + +void f (char *); + +void g (char *s1, char *s2) +{ + char b[1025]; + size_t n = __builtin_strlen (s1), d = __builtin_strlen (s2); + if (n + d + 1 >= 1025) + return; + + sprintf (b, "%s.%s", s1, s2); // { dg-bogus "\\\[-Wformat-overflow" } + + f (b); +} + +/* Extracted from gcc/c-cppbuiltin.c. */ + +void cpp_define (char*); + +static void +builtin_define_type_minmax (const char *min_macro, const char *max_macro, + void *type) +{ + extern const char *suffix; + char *buf; + + if (type) + { + buf = (char *) __builtin_alloca (__builtin_strlen (min_macro) + 2 + + __builtin_strlen (suffix) + 1); + sprintf (buf, "%s=0%s", min_macro, suffix); // { dg-bogus "\\\[-Wformat-overflow" } + } + else + { + buf = (char *) __builtin_alloca (__builtin_strlen (min_macro) + 3 + + __builtin_strlen (max_macro) + 6); + sprintf (buf, "%s=(-%s - 1)", min_macro, max_macro); // { dg-bogus "\\\[-Wformat-overflow" } + } + + cpp_define (buf); +} + +void +c_cpp_builtins (void *type) +{ + + builtin_define_type_minmax ("__WCHAR_MIN__", "__WCHAR_MAX__", type); + builtin_define_type_minmax ("__WINT_MIN__", "__WINT_MAX__", type); +} diff --git a/gcc/vr-values.c b/gcc/vr-values.c index 96c764c..256cae7 100644 --- a/gcc/vr-values.c +++ b/gcc/vr-values.c @@ -1319,7 +1319,12 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) tree max = vrp_val_max (ptrdiff_type_node); wide_int wmax = wi::to_wide (max, TYPE_PRECISION (TREE_TYPE (max))); tree range_min = build_zero_cst (type); - tree range_max = wide_int_to_tree (type, wmax - 1); + /* To account for the terminating NUL, the maximum length + is one less than the maximum array size, which in turn + is one less than PTRDIFF_MAX (or SIZE_MAX where it's + smaller than the former type). + FIXME: Use max_object_size() - 1 here. */ + tree range_max = wide_int_to_tree (type, wmax - 2); vr->set (VR_RANGE, range_min, range_max); return; } -- cgit v1.1 From 4719ac2f2d1d770a840316d02e68fdff8e223129 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Wed, 28 Aug 2019 00:16:21 +0000 Subject: Daily bump. From-SVN: r274980 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 3f31c4a..1f39dbb 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20190827 +20190828 -- cgit v1.1 From 14da3939da3adcef84816573caa9d93c7367507e Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Wed, 28 Aug 2019 02:03:48 +0000 Subject: PR c++/91428 - warn about std::is_constant_evaluated in if constexpr. * cp-tree.h (decl_in_std_namespace_p): Declare. * semantics.c (is_std_constant_evaluated_p): New. (finish_if_stmt_cond): Warn about "std::is_constant_evaluated ()" in an if-constexpr. * typeck.c (decl_in_std_namespace_p): No longer static. * g++.dg/cpp2a/is-constant-evaluated9.C: New test. From-SVN: r274981 --- gcc/cp/ChangeLog | 9 ++++ gcc/cp/cp-tree.h | 1 + gcc/cp/semantics.c | 36 ++++++++++++++++ gcc/cp/typeck.c | 2 +- gcc/testsuite/ChangeLog | 5 +++ .../g++.dg/cpp2a/is-constant-evaluated9.C | 49 ++++++++++++++++++++++ 6 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated9.C (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 162b2c8..c2f1967 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2019-08-27 Marek Polacek + + PR c++/91428 - warn about std::is_constant_evaluated in if constexpr. + * cp-tree.h (decl_in_std_namespace_p): Declare. + * semantics.c (is_std_constant_evaluated_p): New. + (finish_if_stmt_cond): Warn about "std::is_constant_evaluated ()" in + an if-constexpr. + * typeck.c (decl_in_std_namespace_p): No longer static. + 2019-08-26 Jason Merrill * decl.c (duplicate_decls): Always merge DECL_DECLARED_CONSTEXPR_P. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 42f180d..225dbb6 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -7496,6 +7496,7 @@ extern tree finish_left_unary_fold_expr (tree, int); extern tree finish_right_unary_fold_expr (tree, int); extern tree finish_binary_fold_expr (tree, tree, int); extern bool treat_lvalue_as_rvalue_p (tree, bool); +extern bool decl_in_std_namespace_p (tree); /* in typeck2.c */ extern void require_complete_eh_spec_types (tree, tree); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 1f774593..8603e57 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -723,6 +723,28 @@ begin_if_stmt (void) return r; } +/* Returns true if FN, a CALL_EXPR, is a call to + std::is_constant_evaluated or __builtin_is_constant_evaluated. */ + +static bool +is_std_constant_evaluated_p (tree fn) +{ + /* std::is_constant_evaluated takes no arguments. */ + if (call_expr_nargs (fn) != 0) + return false; + + tree fndecl = cp_get_callee_fndecl_nofold (fn); + if (fndecl_built_in_p (fndecl, CP_BUILT_IN_IS_CONSTANT_EVALUATED, + BUILT_IN_FRONTEND)) + return true; + + if (!decl_in_std_namespace_p (fndecl)) + return false; + + tree name = DECL_NAME (fndecl); + return name && id_equal (name, "is_constant_evaluated"); +} + /* Process the COND of an if-statement, which may be given by IF_STMT. */ @@ -738,6 +760,20 @@ finish_if_stmt_cond (tree cond, tree if_stmt) converted to bool. */ && TYPE_MAIN_VARIANT (TREE_TYPE (cond)) == boolean_type_node) { + /* if constexpr (std::is_constant_evaluated()) is always true, + so give the user a clue. */ + if (warn_tautological_compare) + { + tree t = cond; + if (TREE_CODE (t) == CLEANUP_POINT_EXPR) + t = TREE_OPERAND (t, 0); + if (TREE_CODE (t) == CALL_EXPR + && is_std_constant_evaluated_p (t)) + warning_at (EXPR_LOCATION (cond), OPT_Wtautological_compare, + "%qs always evaluates to true in %", + "std::is_constant_evaluated"); + } + cond = instantiate_non_dependent_expr (cond); cond = cxx_constant_value (cond, NULL_TREE); } diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index e2a4f28..c09bb30 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -9328,7 +9328,7 @@ maybe_warn_about_returning_address_of_local (tree retval) /* Returns true if DECL is in the std namespace. */ -static bool +bool decl_in_std_namespace_p (tree decl) { return (decl != NULL_TREE diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cd6fb7f..ade1a69 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-08-27 Marek Polacek + + PR c++/91428 - warn about std::is_constant_evaluated in if constexpr. + * g++.dg/cpp2a/is-constant-evaluated9.C: New test. + 2019-08-27 Martin Sebor PR tree-optimization/91567 diff --git a/gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated9.C b/gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated9.C new file mode 100644 index 0000000..3783369 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated9.C @@ -0,0 +1,49 @@ +// PR c++/91428 - warn about std::is_constant_evaluated in if constexpr. +// { dg-do compile { target c++2a } } +// { dg-options "-Wtautological-compare" } + +namespace std { + constexpr inline bool + is_constant_evaluated () noexcept + { + return __builtin_is_constant_evaluated (); + } +} + +constexpr int +foo(int i) +{ + if constexpr (std::is_constant_evaluated ()) // { dg-warning ".std::is_constant_evaluated. always evaluates to true in .if constexpr." } + return 42; + else + return i; +} + +constexpr int +foo2(int i) +{ + if constexpr (__builtin_is_constant_evaluated ()) // { dg-warning ".std::is_constant_evaluated. always evaluates to true in .if constexpr." } + return 42; + else + return i; +} + +constexpr int +foo3(int i) +{ + // I is not a constant expression but we short-circuit it. + if constexpr (__builtin_is_constant_evaluated () || i) + return 42; + else + return i; +} + +constexpr int +foo4(int i) +{ + const int j = 0; + if constexpr (j && __builtin_is_constant_evaluated ()) + return 42; + else + return i; +} -- cgit v1.1 From 8692693732e89806058d3b9c91132fb83661b214 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Wed, 28 Aug 2019 02:22:29 +0000 Subject: PR c++/81676 - bogus -Wunused warnings in constexpr if. * semantics.c (maybe_mark_exp_read_r): New function. (finish_if_stmt): Call it on THEN_CLAUSE and ELSE_CLAUSE. * g++.dg/cpp1z/constexpr-if31.C: New test. * g++.dg/cpp1z/constexpr-if32.C: New test. From-SVN: r274982 --- gcc/cp/ChangeLog | 4 ++ gcc/cp/semantics.c | 22 ++++++++ gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/g++.dg/cpp1z/constexpr-if31.C | 79 +++++++++++++++++++++++++++++ gcc/testsuite/g++.dg/cpp1z/constexpr-if32.C | 16 ++++++ 5 files changed, 125 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp1z/constexpr-if31.C create mode 100644 gcc/testsuite/g++.dg/cpp1z/constexpr-if32.C (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c2f1967..b735dab 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2019-08-27 Marek Polacek + PR c++/81676 - bogus -Wunused warnings in constexpr if. + * semantics.c (maybe_mark_exp_read_r): New function. + (finish_if_stmt): Call it on THEN_CLAUSE and ELSE_CLAUSE. + PR c++/91428 - warn about std::is_constant_evaluated in if constexpr. * cp-tree.h (decl_in_std_namespace_p): Declare. * semantics.c (is_std_constant_evaluated_p): New. diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 8603e57..b61d86f 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -810,6 +810,18 @@ finish_else_clause (tree if_stmt) ELSE_CLAUSE (if_stmt) = pop_stmt_list (ELSE_CLAUSE (if_stmt)); } +/* Callback for cp_walk_tree to mark all {VAR,PARM}_DECLs in a tree as + read. */ + +static tree +maybe_mark_exp_read_r (tree *tp, int *, void *) +{ + tree t = *tp; + if (VAR_P (t) || TREE_CODE (t) == PARM_DECL) + mark_exp_read (t); + return NULL_TREE; +} + /* Finish an if-statement. */ void @@ -817,6 +829,16 @@ finish_if_stmt (tree if_stmt) { tree scope = IF_SCOPE (if_stmt); IF_SCOPE (if_stmt) = NULL; + if (IF_STMT_CONSTEXPR_P (if_stmt)) + { + /* Prevent various -Wunused warnings. We might not instantiate + either of these branches, so we would not mark the variables + used in that branch as read. */ + cp_walk_tree_without_duplicates (&THEN_CLAUSE (if_stmt), + maybe_mark_exp_read_r, NULL); + cp_walk_tree_without_duplicates (&ELSE_CLAUSE (if_stmt), + maybe_mark_exp_read_r, NULL); + } add_stmt (do_poplevel (scope)); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ade1a69..4c58780 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2019-08-27 Marek Polacek + PR c++/81676 - bogus -Wunused warnings in constexpr if. + * g++.dg/cpp1z/constexpr-if31.C: New test. + * g++.dg/cpp1z/constexpr-if32.C: New test. + PR c++/91428 - warn about std::is_constant_evaluated in if constexpr. * g++.dg/cpp2a/is-constant-evaluated9.C: New test. diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if31.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-if31.C new file mode 100644 index 0000000..02140cf --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-if31.C @@ -0,0 +1,79 @@ +// PR c++/81676 - bogus -Wunused warnings in constexpr if. +// { dg-do compile { target c++17 } } +// { dg-options "-Wall -Wextra" } + +template int +f1 (T v) +{ + T x = 0; + if constexpr(sizeof(T) == sizeof(int)) + return v + x; + else + return 0; +} + +template int +f2 (T v) // { dg-warning "unused parameter .v." } +{ + T x = 0; + if constexpr(sizeof(T) == sizeof(int)) + return x; + else + return 0; +} + +template int +f3 (T v) +{ + T x = 0; // { dg-warning "unused variable .x." } + if constexpr(sizeof(T) == sizeof(int)) + return v; + else + return 0; +} + +template int +f4 (T v) +{ + T x = 0; + if constexpr(sizeof(T) == sizeof(int)) + return 0; + else + return v + x; +} + +template int +f5 (T v) // { dg-warning "unused parameter .v." } +{ + T x = 0; + if constexpr(sizeof(T) == sizeof(int)) + return 0; + else + return x; +} + +template int +f6 (T v) +{ + T x = 0; // { dg-warning "unused variable .x." } + if constexpr(sizeof(T) == sizeof(int)) + return 0; + else + return v; +} + +int main() +{ + f1(0); + f1('a'); + f2(0); + f2('a'); + f3(0); + f3('a'); + f4(0); + f4('a'); + f5(0); + f5('a'); + f6(0); + f6('a'); +} diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if32.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-if32.C new file mode 100644 index 0000000..13a6039 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-if32.C @@ -0,0 +1,16 @@ +// PR c++/81676 - bogus -Wunused warnings in constexpr if. +// { dg-do compile { target c++17 } } +// { dg-options "-Wall -Wextra" } + +int main() +{ + auto f = [](auto a, auto b) { + if constexpr (sizeof(b) == 1) { + return a; + } else { + return b; + } + }; + + return f(1, 1) + f(1, 'a'); +} -- cgit v1.1 From 95ecbf4695a775853e4135d7dfda0be90ae8e80d Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Wed, 28 Aug 2019 08:39:47 +0200 Subject: Remove code leftover that has never been used. 2019-08-28 Martin Liska PR tree-optimization/90970 * builtins.c (check_access): Remove assignment to maxread as it hasn't been used since when it was introduced in r255755. From-SVN: r274983 --- gcc/ChangeLog | 6 ++++++ gcc/builtins.c | 5 ----- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1213e95..1948829 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-08-28 Martin Liska + + PR tree-optimization/90970 + * builtins.c (check_access): Remove assignment to maxread + as it hasn't been used since when it was introduced in r255755. + 2019-08-27 Martin Sebor PR tree-optimization/91567 diff --git a/gcc/builtins.c b/gcc/builtins.c index f902e24..0b25adc 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -3475,11 +3475,6 @@ check_access (tree exp, tree, tree, tree dstwrite, if (maxread) { get_size_range (maxread, range); - - /* Use the lower end for MAXREAD from now on. */ - if (range[0]) - maxread = range[0]; - if (range[0] && dstsize && tree_fits_uhwi_p (dstsize)) { location_t loc = tree_nonartificial_location (exp); -- cgit v1.1 From 5cb72d83bb375ea6ad2121daf4202605e7883d30 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 28 Aug 2019 12:12:11 +0200 Subject: re PR libgomp/91530 (Several libgomp.*/scan-* tests FAIL without avx_runtime) PR libgomp/91530 * config/i386/sse.md (vec_shl_, vec_shr_): Use V_128 iterator instead of VI_128. * testsuite/libgomp.c/scan-21.c: New test. * testsuite/libgomp.c/scan-22.c: New test. From-SVN: r274984 --- gcc/ChangeLog | 6 ++++++ gcc/config/i386/sse.md | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1948829..1ee26fc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-08-28 Jakub Jelinek + + PR libgomp/91530 + * config/i386/sse.md (vec_shl_, vec_shr_): Use + V_128 iterator instead of VI_128. + 2019-08-28 Martin Liska PR tree-optimization/90970 diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 7bef939..621b4db 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -12047,9 +12047,9 @@ (define_expand "vec_shl_" [(set (match_dup 3) (ashift:V1TI - (match_operand:VI_128 1 "register_operand") + (match_operand:V_128 1 "register_operand") (match_operand:SI 2 "const_0_to_255_mul_8_operand"))) - (set (match_operand:VI_128 0 "register_operand") (match_dup 4))] + (set (match_operand:V_128 0 "register_operand") (match_dup 4))] "TARGET_SSE2" { operands[1] = gen_lowpart (V1TImode, operands[1]); @@ -12060,9 +12060,9 @@ (define_expand "vec_shr_" [(set (match_dup 3) (lshiftrt:V1TI - (match_operand:VI_128 1 "register_operand") + (match_operand:V_128 1 "register_operand") (match_operand:SI 2 "const_0_to_255_mul_8_operand"))) - (set (match_operand:VI_128 0 "register_operand") (match_dup 4))] + (set (match_operand:V_128 0 "register_operand") (match_dup 4))] "TARGET_SSE2" { operands[1] = gen_lowpart (V1TImode, operands[1]); -- cgit v1.1 From 70cdb21e579191fe9f0f1d45e328908e59c0179e Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Wed, 28 Aug 2019 10:18:23 +0000 Subject: expr.c (expand_assignment): Handle misaligned DECLs. 2019-09-28 Bernd Edlinger Richard Biener * expr.c (expand_assignment): Handle misaligned DECLs. (expand_expr_real_1): Handle FUNCTION_DECL as unaligned. * function.c (assign_parm_adjust_stack_rtl): Check movmisalign optab too. (assign_parm_setup_stack): Allocate properly aligned stack slots. * varasm.c (build_constant_desc): Align constants of misaligned types. * config/arm/predicates.md (aligned_operand): New predicate. * config/arm/arm.md (movdi, movsi, movhi, movhf, movsf, movdf): Use aligned_operand to check restrictions on memory addresses. * config/arm/neon.md (movti, mov, mov): Likewise. * config/arm/vec-common.md (mov): Likewise. Co-Authored-By: Richard Biener From-SVN: r274986 --- gcc/ChangeLog | 15 +++++++++++++++ gcc/config/arm/arm.md | 12 ++++++++++++ gcc/config/arm/neon.md | 6 ++++++ gcc/config/arm/predicates.md | 4 ++++ gcc/config/arm/vec-common.md | 2 ++ gcc/expr.c | 13 +++++++++++-- gcc/function.c | 15 +++++++++++++-- gcc/varasm.c | 11 ++++++++++- 8 files changed, 73 insertions(+), 5 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1ee26fc..b9b9da9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2019-09-28 Bernd Edlinger + Richard Biener + + * expr.c (expand_assignment): Handle misaligned DECLs. + (expand_expr_real_1): Handle FUNCTION_DECL as unaligned. + * function.c (assign_parm_adjust_stack_rtl): Check movmisalign optab + too. + (assign_parm_setup_stack): Allocate properly aligned stack slots. + * varasm.c (build_constant_desc): Align constants of misaligned types. + * config/arm/predicates.md (aligned_operand): New predicate. + * config/arm/arm.md (movdi, movsi, movhi, movhf, movsf, movdf): Use + aligned_operand to check restrictions on memory addresses. + * config/arm/neon.md (movti, mov, mov): Likewise. + * config/arm/vec-common.md (mov): Likewise. + 2019-08-28 Jakub Jelinek PR libgomp/91530 diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index f138d31..0be7a01 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -5231,6 +5231,8 @@ (match_operand:DI 1 "general_operand"))] "TARGET_EITHER" " + gcc_checking_assert (aligned_operand (operands[0], DImode)); + gcc_checking_assert (aligned_operand (operands[1], DImode)); if (can_create_pseudo_p ()) { if (!REG_P (operands[0])) @@ -5407,6 +5409,8 @@ { rtx base, offset, tmp; + gcc_checking_assert (aligned_operand (operands[0], SImode)); + gcc_checking_assert (aligned_operand (operands[1], SImode)); if (TARGET_32BIT || TARGET_HAVE_MOVT) { /* Everything except mem = const or mem = mem can be done easily. */ @@ -5896,6 +5900,8 @@ (match_operand:HI 1 "general_operand"))] "TARGET_EITHER" " + gcc_checking_assert (aligned_operand (operands[0], HImode)); + gcc_checking_assert (aligned_operand (operands[1], HImode)); if (TARGET_ARM) { if (can_create_pseudo_p ()) @@ -6305,6 +6311,8 @@ (match_operand:HF 1 "general_operand"))] "TARGET_EITHER" " + gcc_checking_assert (aligned_operand (operands[0], HFmode)); + gcc_checking_assert (aligned_operand (operands[1], HFmode)); if (TARGET_32BIT) { if (MEM_P (operands[0])) @@ -6369,6 +6377,8 @@ (match_operand:SF 1 "general_operand"))] "TARGET_EITHER" " + gcc_checking_assert (aligned_operand (operands[0], SFmode)); + gcc_checking_assert (aligned_operand (operands[1], SFmode)); if (TARGET_32BIT) { if (MEM_P (operands[0])) @@ -6464,6 +6474,8 @@ (match_operand:DF 1 "general_operand"))] "TARGET_EITHER" " + gcc_checking_assert (aligned_operand (operands[0], DFmode)); + gcc_checking_assert (aligned_operand (operands[1], DFmode)); if (TARGET_32BIT) { if (MEM_P (operands[0])) diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md index 0c1ee74..a5aa8d6 100644 --- a/gcc/config/arm/neon.md +++ b/gcc/config/arm/neon.md @@ -127,6 +127,8 @@ (match_operand:TI 1 "general_operand"))] "TARGET_NEON" { + gcc_checking_assert (aligned_operand (operands[0], TImode)); + gcc_checking_assert (aligned_operand (operands[1], TImode)); if (can_create_pseudo_p ()) { if (!REG_P (operands[0])) @@ -139,6 +141,8 @@ (match_operand:VSTRUCT 1 "general_operand"))] "TARGET_NEON" { + gcc_checking_assert (aligned_operand (operands[0], mode)); + gcc_checking_assert (aligned_operand (operands[1], mode)); if (can_create_pseudo_p ()) { if (!REG_P (operands[0])) @@ -151,6 +155,8 @@ (match_operand:VH 1 "s_register_operand"))] "TARGET_NEON" { + gcc_checking_assert (aligned_operand (operands[0], mode)); + gcc_checking_assert (aligned_operand (operands[1], mode)); if (can_create_pseudo_p ()) { if (!REG_P (operands[0])) diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md index 59dc2e8..983faac 100644 --- a/gcc/config/arm/predicates.md +++ b/gcc/config/arm/predicates.md @@ -697,3 +697,7 @@ (ior (and (match_code "symbol_ref") (match_test "!arm_is_long_call_p (SYMBOL_REF_DECL (op))")) (match_operand 0 "s_register_operand"))) + +(define_special_predicate "aligned_operand" + (ior (not (match_code "mem")) + (match_test "MEM_ALIGN (op) >= GET_MODE_ALIGNMENT (mode)"))) diff --git a/gcc/config/arm/vec-common.md b/gcc/config/arm/vec-common.md index 99a430e..33ff562 100644 --- a/gcc/config/arm/vec-common.md +++ b/gcc/config/arm/vec-common.md @@ -26,6 +26,8 @@ "TARGET_NEON || (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (mode))" { + gcc_checking_assert (aligned_operand (operands[0], mode)); + gcc_checking_assert (aligned_operand (operands[1], mode)); if (can_create_pseudo_p ()) { if (!REG_P (operands[0])) diff --git a/gcc/expr.c b/gcc/expr.c index 5ca0e20..022b571 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -5001,9 +5001,10 @@ expand_assignment (tree to, tree from, bool nontemporal) /* Handle misaligned stores. */ mode = TYPE_MODE (TREE_TYPE (to)); if ((TREE_CODE (to) == MEM_REF - || TREE_CODE (to) == TARGET_MEM_REF) + || TREE_CODE (to) == TARGET_MEM_REF + || DECL_P (to)) && mode != BLKmode - && !mem_ref_refers_to_non_mem_p (to) + && (DECL_P (to) || !mem_ref_refers_to_non_mem_p (to)) && ((align = get_object_alignment (to)) < GET_MODE_ALIGNMENT (mode)) && (((icode = optab_handler (movmisalign_optab, mode)) @@ -10795,6 +10796,14 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, MEM_VOLATILE_P (op0) = 1; } + if (MEM_P (op0) && TREE_CODE (tem) == FUNCTION_DECL) + { + if (op0 == orig_op0) + op0 = copy_rtx (op0); + + set_mem_align (op0, BITS_PER_UNIT); + } + /* In cases where an aligned union has an unaligned object as a field, we might be extracting a BLKmode value from an integer-mode (e.g., SImode) object. Handle this case diff --git a/gcc/function.c b/gcc/function.c index 05241a3..751d2de3 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -2807,8 +2807,10 @@ assign_parm_adjust_stack_rtl (struct assign_parm_data_one *data) stack slot, if we need one. */ if (stack_parm && ((GET_MODE_ALIGNMENT (data->nominal_mode) > MEM_ALIGN (stack_parm) - && targetm.slow_unaligned_access (data->nominal_mode, - MEM_ALIGN (stack_parm))) + && ((optab_handler (movmisalign_optab, data->nominal_mode) + != CODE_FOR_nothing) + || targetm.slow_unaligned_access (data->nominal_mode, + MEM_ALIGN (stack_parm)))) || (data->nominal_type && TYPE_ALIGN (data->nominal_type) > MEM_ALIGN (stack_parm) && MEM_ALIGN (stack_parm) < PREFERRED_STACK_BOUNDARY))) @@ -3461,11 +3463,20 @@ assign_parm_setup_stack (struct assign_parm_data_all *all, tree parm, int align = STACK_SLOT_ALIGNMENT (data->arg.type, GET_MODE (data->entry_parm), TYPE_ALIGN (data->arg.type)); + if (align < (int)GET_MODE_ALIGNMENT (GET_MODE (data->entry_parm)) + && ((optab_handler (movmisalign_optab, + GET_MODE (data->entry_parm)) + != CODE_FOR_nothing) + || targetm.slow_unaligned_access (GET_MODE (data->entry_parm), + align))) + align = GET_MODE_ALIGNMENT (GET_MODE (data->entry_parm)); data->stack_parm = assign_stack_local (GET_MODE (data->entry_parm), GET_MODE_SIZE (GET_MODE (data->entry_parm)), align); + align = MEM_ALIGN (data->stack_parm); set_mem_attributes (data->stack_parm, parm, 1); + set_mem_align (data->stack_parm, align); } dest = validize_mem (copy_rtx (data->stack_parm)); diff --git a/gcc/varasm.c b/gcc/varasm.c index ae25f4d..a7c2252 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -47,6 +47,7 @@ along with GCC; see the file COPYING3. If not see #include "stmt.h" #include "expr.h" #include "expmed.h" +#include "optabs.h" #include "output.h" #include "langhooks.h" #include "debug.h" @@ -3386,7 +3387,15 @@ build_constant_desc (tree exp) if (TREE_CODE (exp) == STRING_CST) SET_DECL_ALIGN (decl, targetm.constant_alignment (exp, DECL_ALIGN (decl))); else - align_variable (decl, 0); + { + align_variable (decl, 0); + if (DECL_ALIGN (decl) < GET_MODE_ALIGNMENT (DECL_MODE (decl)) + && ((optab_handler (movmisalign_optab, DECL_MODE (decl)) + != CODE_FOR_nothing) + || targetm.slow_unaligned_access (DECL_MODE (decl), + DECL_ALIGN (decl)))) + SET_DECL_ALIGN (decl, GET_MODE_ALIGNMENT (DECL_MODE (decl))); + } /* Now construct the SYMBOL_REF and the MEM. */ if (use_object_blocks_p ()) -- cgit v1.1 From 0b778f9f4a9606cff7c9b9b8a923e17f291c527a Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Wed, 28 Aug 2019 10:20:44 +0000 Subject: re PR middle-end/89544 (Argument marshalling incorrectly assumes stack slots are naturally aligned.) 2019-08-28 Bernd Edlinger PR middle-end/89544 * gcc.target/arm/unaligned-argument-3.c: New test. From-SVN: r274987 --- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.target/arm/unaligned-argument-3.c | 14 ++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 gcc/testsuite/gcc.target/arm/unaligned-argument-3.c (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4c58780..333fe3c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-08-28 Bernd Edlinger + + PR middle-end/89544 + * gcc.target/arm/unaligned-argument-3.c: New test. + 2019-08-27 Marek Polacek PR c++/81676 - bogus -Wunused warnings in constexpr if. diff --git a/gcc/testsuite/gcc.target/arm/unaligned-argument-3.c b/gcc/testsuite/gcc.target/arm/unaligned-argument-3.c new file mode 100644 index 0000000..2543038 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/unaligned-argument-3.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target arm_arm_ok } */ +/* { dg-options "-marm -mno-unaligned-access -O3" } */ + +typedef int __attribute__((aligned(1))) s; + +void x(char*, s*); +void f(char a, s f) +{ + x(&a, &f); +} + +/* { dg-final { scan-assembler-times "str\t\[^\\n\]*\\\[sp\\\]" 1 } } */ +/* { dg-final { scan-assembler-times "str\t\[^\\n\]*\\\[sp, #3\\\]" 0 } } */ -- cgit v1.1 From 13668284c944a88ee0bf50922fbd0253d586c523 Mon Sep 17 00:00:00 2001 From: Mark Eggleston Date: Wed, 28 Aug 2019 10:21:31 +0000 Subject: Stated standards in documentation Correct the stated standards in documentation and for intrinsics and specific intrinsics. In C_SIZEOF the printed value is T not .TRUE.. In IPARITY example wrap BOZ constants in calls to INT. From-SVN: r274988 --- gcc/fortran/ChangeLog | 7 + gcc/fortran/intrinsic.texi | 339 +++++++++++++++++++++++---------------------- 2 files changed, 178 insertions(+), 168 deletions(-) (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 4ef8106..6b760ce 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,10 @@ +2019-08-28 Mark Eggleston + + * intrinsics.text: Corrected stated standard for intrinsics + and specific intrinsics where necessary. Also in C_SIZEOF the + printed value is T not .TRUE.. In IPARITY example wrap BOZ + constants in calls to INT. + 2019-08-27 Harald Anlauf PR fortran/91496 diff --git a/gcc/fortran/intrinsic.texi b/gcc/fortran/intrinsic.texi index 61f533e..7e01e94 100644 --- a/gcc/fortran/intrinsic.texi +++ b/gcc/fortran/intrinsic.texi @@ -657,7 +657,7 @@ This function is for compatibility only and should be avoided in favor of standard constructs wherever possible. @item @emph{Standard}: -GNU Extension, enabled with @option{-fdec-math} +GNU extension, enabled with @option{-fdec-math} @item @emph{Class}: Elemental function @@ -687,8 +687,8 @@ end program test_acosd @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{ACOSD(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU Extension -@item @code{DACOSD(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU Extension +@item @code{ACOSD(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU extension +@item @code{DACOSD(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU extension @end multitable @item @emph{See also}: @@ -811,7 +811,7 @@ end program test_adjustl Spaces are inserted at the start of the string as needed. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Elemental function @@ -892,7 +892,7 @@ end program test_aimag @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{AIMAG(Z)} @tab @code{COMPLEX Z} @tab @code{REAL} @tab GNU extension +@item @code{AIMAG(Z)} @tab @code{COMPLEX Z} @tab @code{REAL} @tab Fortran 77 and later @item @code{DIMAG(Z)} @tab @code{COMPLEX(8) Z} @tab @code{REAL(8)} @tab GNU extension @item @code{IMAG(Z)} @tab @code{COMPLEX Z} @tab @code{REAL} @tab GNU extension @item @code{IMAGPART(Z)} @tab @code{COMPLEX Z} @tab @code{REAL} @tab GNU extension @@ -1022,7 +1022,7 @@ after 3 seconds. in the array along dimension @var{DIM}. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Transformational function @@ -1088,7 +1088,7 @@ end program test_all status of @var{ARRAY} and @var{SCALAR}, respectively. @item @emph{Standard}: -Fortran 95 and later. Note, the @code{SCALAR=} keyword and allocatable +Fortran 90 and later. Note, the @code{SCALAR=} keyword and allocatable scalar entities are available in Fortran 2003 and later. @item @emph{Class}: @@ -1251,7 +1251,7 @@ end program test_anint @var{MASK} along dimension @var{DIM} are @code{.TRUE.}. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Transformational function @@ -1377,7 +1377,7 @@ This function is for compatibility only and should be avoided in favor of standard constructs wherever possible. @item @emph{Standard}: -GNU Extension, enabled with @option{-fdec-math}. +GNU extension, enabled with @option{-fdec-math}. @item @emph{Class}: Elemental function @@ -1407,8 +1407,8 @@ end program test_asind @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{ASIND(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU Extension -@item @code{DASIND(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU Extension +@item @code{ASIND(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU extension +@item @code{DASIND(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU extension @end multitable @item @emph{See also}: @@ -1485,7 +1485,7 @@ Inverse function: @gol @var{POINTER} or if @var{POINTER} is associated with the target @var{TARGET}. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Inquiry function @@ -1578,7 +1578,7 @@ Elemental function @multitable @columnfractions .15 .70 @item @var{X} @tab The type shall be @code{REAL} or @code{COMPLEX}; if @var{Y} is present, @var{X} shall be REAL. -@item @var{Y} shall be of the same type and kind as @var{X}. +@item @var{Y} @tab The type and kind type parameter shall be the same as @var{X}. @end multitable @item @emph{Return value}: @@ -1628,7 +1628,7 @@ This function is for compatibility only and should be avoided in favor of standard constructs wherever possible. @item @emph{Standard}: -GNU Extension, enabled with @option{-fdec-math}. +GNU extension, enabled with @option{-fdec-math}. @item @emph{Class}: Elemental function @@ -1643,7 +1643,7 @@ Elemental function @multitable @columnfractions .15 .70 @item @var{X} @tab The type shall be @code{REAL} or @code{COMPLEX}; if @var{Y} is present, @var{X} shall be REAL. -@item @var{Y} shall be of the same type and kind as @var{X}. +@item @var{Y} @tab The type and kind type parameter shall be the same as @var{X}. @end multitable @item @emph{Return value}: @@ -1664,8 +1664,8 @@ end program test_atand @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{ATAND(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU Extension -@item @code{DATAND(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU Extension +@item @code{ATAND(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU extension +@item @code{DATAND(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU extension @end multitable @item @emph{See also}: @@ -1738,7 +1738,6 @@ Alias: @gol @ref{ATAN} @gol Degrees function: @gol @ref{ATAN2D} - @end table @@ -1761,7 +1760,7 @@ This function is for compatibility only and should be avoided in favor of standard constructs wherever possible. @item @emph{Standard}: -GNU Extension, enabled with @option{-fdec-math}. +GNU extension, enabled with @option{-fdec-math}. @item @emph{Class}: Elemental function @@ -1798,8 +1797,8 @@ end program test_atan2d @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{ATAN2D(X, Y)} @tab @code{REAL(4) X, Y} @tab @code{REAL(4)} @tab GNU Extension -@item @code{DATAN2D(X, Y)} @tab @code{REAL(8) X, Y} @tab @code{REAL(8)} @tab GNU Extension +@item @code{ATAN2D(X, Y)} @tab @code{REAL(4) X, Y} @tab @code{REAL(4)} @tab GNU extension +@item @code{DATAN2D(X, Y)} @tab @code{REAL(8) X, Y} @tab @code{REAL(8)} @tab GNU extension @end multitable @item @emph{See also}: @@ -2483,7 +2482,7 @@ execution continues normally afterwards. The backtrace information is printed to the unit corresponding to @code{ERROR_UNIT} in @code{ISO_FORTRAN_ENV}. @item @emph{Standard}: -GNU Extension +GNU extension @item @emph{Class}: Subroutine @@ -2910,7 +2909,7 @@ represented by the type of @var{I}. The result of @code{BIT_SIZE(I)} is independent of the actual value of @var{I}. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Inquiry function @@ -3027,7 +3026,7 @@ The return value is of type @code{LOGICAL} and of the default kind. in @var{I} is set. The counting of the bits starts at 0. @item @emph{Standard}: -Fortran 95 and later, has overloads that are GNU extensions +Fortran 90 and later, has overloads that are GNU extensions @item @emph{Class}: Elemental function @@ -3060,7 +3059,7 @@ end program test_btest @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{BTEST(I,POS)} @tab @code{INTEGER I,POS} @tab @code{LOGICAL} @tab F95 and later +@item @code{BTEST(I,POS)} @tab @code{INTEGER I,POS} @tab @code{LOGICAL} @tab Fortran 95 and later @item @code{BBTEST(I,POS)} @tab @code{INTEGER(1) I,POS} @tab @code{LOGICAL(1)} @tab GNU extension @item @code{BITEST(I,POS)} @tab @code{INTEGER(2) I,POS} @tab @code{LOGICAL(2)} @tab GNU extension @item @code{BJTEST(I,POS)} @tab @code{INTEGER(4) I,POS} @tab @code{LOGICAL(4)} @tab GNU extension @@ -3380,7 +3379,7 @@ the sizes of the data pointed to by these components. print *, (c_sizeof(s)/c_sizeof(r) == 5) end @end smallexample -The example will print @code{.TRUE.} unless you are using a platform +The example will print @code{T} unless you are using a platform where default @code{REAL} variables are unusually padded. @item @emph{See also}: @@ -3477,7 +3476,7 @@ end program test_char @item @emph{Specific names}: @multitable @columnfractions .18 .18 .24 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{CHAR(I)} @tab @code{INTEGER I} @tab @code{CHARACTER(LEN=1)} @tab F77 and later +@item @code{CHAR(I)} @tab @code{INTEGER I} @tab @code{CHARACTER(LEN=1)} @tab Fortran 77 and later @end multitable @item @emph{Note}: @@ -4046,7 +4045,7 @@ Inquiry function of the module @code{ISO_FORTRAN_ENV} @code{STR = COMPILER_OPTIONS()} @item @emph{Arguments}: -None. +None @item @emph{Return value}: The return value is a default-kind string with system-dependent length. @@ -4090,7 +4089,7 @@ Inquiry function of the module @code{ISO_FORTRAN_ENV} @code{STR = COMPILER_VERSION()} @item @emph{Arguments}: -None. +None @item @emph{Return value}: The return value is a default-kind string with system-dependent length. @@ -4175,7 +4174,7 @@ end program test_complex then the result is @code{(x, -y)} @item @emph{Standard}: -Fortran 77 and later, has overloads that are GNU extensions +Fortran 77 and later, has an overload that is a GNU extension @item @emph{Class}: Elemental function @@ -4206,7 +4205,6 @@ end program test_conjg @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{CONJG(Z)} @tab @code{COMPLEX Z} @tab @code{COMPLEX} @tab GNU extension @item @code{DCONJG(Z)} @tab @code{COMPLEX(8) Z} @tab @code{COMPLEX(8)} @tab GNU extension @end multitable @end table @@ -4292,7 +4290,7 @@ This function is for compatibility only and should be avoided in favor of standard constructs wherever possible. @item @emph{Standard}: -GNU Extension, enabled with @option{-fdec-math}. +GNU extension, enabled with @option{-fdec-math}. @item @emph{Class}: Elemental function @@ -4322,9 +4320,9 @@ end program test_cosd @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{COSD(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU Extension -@item @code{DCOSD(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU Extension -@item @code{CCOSD(X)} @tab @code{COMPLEX(4) X} @tab @code{COMPLEX(4)} @tab GNU Extension +@item @code{COSD(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU extension +@item @code{DCOSD(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU extension +@item @code{CCOSD(X)} @tab @code{COMPLEX(4) X} @tab @code{COMPLEX(4)} @tab GNU extension @item @code{ZCOSD(X)} @tab @code{COMPLEX(8) X} @tab @code{COMPLEX(8)} @tab GNU extension @item @code{CDCOSD(X)} @tab @code{COMPLEX(8) X} @tab @code{COMPLEX(8)} @tab GNU extension @end multitable @@ -4408,7 +4406,7 @@ This function is for compatibility only and should be avoided in favor of standard constructs wherever possible. @item @emph{Standard}: -GNU Extension, enabled with @option{-fdec-math}. +GNU extension, enabled with @option{-fdec-math}. @item @emph{Class}: Elemental function @@ -4435,8 +4433,8 @@ end program test_cotan @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{COTAN(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU Extension -@item @code{DCOTAN(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU Extension +@item @code{COTAN(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU extension +@item @code{DCOTAN(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU extension @end multitable @item @emph{See also}: @@ -4461,7 +4459,7 @@ Degrees function: @gol @code{COSD(x)} divided by @code{SIND(x)}, or @code{1 / TAND(x)}. @item @emph{Standard}: -GNU Extension, enabled with @option{-fdec-math}. +GNU extension, enabled with @option{-fdec-math}. This function is for compatibility only and should be avoided in favor of standard constructs wherever possible. @@ -4491,8 +4489,8 @@ end program test_cotand @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{COTAND(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU Extension -@item @code{DCOTAND(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU Extension +@item @code{COTAND(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU extension +@item @code{DCOTAND(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU extension @end multitable @item @emph{See also}: @@ -4521,7 +4519,7 @@ If the array has zero size, or all of the elements of @var{MASK} are @code{.FALSE.}, then the result is @code{0}. @item @emph{Standard}: -Fortran 95 and later, with @var{KIND} argument Fortran 2003 and later +Fortran 90 and later, with @var{KIND} argument Fortran 2003 and later @item @emph{Class}: Transformational function @@ -4647,7 +4645,7 @@ sections of @var{ARRAY} along the given dimension are shifted. Elements shifted out one end of each rank one section are shifted back in the other end. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Transformational function @@ -4778,7 +4776,7 @@ Unavailable time and date parameters return blanks. @end multitable @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Subroutine @@ -4928,7 +4926,7 @@ model representation of @var{X}. For example, on a system using a 32-bit floating point representation, a default real number would likely return 24. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Inquiry function @@ -5032,7 +5030,7 @@ is @code{SUM(CONJG(VECTOR_A)*VECTOR_B)}. If the vectors are @code{LOGICAL}, the result is @code{ANY(VECTOR_A .AND. VECTOR_B)}. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Transformational function @@ -5362,7 +5360,7 @@ following are copied in depending on the type of @var{ARRAY}. @end multitable @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Transformational function @@ -5411,7 +5409,7 @@ end program test_eoshift as @var{X} such that @math{1 + E > 1}. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Inquiry function @@ -5888,7 +5886,7 @@ end program test_exp is zero the value returned is zero. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Elemental function @@ -6506,7 +6504,7 @@ END PROGRAM representation of @code{X}. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Elemental function @@ -6803,8 +6801,7 @@ end program test_gamma @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{GAMMA(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU Extension -@item @code{DGAMMA(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU Extension +@item @code{DGAMMA(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU extension @end multitable @item @emph{See also}: @@ -7464,7 +7461,7 @@ be obtained, or to a blank string otherwise. the model of the type of @code{X}. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Inquiry function @@ -7660,7 +7657,7 @@ END PROGRAM Bitwise logical @code{AND}. @item @emph{Standard}: -Fortran 95 and later, has overloads that are GNU extensions +Fortran 90 and later, with boz-literal-constant Fortran 2008 and later, has overloads that are GNU extensions @item @emph{Class}: Elemental function @@ -7694,7 +7691,7 @@ END PROGRAM @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{IAND(A)} @tab @code{INTEGER A} @tab @code{INTEGER} @tab Fortran 95 and later +@item @code{IAND(A)} @tab @code{INTEGER A} @tab @code{INTEGER} @tab Fortran 90 and later @item @code{BIAND(A)} @tab @code{INTEGER(1) A} @tab @code{INTEGER(1)} @tab GNU extension @item @code{IIAND(A)} @tab @code{INTEGER(2) A} @tab @code{INTEGER(2)} @tab GNU extension @item @code{JIAND(A)} @tab @code{INTEGER(4) A} @tab @code{INTEGER(4)} @tab GNU extension @@ -7801,7 +7798,7 @@ Function @code{RESULT = IARGC()} @item @emph{Arguments}: -None. +None @item @emph{Return value}: The number of command line arguments, type @code{INTEGER(4)}. @@ -7836,7 +7833,7 @@ Fortran 2003 functions and subroutines: @gol @var{POS} set to zero. @item @emph{Standard}: -Fortran 95 and later, has overloads that are GNU extensions +Fortran 90 and later, has overloads that are GNU extensions @item @emph{Class}: Elemental function @@ -7857,7 +7854,7 @@ The return value is of type @code{INTEGER} and of the same kind as @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{IBCLR(A)} @tab @code{INTEGER A} @tab @code{INTEGER} @tab Fortran 95 and later +@item @code{IBCLR(A)} @tab @code{INTEGER A} @tab @code{INTEGER} @tab Fortran 90 and later @item @code{BBCLR(A)} @tab @code{INTEGER(1) A} @tab @code{INTEGER(1)} @tab GNU extension @item @code{IIBCLR(A)} @tab @code{INTEGER(2) A} @tab @code{INTEGER(2)} @tab GNU extension @item @code{JIBCLR(A)} @tab @code{INTEGER(4) A} @tab @code{INTEGER(4)} @tab GNU extension @@ -7894,7 +7891,7 @@ zeroed. The value of @code{POS+LEN} must be less than or equal to the value @code{BIT_SIZE(I)}. @item @emph{Standard}: -Fortran 95 and later, has overloads that are GNU extensions +Fortran 90 and later, has overloads that are GNU extensions @item @emph{Class}: Elemental function @@ -7916,7 +7913,7 @@ The return value is of type @code{INTEGER} and of the same kind as @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{IBITS(A)} @tab @code{INTEGER A} @tab @code{INTEGER} @tab Fortran 95 and later +@item @code{IBITS(A)} @tab @code{INTEGER A} @tab @code{INTEGER} @tab Fortran 90 and later @item @code{BBITS(A)} @tab @code{INTEGER(1) A} @tab @code{INTEGER(1)} @tab GNU extension @item @code{IIBITS(A)} @tab @code{INTEGER(2) A} @tab @code{INTEGER(2)} @tab GNU extension @item @code{JIBITS(A)} @tab @code{INTEGER(4) A} @tab @code{INTEGER(4)} @tab GNU extension @@ -7949,7 +7946,7 @@ The return value is of type @code{INTEGER} and of the same kind as @var{POS} set to one. @item @emph{Standard}: -Fortran 95 and later, has overloads that are GNU extensions +Fortran 90 and later, has overloads that are GNU extensions @item @emph{Class}: Elemental function @@ -7970,7 +7967,7 @@ The return value is of type @code{INTEGER} and of the same kind as @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{IBSET(A)} @tab @code{INTEGER A} @tab @code{INTEGER} @tab Fortran 95 and later +@item @code{IBSET(A)} @tab @code{INTEGER A} @tab @code{INTEGER} @tab Fortran 90 and later @item @code{BBSET(A)} @tab @code{INTEGER(1) A} @tab @code{INTEGER(1)} @tab GNU extension @item @code{IIBSET(A)} @tab @code{INTEGER(2) A} @tab @code{INTEGER(2)} @tab GNU extension @item @code{JIBSET(A)} @tab @code{INTEGER(4) A} @tab @code{INTEGER(4)} @tab GNU extension @@ -8001,7 +7998,7 @@ The correspondence between characters and their codes is not necessarily the same across different GNU Fortran implementations. @item @emph{Standard}: -Fortran 95 and later, with @var{KIND} argument Fortran 2003 and later +Fortran 77 and later, with @var{KIND} argument Fortran 2003 and later @item @emph{Class}: Elemental function @@ -8133,7 +8130,7 @@ end program test_idate @var{J}. @item @emph{Standard}: -Fortran 95 and later, has overloads that are GNU extensions +Fortran 90 and later, with boz-literal-constant Fortran 2008 and later, has overloads that are GNU extensions @item @emph{Class}: Elemental function @@ -8158,7 +8155,7 @@ type parameter of the other argument as-if a call to @ref{INT} occurred. @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{IEOR(A)} @tab @code{INTEGER A} @tab @code{INTEGER} @tab Fortran 95 and later +@item @code{IEOR(A)} @tab @code{INTEGER A} @tab @code{INTEGER} @tab Fortran 90 and later @item @code{BIEOR(A)} @tab @code{INTEGER(1) A} @tab @code{INTEGER(1)} @tab GNU extension @item @code{IIEOR(A)} @tab @code{INTEGER(2) A} @tab @code{INTEGER(2)} @tab GNU extension @item @code{JIEOR(A)} @tab @code{INTEGER(4) A} @tab @code{INTEGER(4)} @tab GNU extension @@ -8196,7 +8193,7 @@ Function @code{RESULT = IERRNO()} @item @emph{Arguments}: -None. +None @item @emph{Return value}: The return value is of type @code{INTEGER} and of the default integer @@ -8317,7 +8314,7 @@ The return value is of type @code{INTEGER} and of kind @var{KIND}. If Convert to integer type @item @emph{Standard}: -Fortran 77 and later +Fortran 77 and later, with boz-literal-constant Fortran 2008 and later. @item @emph{Class}: Elemental function @@ -8328,7 +8325,7 @@ Elemental function @item @emph{Arguments}: @multitable @columnfractions .15 .70 @item @var{A} @tab Shall be of type @code{INTEGER}, -@code{REAL}, or @code{COMPLEX}. +@code{REAL}, or @code{COMPLEX} or or a boz-literal-constant. @item @var{KIND} @tab (Optional) An @code{INTEGER} initialization expression indicating the kind parameter of the result. @end multitable @@ -8463,7 +8460,7 @@ The return value is a @code{INTEGER(8)} variable. @var{J}. @item @emph{Standard}: -Fortran 95 and later, has overloads that are GNU extensions +Fortran 90 and later, with boz-literal-constant Fortran 2008 and later, has overloads that are GNU extensions @item @emph{Class}: Elemental function @@ -8488,7 +8485,7 @@ type parameter of the other argument as-if a call to @ref{INT} occurred. @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{IOR(A)} @tab @code{INTEGER A} @tab @code{INTEGER} @tab Fortran 95 and later +@item @code{IOR(A)} @tab @code{INTEGER A} @tab @code{INTEGER} @tab Fortran 90 and later @item @code{BIOR(A)} @tab @code{INTEGER(1) A} @tab @code{INTEGER(1)} @tab GNU extension @item @code{IIOR(A)} @tab @code{INTEGER(2) A} @tab @code{INTEGER(2)} @tab GNU extension @item @code{JIOR(A)} @tab @code{INTEGER(4) A} @tab @code{INTEGER(4)} @tab GNU extension @@ -8553,8 +8550,8 @@ dimension @var{DIM} dropped is returned. PROGRAM test_iparity INTEGER(1) :: a(2) - a(1) = b'00100100' - a(2) = b'01101010' + a(1) = int(b'00100100', 1) + a(2) = int(b'01101010', 1) ! prints 01001110 PRINT '(b8.8)', IPARITY(a) @@ -8821,7 +8818,7 @@ value is undefined. Bits shifted out from the left end or right end are lost; zeros are shifted in from the opposite end. @item @emph{Standard}: -Fortran 95 and later, has overloads that are GNU extensions +Fortran 90 and later, has overloads that are GNU extensions @item @emph{Class}: Elemental function @@ -8842,7 +8839,7 @@ The return value is of type @code{INTEGER} and of the same kind as @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{ISHFT(A)} @tab @code{INTEGER A} @tab @code{INTEGER} @tab Fortran 95 and later +@item @code{ISHFT(A)} @tab @code{INTEGER A} @tab @code{INTEGER} @tab Fortran 90 and later @item @code{BSHFT(A)} @tab @code{INTEGER(1) A} @tab @code{INTEGER(1)} @tab GNU extension @item @code{IISHFT(A)} @tab @code{INTEGER(2) A} @tab @code{INTEGER(2)} @tab GNU extension @item @code{JISHFT(A)} @tab @code{INTEGER(4) A} @tab @code{INTEGER(4)} @tab GNU extension @@ -8876,7 +8873,7 @@ a right shift. The absolute value of @var{SHIFT} must be less than equivalent to @code{BIT_SIZE(I)}. @item @emph{Standard}: -Fortran 95 and later, has overloads that are GNU extensions +Fortran 90 and later, has overloads that are GNU extensions @item @emph{Class}: Elemental function @@ -8900,7 +8897,7 @@ The return value is of type @code{INTEGER} and of the same kind as @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{ISHFTC(A)} @tab @code{INTEGER A} @tab @code{INTEGER} @tab Fortran 95 and later +@item @code{ISHFTC(A)} @tab @code{INTEGER A} @tab @code{INTEGER} @tab Fortran 90 and later @item @code{BSHFTC(A)} @tab @code{INTEGER(1) A} @tab @code{INTEGER(1)} @tab GNU extension @item @code{IISHFTC(A)} @tab @code{INTEGER(2) A} @tab @code{INTEGER(2)} @tab GNU extension @item @code{JISHFTC(A)} @tab @code{INTEGER(4) A} @tab @code{INTEGER(4)} @tab GNU extension @@ -9023,6 +9020,9 @@ however, only one form can be used in any given program unit. @item @emph{Standard}: GNU extension +@item @emph{Standard}: +GNU extension + @item @emph{Class}: Subroutine, function @@ -9071,7 +9071,8 @@ Inquiry function @item @emph{Arguments}: @multitable @columnfractions .15 .70 @item @var{X} @tab Shall be of type @code{LOGICAL}, @code{INTEGER}, -@code{REAL}, @code{COMPLEX} or @code{CHARACTER}. +@code{REAL}, @code{COMPLEX} or @code{CHARACTER}. It may be scalar or +array valued. @end multitable @item @emph{Return value}: @@ -9103,7 +9104,7 @@ end program test_kind Returns the lower bounds of an array, or a single lower bound along the @var{DIM} dimension. @item @emph{Standard}: -Fortran 95 and later, with @var{KIND} argument Fortran 2003 and later +Fortran 90 and later, with @var{KIND} argument Fortran 2003 and later @item @emph{Class}: Inquiry function @@ -9279,7 +9280,7 @@ The return value is of type @code{INTEGER} and of kind @var{KIND}. If Returns the length of a character string, ignoring any trailing blanks. @item @emph{Standard}: -Fortran 95 and later, with @var{KIND} argument Fortran 2003 and later +Fortran 90 and later, with @var{KIND} argument Fortran 2003 and later @item @emph{Class}: Elemental function @@ -9662,7 +9663,7 @@ end program test_loc logarithm to the base @math{e}. @item @emph{Standard}: -Fortran 77 and later +Fortran 77 and later, has GNU extensions @item @emph{Class}: Elemental function @@ -9695,11 +9696,11 @@ end program test_log @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{ALOG(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab f95, gnu -@item @code{DLOG(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab f95, gnu -@item @code{CLOG(X)} @tab @code{COMPLEX(4) X} @tab @code{COMPLEX(4)} @tab f95, gnu -@item @code{ZLOG(X)} @tab @code{COMPLEX(8) X} @tab @code{COMPLEX(8)} @tab f95, gnu -@item @code{CDLOG(X)} @tab @code{COMPLEX(8) X} @tab @code{COMPLEX(8)} @tab f95, gnu +@item @code{ALOG(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab Fortran 77 or later +@item @code{DLOG(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab Fortran 77 or later +@item @code{CLOG(X)} @tab @code{COMPLEX(4) X} @tab @code{COMPLEX(4)} @tab Fortran 77 or later +@item @code{ZLOG(X)} @tab @code{COMPLEX(8) X} @tab @code{COMPLEX(8)} @tab GNU extension +@item @code{CDLOG(X)} @tab @code{COMPLEX(8) X} @tab @code{COMPLEX(8)} @tab GNU extension @end multitable @end table @@ -9747,8 +9748,8 @@ end program test_log10 @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{ALOG10(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab Fortran 95 and later -@item @code{DLOG10(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab Fortran 95 and later +@item @code{ALOG10(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab Fortran 77 and later +@item @code{DLOG10(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab Fortran 77 and later @end multitable @end table @@ -9796,9 +9797,9 @@ end program test_log_gamma @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{LGAMMA(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU Extension -@item @code{ALGAMA(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU Extension -@item @code{DLGAMA(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU Extension +@item @code{LGAMMA(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU extension +@item @code{ALGAMA(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU extension +@item @code{DLGAMA(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU extension @end multitable @item @emph{See also}: @@ -9818,7 +9819,7 @@ Gamma function: @gol Converts one kind of @code{LOGICAL} variable to another. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Elemental function @@ -10187,7 +10188,7 @@ default integer kind. Performs a matrix multiplication on numeric or logical arguments. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Transformational function @@ -10281,7 +10282,7 @@ and has the same type and kind as the first argument. type of @code{X}. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Inquiry function @@ -10397,7 +10398,7 @@ if @var{ARRAY} is numeric, or a string of nulls if @var{ARRAY} is of character type. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Transformational function @@ -10415,7 +10416,7 @@ Transformational function @item @var{DIM} @tab (Optional) Shall be a scalar of type @code{INTEGER}, with a value between one and the rank of @var{ARRAY}, inclusive. It may not be an optional dummy argument. -@item @var{MASK} @tab Shall be an array of type @code{LOGICAL}, +@item @var{MASK} @tab (Opional) Shall be an array of type @code{LOGICAL}, and conformable with @var{ARRAY}. @end multitable @@ -10530,7 +10531,7 @@ is equal to @var{TSOURCE} if @var{MASK} is @code{.TRUE.}, or equal to @var{FSOURCE} if it is @code{.FALSE.}. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Elemental function @@ -10656,7 +10657,7 @@ and has the same type and kind as the first argument. type of @code{X}. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Inquiry function @@ -10701,7 +10702,7 @@ and all of the elements of @var{MASK} along a given row are zero, the result value for that row is zero. @item @emph{Standard}: -Fortran 95 and later; @var{ARRAY} of @code{CHARACTER} and the +Fortran 90 and later; @var{ARRAY} of @code{CHARACTER} and the @var{KIND} argument are available in Fortran 2003 and later. The @var{BACK} argument is available in Fortran 2008 and later. @@ -10764,7 +10765,7 @@ considered. If the array has zero size, or all of the elements of @var{ARRAY} is of character type. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Transformational function @@ -10863,9 +10864,9 @@ end program test_mod @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Arguments @tab Return type @tab Standard -@item @code{MOD(A,P)} @tab @code{INTEGER A,P} @tab @code{INTEGER} @tab Fortran 95 and later -@item @code{AMOD(A,P)} @tab @code{REAL(4) A,P} @tab @code{REAL(4)} @tab Fortran 95 and later -@item @code{DMOD(A,P)} @tab @code{REAL(8) A,P} @tab @code{REAL(8)} @tab Fortran 95 and later +@item @code{MOD(A,P)} @tab @code{INTEGER A,P} @tab @code{INTEGER} @tab Fortran 77 and later +@item @code{AMOD(A,P)} @tab @code{REAL(4) A,P} @tab @code{REAL(4)} @tab Fortran 77 and later +@item @code{DMOD(A,P)} @tab @code{REAL(8) A,P} @tab @code{REAL(8)} @tab Fortran 77 and later @item @code{BMOD(A,P)} @tab @code{INTEGER(1) A,P} @tab @code{INTEGER(1)} @tab GNU extension @item @code{IMOD(A,P)} @tab @code{INTEGER(2) A,P} @tab @code{INTEGER(2)} @tab GNU extension @item @code{JMOD(A,P)} @tab @code{INTEGER(4) A,P} @tab @code{INTEGER(4)} @tab GNU extension @@ -11007,7 +11008,7 @@ affected by the movement of bits is unchanged. The values of @code{BIT_SIZE(FROM)}. @item @emph{Standard}: -Fortran 95 and later, has overloads that are GNU extensions +Fortran 90 and later, has overloads that are GNU extensions @item @emph{Class}: Elemental subroutine @@ -11028,7 +11029,7 @@ same kind as @var{FROM}. @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{MVBITS(A)} @tab @code{INTEGER A} @tab @code{INTEGER} @tab Fortran 95 and later +@item @code{MVBITS(A)} @tab @code{INTEGER A} @tab @code{INTEGER} @tab Fortran 90 and later @item @code{BMVBITS(A)} @tab @code{INTEGER(1) A} @tab @code{INTEGER(1)} @tab GNU extension @item @code{IMVBITS(A)} @tab @code{INTEGER(2) A} @tab @code{INTEGER(2)} @tab GNU extension @item @code{JMVBITS(A)} @tab @code{INTEGER(4) A} @tab @code{INTEGER(4)} @tab GNU extension @@ -11058,7 +11059,7 @@ same kind as @var{FROM}. to @code{X} in the direction indicated by the sign of @code{S}. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Elemental function @@ -11178,8 +11179,8 @@ end program test_nint @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return Type @tab Standard -@item @code{NINT(A)} @tab @code{REAL(4) A} @tab @code{INTEGER} @tab Fortran 95 and later -@item @code{IDNINT(A)} @tab @code{REAL(8) A} @tab @code{INTEGER} @tab Fortran 95 and later +@item @code{NINT(A)} @tab @code{REAL(4) A} @tab @code{INTEGER} @tab Fortran 77 and later +@item @code{IDNINT(A)} @tab @code{REAL(8) A} @tab @code{INTEGER} @tab Fortran 77 and later @end multitable @item @emph{See also}: @@ -11256,7 +11257,7 @@ END PROGRAM @code{NOT} returns the bitwise Boolean inverse of @var{I}. @item @emph{Standard}: -Fortran 95 and later, has overloads that are GNU extensions +Fortran 90 and later, has overloads that are GNU extensions @item @emph{Class}: Elemental function @@ -11473,7 +11474,7 @@ equals @code{TRUE}. Afterwards, positions are filled with elements taken from @var{VECTOR}. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Transformational function @@ -11654,6 +11655,7 @@ end program test_population @end table + @node POPPAR @section @code{POPPAR} --- Parity of the number of bits set @fnindex POPPAR @@ -11712,7 +11714,7 @@ end program test_population type of @code{X}. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Inquiry function @@ -11722,7 +11724,8 @@ Inquiry function @item @emph{Arguments}: @multitable @columnfractions .15 .70 -@item @var{X} @tab Shall be of type @code{REAL} or @code{COMPLEX}. +@item @var{X} @tab Shall be of type @code{REAL} or @code{COMPLEX}. It may +be scalar or valued. @end multitable @item @emph{Return value}: @@ -11755,7 +11758,7 @@ end program prec_and_range Determines whether an optional dummy argument is present. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Inquiry function @@ -11803,7 +11806,7 @@ Multiplies the elements of @var{ARRAY} along dimension @var{DIM} if the corresponding element in @var{MASK} is @code{TRUE}. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Transformational function @@ -11860,7 +11863,7 @@ END PROGRAM @code{RADIX(X)} returns the base of the model representing the entity @var{X}. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Inquiry function @@ -12045,7 +12048,7 @@ intrinsic. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Subroutine @@ -12100,7 +12103,7 @@ threads that have used @code{RANDOM_NUMBER} so far during the program execution. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Subroutine @@ -12155,7 +12158,7 @@ end program test_random_seed type of @code{X}. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Inquiry function @@ -12243,7 +12246,7 @@ end program test_rank and its use is strongly discouraged. @item @emph{Standard}: -Fortran 77 and later +Fortran 77 and later, with @var{KIND} argument Fortran 90 and later, has GNU extensions @item @emph{Class}: Elemental function @@ -12290,12 +12293,12 @@ end program test_real @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{FLOAT(A)} @tab @code{INTEGER(4)} @tab @code{REAL(4)} @tab Fortran 77 and later +@item @code{FLOAT(A)} @tab @code{INTEGER(4)} @tab @code{REAL(4)} @tab GNU extension @item @code{DFLOAT(A)} @tab @code{INTEGER(4)} @tab @code{REAL(8)} @tab GNU extension @item @code{FLOATI(A)} @tab @code{INTEGER(2)} @tab @code{REAL(4)} @tab GNU extension @item @code{FLOATJ(A)} @tab @code{INTEGER(4)} @tab @code{REAL(4)} @tab GNU extension @item @code{FLOATK(A)} @tab @code{INTEGER(8)} @tab @code{REAL(4)} @tab GNU extension -@item @code{SNGL(A)} @tab @code{INTEGER(8)} @tab @code{REAL(4)} @tab Fortran 77 and later +@item @code{SNGL(A)} @tab @code{INTEGER(8)} @tab @code{REAL(4)} @tab GNU extension @end multitable @@ -12360,7 +12363,7 @@ Subroutine, function Concatenates @var{NCOPIES} copies of a string. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Transformational function @@ -12401,7 +12404,7 @@ the new array may be padded with elements from @var{PAD} or permuted as defined by @var{ORDER}. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Transformational function @@ -12455,7 +12458,7 @@ END PROGRAM model numbers near @var{X}. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Elemental function @@ -12575,7 +12578,7 @@ only if the dynamic type of A is the same as the dynamic type of B. @code{SCALE(X,I)} returns @code{X * RADIX(X)**I}. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Elemental function @@ -12623,7 +12626,7 @@ is returned. If no character of @var{SET} is found in @var{STRING}, the result is zero. @item @emph{Standard}: -Fortran 95 and later, with @var{KIND} argument Fortran 2003 and later +Fortran 90 and later, with @var{KIND} argument Fortran 2003 and later @item @emph{Class}: Elemental function @@ -12821,7 +12824,7 @@ to @math{10^R} (exclusive). If there is no integer kind that accommodates this range, @code{SELECTED_INT_KIND} returns @math{-1}. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Transformational function @@ -12867,7 +12870,7 @@ with decimal precision of at least @code{P} digits, exponent range of at least @code{R}, and with a radix of @code{RADIX}. @item @emph{Standard}: -Fortran 95 and later, with @code{RADIX} Fortran 2008 or later +Fortran 90 and later, with @code{RADIX} Fortran 2008 or later @item @emph{Class}: Transformational function @@ -12942,7 +12945,7 @@ end program real_kinds is that that of @var{X} and whose exponent part is @var{I}. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Elemental function @@ -12985,7 +12988,7 @@ END PROGRAM Determines the shape of an array. @item @emph{Standard}: -Fortran 95 and later, with @var{KIND} argument Fortran 2003 and later +Fortran 90 and later, with @var{KIND} argument Fortran 2003 and later @item @emph{Class}: Inquiry function @@ -13194,9 +13197,9 @@ end program test_sign @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Arguments @tab Return type @tab Standard -@item @code{SIGN(A,B)} @tab @code{REAL(4) A, B} @tab @code{REAL(4)} @tab f77, gnu -@item @code{ISIGN(A,B)} @tab @code{INTEGER(4) A, B} @tab @code{INTEGER(4)} @tab f77, gnu -@item @code{DSIGN(A,B)} @tab @code{REAL(8) A, B} @tab @code{REAL(8)} @tab f77, gnu +@item @code{SIGN(A,B)} @tab @code{REAL(4) A, B} @tab @code{REAL(4)} @tab Fortran 77 and later +@item @code{ISIGN(A,B)} @tab @code{INTEGER(4) A, B} @tab @code{INTEGER(4)} @tab Fortran 77 and later +@item @code{DSIGN(A,B)} @tab @code{REAL(8) A, B} @tab @code{REAL(8)} @tab Fortran 77 and later @end multitable @end table @@ -13303,11 +13306,11 @@ end program test_sin @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{SIN(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab f77, gnu -@item @code{DSIN(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab f95, gnu -@item @code{CSIN(X)} @tab @code{COMPLEX(4) X} @tab @code{COMPLEX(4)} @tab f95, gnu -@item @code{ZSIN(X)} @tab @code{COMPLEX(8) X} @tab @code{COMPLEX(8)} @tab f95, gnu -@item @code{CDSIN(X)} @tab @code{COMPLEX(8) X} @tab @code{COMPLEX(8)} @tab f95, gnu +@item @code{SIN(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab Fortran 77 and later +@item @code{DSIN(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab Fortran 77 and later +@item @code{CSIN(X)} @tab @code{COMPLEX(4) X} @tab @code{COMPLEX(4)} @tab Fortran 77 and later +@item @code{ZSIN(X)} @tab @code{COMPLEX(8) X} @tab @code{COMPLEX(8)} @tab GNU extension +@item @code{CDSIN(X)} @tab @code{COMPLEX(8) X} @tab @code{COMPLEX(8)} @tab GNU extension @end multitable @item @emph{See also}: @@ -13337,7 +13340,7 @@ This function is for compatibility only and should be avoided in favor of standard constructs wherever possible. @item @emph{Standard}: -GNU Extension, enabled with @option{-fdec-math}. +GNU extension, enabled with @option{-fdec-math}. @item @emph{Class}: Elemental function @@ -13365,11 +13368,11 @@ end program test_sind @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{SIND(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU Extension -@item @code{DSIND(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU Extension -@item @code{CSIND(X)} @tab @code{COMPLEX(4) X} @tab @code{COMPLEX(4)} @tab GNU Extension -@item @code{ZSIND(X)} @tab @code{COMPLEX(8) X} @tab @code{COMPLEX(8)} @tab GNU Extension -@item @code{CDSIND(X)} @tab @code{COMPLEX(8) X} @tab @code{COMPLEX(8)} @tab GNU Extension +@item @code{SIND(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU extension +@item @code{DSIND(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU extension +@item @code{CSIND(X)} @tab @code{COMPLEX(4) X} @tab @code{COMPLEX(4)} @tab GNU extension +@item @code{ZSIND(X)} @tab @code{COMPLEX(8) X} @tab @code{COMPLEX(8)} @tab GNU extension +@item @code{CDSIND(X)} @tab @code{COMPLEX(8) X} @tab @code{COMPLEX(8)} @tab GNU extension @end multitable @item @emph{See also}: @@ -13394,7 +13397,8 @@ Radians function: @gol @code{SINH(X)} computes the hyperbolic sine of @var{X}. @item @emph{Standard}: -Fortran 95 and later, for a complex argument Fortran 2008 or later +Fortran 90 and later, for a complex argument Fortran 2008 or later, has +a GNU extension @item @emph{Class}: Elemental function @@ -13421,8 +13425,7 @@ end program test_sinh @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{SINH(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab Fortran 95 and later -@item @code{DSINH(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab Fortran 95 and later +@item @code{DSINH(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab Fortran 90 and later @end multitable @item @emph{See also}: @@ -13444,7 +13447,7 @@ Determine the extent of @var{ARRAY} along a specified dimension @var{DIM}, or the total number of elements in @var{ARRAY} if @var{DIM} is absent. @item @emph{Standard}: -Fortran 95 and later, with @var{KIND} argument Fortran 2003 and later +Fortran 90 and later, with @var{KIND} argument Fortran 2003 and later @item @emph{Class}: Inquiry function @@ -13579,7 +13582,7 @@ Determines the distance between the argument @var{X} and the nearest adjacent number of the same type. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Elemental function @@ -13625,7 +13628,7 @@ Replicates a @var{SOURCE} array @var{NCOPIES} times along a specified dimension @var{DIM}. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Transformational function @@ -13707,9 +13710,9 @@ end program test_sqrt @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{SQRT(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab Fortran 95 and later -@item @code{DSQRT(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab Fortran 95 and later -@item @code{CSQRT(X)} @tab @code{COMPLEX(4) X} @tab @code{COMPLEX(4)} @tab Fortran 95 and later +@item @code{SQRT(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab Fortran 77 and later +@item @code{DSQRT(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab Fortran 77 and later +@item @code{CSQRT(X)} @tab @code{COMPLEX(4) X} @tab @code{COMPLEX(4)} @tab Fortran 77 and later @item @code{ZSQRT(X)} @tab @code{COMPLEX(8) X} @tab @code{COMPLEX(8)} @tab GNU extension @item @code{CDSQRT(X)} @tab @code{COMPLEX(8) X} @tab @code{COMPLEX(8)} @tab GNU extension @end multitable @@ -13906,7 +13909,7 @@ Adds the elements of @var{ARRAY} along dimension @var{DIM} if the corresponding element in @var{MASK} is @code{TRUE}. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Transformational function @@ -14085,7 +14088,7 @@ uses @code{QueryPerformanceCounter} and potential caveats, please see the platform documentation. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Subroutine @@ -14158,8 +14161,8 @@ end program test_tan @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{TAN(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab Fortran 95 and later -@item @code{DTAN(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab Fortran 95 and later +@item @code{TAN(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab Fortran 77 and later +@item @code{DTAN(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab Fortran 77 and later @end multitable @item @emph{See also}: @@ -14186,7 +14189,7 @@ This function is for compatibility only and should be avoided in favor of standard constructs wherever possible. @item @emph{Standard}: -GNU Extension, enabled with @option{-fdec-math}. +GNU extension, enabled with @option{-fdec-math}. @item @emph{Class}: Elemental function @@ -14213,8 +14216,8 @@ end program test_tand @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{TAND(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU Extension -@item @code{DTAND(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU Extension +@item @code{TAND(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab GNU extension +@item @code{DTAND(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab GNU extension @end multitable @item @emph{See also}: @@ -14269,8 +14272,8 @@ end program test_tanh @item @emph{Specific names}: @multitable @columnfractions .20 .20 .20 .25 @item Name @tab Argument @tab Return type @tab Standard -@item @code{TANH(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab Fortran 95 and later -@item @code{DTANH(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab Fortran 95 and later +@item @code{TANH(X)} @tab @code{REAL(4) X} @tab @code{REAL(4)} @tab Fortran 77 and later +@item @code{DTANH(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab Fortran 77 and later @end multitable @item @emph{See also}: @@ -14451,7 +14454,7 @@ The return value is a scalar of type @code{INTEGER(8)}. in the model of the type of @code{X}. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Inquiry function @@ -14532,7 +14535,7 @@ This is approximately equivalent to the C concept of @emph{casting} one type to another. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Transformational function @@ -14592,7 +14595,7 @@ Transpose an array of rank two. Element (i, j) of the result has the value @code{MATRIX(j, i)}, for all i, j. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Transformational function @@ -14622,7 +14625,7 @@ The result has the same type as @var{MATRIX}, and has shape Removes trailing blank characters of a string. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Transformational function @@ -14711,7 +14714,7 @@ END PROGRAM Returns the upper bounds of an array, or a single upper bound along the @var{DIM} dimension. @item @emph{Standard}: -Fortran 95 and later, with @var{KIND} argument Fortran 2003 and later +Fortran 90 and later, with @var{KIND} argument Fortran 2003 and later @item @emph{Class}: Inquiry function @@ -14872,7 +14875,7 @@ Subroutine, function Store the elements of @var{VECTOR} in an array of higher rank. @item @emph{Standard}: -Fortran 95 and later +Fortran 90 and later @item @emph{Class}: Transformational function @@ -14929,7 +14932,7 @@ position is returned. If all characters of @var{STRING} are found in @var{SET}, the result is zero. @item @emph{Standard}: -Fortran 95 and later, with @var{KIND} argument Fortran 2003 and later +Fortran 90 and later, with @var{KIND} argument Fortran 2003 and later @item @emph{Class}: Elemental function -- cgit v1.1 From 629c4e52e48ae0a02cd757815c8dc25a41a53d88 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 28 Aug 2019 13:26:41 +0000 Subject: i386-features.c (convert_scalars_to_vector): Do not add the MD problem. 2019-08-28 Richard Biener * config/i386/i386-features.c (convert_scalars_to_vector): Do not add the MD problem. From-SVN: r274990 --- gcc/ChangeLog | 5 +++++ gcc/config/i386/i386-features.c | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b9b9da9..9d64840 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-08-28 Richard Biener + + * config/i386/i386-features.c (convert_scalars_to_vector): Do not + add the MD problem. + 2019-09-28 Bernd Edlinger Richard Biener diff --git a/gcc/config/i386/i386-features.c b/gcc/config/i386/i386-features.c index 6eb1482..d6a1074 100644 --- a/gcc/config/i386/i386-features.c +++ b/gcc/config/i386/i386-features.c @@ -1564,7 +1564,6 @@ convert_scalars_to_vector (bool timode_p) calculate_dominance_info (CDI_DOMINATORS); df_set_flags (DF_DEFER_INSN_RESCAN); df_chain_add_problem (DF_DU_CHAIN | DF_UD_CHAIN); - df_md_add_problem (); df_analyze (); /* Find all instructions we want to convert into vector mode. */ -- cgit v1.1 From a09b09ccee0208c68d5a6bb57fda94f55db4aded Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Wed, 28 Aug 2019 13:36:54 +0000 Subject: [PR c++/90613] Fix using-decl debug bloat https://gcc.gnu.org/ml/gcc-patches/2019-08/msg01888.html cp/ PR c++/90613 * name-lookup.c (cp_emit_debug_info): Check for builtins during overload iteration. testsuite/ PR c++/90613 * g++.dg/lookup/using61.C: New. From-SVN: r274991 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/name-lookup.c | 33 +++++++++++++++++---------------- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/lookup/using61.C | 8 ++++++++ 4 files changed, 36 insertions(+), 16 deletions(-) create mode 100644 gcc/testsuite/g++.dg/lookup/using61.C (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b735dab..08a44b6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2019-08-28 Nathan Sidwell + + PR c++/90613 + * name-lookup.c (cp_emit_debug_info): Check for builtins during + overload iteration. + 2019-08-27 Marek Polacek PR c++/81676 - bogus -Wunused warnings in constexpr if. diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index a8ab4db..8bbb92d 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -7455,13 +7455,6 @@ cp_emit_debug_info_for_using (tree t, tree context) if (seen_error ()) return; - /* Ignore this FUNCTION_DECL if it refers to a builtin declaration - of a builtin function. */ - if (TREE_CODE (t) == FUNCTION_DECL - && DECL_EXTERNAL (t) - && fndecl_built_in_p (t)) - return; - /* Do not supply context to imported_module_or_decl, if it is a global namespace. */ if (context == global_namespace) @@ -7469,18 +7462,26 @@ cp_emit_debug_info_for_using (tree t, tree context) t = MAYBE_BASELINK_FUNCTIONS (t); - /* FIXME: Handle TEMPLATE_DECLs. */ for (lkp_iterator iter (t); iter; ++iter) { tree fn = *iter; - if (TREE_CODE (fn) != TEMPLATE_DECL) - { - if (building_stmt_list_p ()) - add_stmt (build_stmt (input_location, USING_STMT, fn)); - else - debug_hooks->imported_module_or_decl (fn, NULL_TREE, context, - false, false); - } + + if (TREE_CODE (fn) == TEMPLATE_DECL) + /* FIXME: Handle TEMPLATE_DECLs. */ + continue; + + /* Ignore this FUNCTION_DECL if it refers to a builtin declaration + of a builtin function. */ + if (TREE_CODE (fn) == FUNCTION_DECL + && DECL_EXTERNAL (fn) + && fndecl_built_in_p (fn)) + continue; + + if (building_stmt_list_p ()) + add_stmt (build_stmt (input_location, USING_STMT, fn)); + else + debug_hooks->imported_module_or_decl (fn, NULL_TREE, context, + false, false); } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 333fe3c..480362e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-08-16 Martin Liska + + PR c++/90613 + * g++.dg/lookup/using61.C: New. + 2019-08-28 Bernd Edlinger PR middle-end/89544 diff --git a/gcc/testsuite/g++.dg/lookup/using61.C b/gcc/testsuite/g++.dg/lookup/using61.C new file mode 100644 index 0000000..33d6df0 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/using61.C @@ -0,0 +1,8 @@ +// { dg-options "-gdwarf-2" } +/* { dg-skip-if "No Dwarf" { { *-*-aix* hppa*-*-hpux* } && { ! hppa*64*-*-* } } } */ + +extern "C" long double nanl(const char *); +using ::nanl; + +// We should elide the using for this extern C builtin +// { dg-final { scan-assembler-not ".debug_info" } } -- cgit v1.1 From b66113e9c1ec1f7550cf9680b9b9e4d725583f34 Mon Sep 17 00:00:00 2001 From: Martin Jambor Date: Wed, 28 Aug 2019 16:26:45 +0200 Subject: [PR 91468] Small fixes in ipa-cp.c and ipa-prop.c 2019-08-28 Martin Jambor PR ipa/91468 * ipa-cp.c (merge_agg_lats_step): Removed redundant test, made a checking assert a normal assert to test it really is redundant. * ipa-prop.c (compute_complex_assign_jump_func): Removed redundant test. (update_jump_functions_after_inlining): Removed combining unary arithmetic operations with an ancestor jump function. (ipcp_modif_dom_walker::before_dom_children): Fix wrong use of rhs instead of t. From-SVN: r274992 --- gcc/ChangeLog | 12 ++++++++++++ gcc/ipa-cp.c | 8 +++----- gcc/ipa-prop.c | 12 ++---------- 3 files changed, 17 insertions(+), 15 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9d64840..525cd90 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2019-08-28 Martin Jambor + + PR ipa/91468 + * ipa-cp.c (merge_agg_lats_step): Removed redundant test, made a + checking assert a normal assert to test it really is redundant. + * ipa-prop.c (compute_complex_assign_jump_func): Removed + redundant test. + (update_jump_functions_after_inlining): Removed combining unary + arithmetic operations with an ancestor jump function. + (ipcp_modif_dom_walker::before_dom_children): Fix wrong use of rhs + instead of t. + 2019-08-28 Richard Biener * config/i386/i386-features.c (convert_scalars_to_vector): Do not diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 0046064..33d52fe 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -2026,15 +2026,13 @@ merge_agg_lats_step (class ipcp_param_lattices *dest_plats, if (**aglat && (**aglat)->offset == offset) { - if ((**aglat)->size != val_size - || ((**aglat)->next - && (**aglat)->next->offset < offset + val_size)) + if ((**aglat)->size != val_size) { set_agg_lats_to_bottom (dest_plats); return false; } - gcc_checking_assert (!(**aglat)->next - || (**aglat)->next->offset >= offset + val_size); + gcc_assert (!(**aglat)->next + || (**aglat)->next->offset >= offset + val_size); return true; } else diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 1a0e12e..a23aa25 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -1243,9 +1243,7 @@ compute_complex_assign_jump_func (struct ipa_func_body_info *fbi, break; } case GIMPLE_UNARY_RHS: - if (is_gimple_assign (stmt) - && gimple_assign_rhs_class (stmt) == GIMPLE_UNARY_RHS - && ! CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))) + if (!CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))) ipa_set_jf_unary_pass_through (jfunc, index, gimple_assign_rhs_code (stmt)); default:; @@ -2725,12 +2723,6 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs, dst->value.ancestor.agg_preserved &= src->value.pass_through.agg_preserved; } - else if (src->type == IPA_JF_PASS_THROUGH - && TREE_CODE_CLASS (src->value.pass_through.operation) == tcc_unary) - { - dst->value.ancestor.formal_id = src->value.pass_through.formal_id; - dst->value.ancestor.agg_preserved = false; - } else if (src->type == IPA_JF_ANCESTOR) { dst->value.ancestor.formal_id = src->value.ancestor.formal_id; @@ -4933,7 +4925,7 @@ ipcp_modif_dom_walker::before_dom_children (basic_block bb) { /* V_C_E can do things like convert an array of integers to one bigger integer and similar things we do not handle below. */ - if (TREE_CODE (rhs) == VIEW_CONVERT_EXPR) + if (TREE_CODE (t) == VIEW_CONVERT_EXPR) { vce = true; break; -- cgit v1.1 From bc4aa158c9490e76573bee3eec90f893b7d0b1ae Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Wed, 28 Aug 2019 17:09:51 +0200 Subject: * config/i386/i386-features.c (general_scalar_chain::compute_convert_gain): Correct cost for double-word shifts. (general_scalar_to_vector_candidate_p): Reject count operands greater or equal to mode bitsize. From-SVN: r274994 --- gcc/ChangeLog | 8 ++++++++ gcc/config/i386/i386.c | 6 +++--- 2 files changed, 11 insertions(+), 3 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 525cd90..561bbcb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2019-08-28 Uroš Bizjak + + * config/i386/i386-features.c + (general_scalar_chain::compute_convert_gain): + Correct cost for double-word shifts. + (general_scalar_to_vector_candidate_p): Reject count operands + greater or equal to mode bitsize. + 2019-08-28 Martin Jambor PR ipa/91468 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index f3b3a9a..d2d84eb 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -18617,9 +18617,9 @@ ix86_register_move_cost (machine_mode mode, reg_class_t class1_i, where integer modes in SSE registers are not tieable because of missing QImode and HImode moves to, from or between MMX/SSE registers. */ - return MAX (8, SSE_CLASS_P (class1) - ? ix86_cost->hard_register.sse_to_integer - : ix86_cost->hard_register.integer_to_sse); + return (SSE_CLASS_P (class1) + ? ix86_cost->hard_register.sse_to_integer + : ix86_cost->hard_register.integer_to_sse); if (MAYBE_FLOAT_CLASS_P (class1)) return ix86_cost->hard_register.fp_move; -- cgit v1.1 From e2eee239811d4335f28ccdf7c2d9c490fcf6612d Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Wed, 28 Aug 2019 16:24:38 +0000 Subject: PR driver/80545 - option -Wstringop-overflow not recognized by Fortran gcc/ChangeLog: PR driver/80545 * opts-common.c (option_enabled): Correct checking for language options. From-SVN: r274996 --- gcc/ChangeLog | 6 ++++++ gcc/opts-common.c | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 561bbcb..6fa4090 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-08-28 Martin Sebor + + PR driver/80545 + * opts-common.c (option_enabled): Correct checking for language + options. + 2019-08-28 Uroš Bizjak * config/i386/i386-features.c diff --git a/gcc/opts-common.c b/gcc/opts-common.c index e2a315b..200951b 100644 --- a/gcc/opts-common.c +++ b/gcc/opts-common.c @@ -1532,7 +1532,9 @@ option_enabled (int opt_idx, unsigned lang_mask, void *opts) /* A language-specific option can only be considered enabled when it's valid for the current language. */ - if (option->flags & CL_LANG_ALL && !(option->flags | lang_mask)) + if (!(option->flags & CL_COMMON) + && (option->flags & CL_LANG_ALL) + && !(option->flags & lang_mask)) return 0; struct gcc_options *optsg = (struct gcc_options *) opts; -- cgit v1.1 From 464969eb9b47eb2f24403c74c16769a58dbaa638 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Wed, 28 Aug 2019 16:43:56 +0000 Subject: PR tree-optimization/91457 - inconsistent warning for writing past the end of an array member gcc/ChangeLog: PR tree-optimization/91457 * builtins.c (component_size): New function. (compute_objsize): Add argument. Handle ARRAY_REF and COMPONENT_REF. * builtins.h (compute_objsize): Add argument. * tree-ssa-strlen.c (handle_store): Handle no-warning bit. * tree-vrp.c (vrp_prop::check_array_ref): Return warning result. (vrp_prop::check_mem_ref): Same. (vrp_prop::search_for_addr_array): Set no-warning bit. (check_array_bounds): Same. gcc/testsuite/ChangeLog: PR tree-optimization/91457 * c-c++-common/Wstringop-overflow-2.c: New test. * g++.dg/warn/Warray-bounds-8.C: New test. * g++.dg/warn/Wstringop-overflow-3.C: New test. * gcc.dg/Wstringop-overflow-15.c: New test. From-SVN: r274997 --- gcc/ChangeLog | 12 + gcc/builtins.c | 113 ++++++- gcc/builtins.h | 2 +- gcc/testsuite/ChangeLog | 8 + gcc/testsuite/c-c++-common/Wstringop-overflow-2.c | 348 +++++++++++++++++++ gcc/testsuite/g++.dg/warn/Warray-bounds-8.C | 388 ++++++++++++++++++++++ gcc/testsuite/g++.dg/warn/Wstringop-overflow-3.C | 386 +++++++++++++++++++++ gcc/testsuite/gcc.dg/Wstringop-overflow-15.c | 62 ++++ gcc/tree-ssa-strlen.c | 34 +- gcc/tree-vrp.c | 57 ++-- 10 files changed, 1365 insertions(+), 45 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/Wstringop-overflow-2.c create mode 100644 gcc/testsuite/g++.dg/warn/Warray-bounds-8.C create mode 100644 gcc/testsuite/g++.dg/warn/Wstringop-overflow-3.C create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-15.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6fa4090..77dbf87 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,17 @@ 2019-08-28 Martin Sebor + PR tree-optimization/91457 + * builtins.c (component_size): New function. + (compute_objsize): Add argument. Handle ARRAY_REF and COMPONENT_REF. + * builtins.h (compute_objsize): Add argument. + * tree-ssa-strlen.c (handle_store): Handle no-warning bit. + * tree-vrp.c (vrp_prop::check_array_ref): Return warning result. + (vrp_prop::check_mem_ref): Same. + (vrp_prop::search_for_addr_array): Set no-warning bit. + (check_array_bounds): Same. + +2019-08-28 Martin Sebor + PR driver/80545 * opts-common.c (option_enabled): Correct checking for language options. diff --git a/gcc/builtins.c b/gcc/builtins.c index 0b25adc..f8063c1 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -72,6 +72,7 @@ along with GCC; see the file COPYING3. If not see #include "file-prefix-map.h" /* remap_macro_filename() */ #include "gomp-constants.h" #include "omp-general.h" +#include "tree-dfa.h" struct target_builtins default_target_builtins; #if SWITCHABLE_TARGET @@ -3561,6 +3562,54 @@ check_access (tree exp, tree, tree, tree dstwrite, return true; } +/* Determines the size of the member referenced by the COMPONENT_REF + REF, using its initializer expression if necessary in order to + determine the size of an initialized flexible array member. + Returns the size (which might be zero for an object with + an uninitialized flexible array member) or null if the size + cannot be determined. */ + +static tree +component_size (tree ref) +{ + gcc_assert (TREE_CODE (ref) == COMPONENT_REF); + + tree member = TREE_OPERAND (ref, 1); + + /* If the member is not last or has a size greater than one, return + it. Otherwise it's either a flexible array member or a zero-length + array member, or an array of length one treated as such. */ + tree size = DECL_SIZE_UNIT (member); + if (size + && (!array_at_struct_end_p (ref) + || (!integer_zerop (size) + && !integer_onep (size)))) + return size; + + /* If the reference is to a declared object and the member a true + flexible array, try to determine its size from its initializer. */ + poly_int64 off = 0; + tree base = get_addr_base_and_unit_offset (ref, &off); + if (!base || !VAR_P (base)) + return NULL_TREE; + + /* The size of any member of a declared object other than a flexible + array member is that obtained above. */ + if (size) + return size; + + if (tree init = DECL_INITIAL (base)) + if (TREE_CODE (init) == CONSTRUCTOR) + { + off <<= LOG2_BITS_PER_UNIT; + init = fold_ctor_reference (NULL_TREE, init, off, 0, base); + if (init) + return TYPE_SIZE_UNIT (TREE_TYPE (init)); + } + + return DECL_EXTERNAL (base) ? NULL_TREE : integer_zero_node; +} + /* Helper to compute the size of the object referenced by the DEST expression which must have pointer type, using Object Size type OSTYPE (only the least significant 2 bits are used). Return @@ -3568,12 +3617,18 @@ check_access (tree exp, tree, tree, tree dstwrite, the size cannot be determined. When the referenced object involves a non-constant offset in some range the returned value represents the largest size given the smallest non-negative offset in the - range. The function is intended for diagnostics and should not - be used to influence code generation or optimization. */ + range. If nonnull, set *PDECL to the decl of the referenced + subobject if it can be determined, or to null otherwise. + The function is intended for diagnostics and should not be used + to influence code generation or optimization. */ tree -compute_objsize (tree dest, int ostype) +compute_objsize (tree dest, int ostype, tree *pdecl /* = NULL */) { + tree dummy = NULL_TREE; + if (!pdecl) + pdecl = &dummy; + unsigned HOST_WIDE_INT size; /* Only the two least significant bits are meaningful. */ @@ -3600,7 +3655,7 @@ compute_objsize (tree dest, int ostype) tree off = gimple_assign_rhs2 (stmt); if (TREE_CODE (off) == INTEGER_CST) { - if (tree size = compute_objsize (dest, ostype)) + if (tree size = compute_objsize (dest, ostype, pdecl)) { wide_int wioff = wi::to_wide (off); wide_int wisiz = wi::to_wide (size); @@ -3625,7 +3680,7 @@ compute_objsize (tree dest, int ostype) if (rng == VR_RANGE) { - if (tree size = compute_objsize (dest, ostype)) + if (tree size = compute_objsize (dest, ostype, pdecl)) { wide_int wisiz = wi::to_wide (size); @@ -3653,12 +3708,31 @@ compute_objsize (tree dest, int ostype) if (!ostype) return NULL_TREE; - if (TREE_CODE (dest) == MEM_REF) + if (TREE_CODE (dest) == ARRAY_REF + || TREE_CODE (dest) == MEM_REF) { tree ref = TREE_OPERAND (dest, 0); tree off = TREE_OPERAND (dest, 1); - if (tree size = compute_objsize (ref, ostype)) + if (tree size = compute_objsize (ref, ostype, pdecl)) { + /* If the declaration of the destination object is known + to have zero size, return zero. */ + if (integer_zerop (size)) + return integer_zero_node; + + if (TREE_CODE (off) != INTEGER_CST + || TREE_CODE (size) != INTEGER_CST) + return NULL_TREE; + + if (TREE_CODE (dest) == ARRAY_REF) + { + tree eltype = TREE_TYPE (dest); + if (tree tpsize = TYPE_SIZE_UNIT (eltype)) + off = fold_build2 (MULT_EXPR, size_type_node, off, tpsize); + else + return NULL_TREE; + } + if (tree_int_cst_lt (off, size)) return fold_build2 (MINUS_EXPR, size_type_node, size, off); return integer_zero_node; @@ -3667,9 +3741,22 @@ compute_objsize (tree dest, int ostype) return NULL_TREE; } + if (TREE_CODE (dest) == COMPONENT_REF) + { + *pdecl = TREE_OPERAND (dest, 1); + return component_size (dest); + } + if (TREE_CODE (dest) != ADDR_EXPR) return NULL_TREE; + tree ref = TREE_OPERAND (dest, 0); + if (DECL_P (ref)) + { + *pdecl = ref; + return DECL_SIZE_UNIT (ref); + } + tree type = TREE_TYPE (dest); if (TREE_CODE (type) == POINTER_TYPE) type = TREE_TYPE (type); @@ -3677,14 +3764,10 @@ compute_objsize (tree dest, int ostype) type = TYPE_MAIN_VARIANT (type); if (TREE_CODE (type) == ARRAY_TYPE - && !array_at_struct_end_p (TREE_OPERAND (dest, 0))) - { - /* Return the constant size unless it's zero (that's a zero-length - array likely at the end of a struct). */ - tree size = TYPE_SIZE_UNIT (type); - if (size && TREE_CODE (size) == INTEGER_CST - && !integer_zerop (size)) - return size; + && !array_at_struct_end_p (ref)) + { + if (tree size = TYPE_SIZE_UNIT (type)) + return TREE_CODE (size) == INTEGER_CST ? size : NULL_TREE; } return NULL_TREE; diff --git a/gcc/builtins.h b/gcc/builtins.h index 66c9295..1ad82e8 100644 --- a/gcc/builtins.h +++ b/gcc/builtins.h @@ -134,7 +134,7 @@ extern tree fold_call_stmt (gcall *, bool); extern void set_builtin_user_assembler_name (tree decl, const char *asmspec); extern bool is_simple_builtin (tree); extern bool is_inexpensive_builtin (tree); -extern tree compute_objsize (tree, int); +extern tree compute_objsize (tree, int, tree * = NULL); extern bool readonly_data_expr (tree exp); extern bool init_target_chars (void); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 480362e..0e7c31b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2019-08-28 Martin Sebor + + PR tree-optimization/91457 + * c-c++-common/Wstringop-overflow-2.c: New test. + * g++.dg/warn/Warray-bounds-8.C: New test. + * g++.dg/warn/Wstringop-overflow-3.C: New test. + * gcc.dg/Wstringop-overflow-15.c: New test. + 2019-08-16 Martin Liska PR c++/90613 diff --git a/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c b/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c new file mode 100644 index 0000000..d1aab48 --- /dev/null +++ b/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c @@ -0,0 +1,348 @@ +/* PR middle-end/91458 - inconsistent warning for writing past the end + of an array member + { dg-do compile } + { dg-options "-O2 -Wall -Wno-array-bounds" } */ + +void sink (void*); + +// Exercise flexible array members. + +struct Ax +{ + char n; + char a[]; // { dg-message "destination object declared here" } +}; + +// Verify warning for a definition with no initializer. +struct Ax ax_; + +void gax_ (void) +{ + ax_.a[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + ax_.a[1] = 1; // { dg-warning "\\\[-Wstringop-overflow" } + ax_.a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" } +} + +// Verify warning for access to a definition with an initializer that doesn't +// initialize the flexible array member. +struct Ax ax0 = { 0 }; + +void gax0 (void) +{ + ax0.a[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + ax0.a[1] = 1; // { dg-warning "\\\[-Wstringop-overflow" } + ax0.a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" } +} + +// Verify warning for access to a definition with an initializer that +// initializes the flexible array member to empty. +struct Ax ax0_ = { 0, { } }; + +void gax0_ (void) +{ + ax0_.a[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + ax0_.a[1] = 1; // { dg-warning "\\\[-Wstringop-overflow" } + ax0_.a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" } +} + +// Verify warning for out-of-bounds accesses to a definition with +// an initializer. +struct Ax ax1 = { 1, { 0 } }; + +void gax1 (void) +{ + ax1.a[0] = 0; + ax1.a[1] = 1; // { dg-warning "\\\[-Wstringop-overflow" } + ax1.a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" } +} + +struct Ax ax2 = { 2, { 1, 0 } }; + +void gax2 (void) +{ + ax2.a[0] = 0; + ax2.a[1] = 1; + ax2.a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" } +} + + +// Verify no warning for an unknown struct object. +void gaxp (struct Ax *p) +{ + p->a[0] = 0; + p->a[3] = 3; + p->a[9] = 9; +} + + +// Verify no warning for an extern struct object whose array may be +// initialized to any number of elements. +extern struct Ax axx; + +void gaxx (void) +{ + axx.a[0] = 0; + axx.a[3] = 3; + axx.a[9] = 9; +} + +// Exercise zero-length array members. + +struct A0 +{ + char n; + char a[0]; // { dg-message "destination object declared here" } +}; + +// Verify warning for a definition with no initializer. +struct A0 a0_; + +void ga0_ (void) +{ + a0_.a[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + a0_.a[1] = 1; // { dg-warning "\\\[-Wstringop-overflow" } + a0_.a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" } +} + +// Verify warning for access to a definition with an initializer that doesn't +// initialize the flexible array member. +struct A0 a00 = { 0 }; + +void ga00 (void) +{ + a00.a[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + a00.a[1] = 1; // { dg-warning "\\\[-Wstringop-overflow" } + a00.a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" } +} + +// Verify warning for access to a definition with an initializer that +// initializes the flexible array member to empty. +struct A0 a00_ = { 0, { } }; + +void ga00_ (void) +{ + a00_.a[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + a00_.a[1] = 1; // { dg-warning "\\\[-Wstringop-overflow" } + a00_.a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" } +} + +// The following are rejected with +// error: too many initializers for 'char [0]' +// A0 a01 = { 1, { 0 } }; +// A0 a02 = { 2, { 1, 0 } }; + + +// Verify no warning for an unknown struct object. +void ga0p (struct A0 *p) +{ + p->a[0] = 0; + p->a[3] = 3; + p->a[9] = 9; +} + + +// Verify warning for an extern struct object which (unlike a true +// flexible array member) may not be initialized. +extern struct A0 a0x; + +void ga0x (void) +{ + a0x.a[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + a0x.a[3] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + a0x.a[9] = 0; // { dg-warning "\\\[-Wstringop-overflow" } +} + + +// Exercise trailing one-element array members. + +struct A1 +{ + char n; + char a[1]; // { dg-message "destination object declared here" } +}; + +// Verify warning for a definition with no initializer. +struct A1 a1_; + +void ga1_ (void) +{ + a1_.a[0] = 0; + a1_.a[1] = 1; // { dg-warning "\\\[-Wstringop-overflow" } + a1_.a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" } + + struct A1 a; + a.a[0] = 0; + a.a[1] = 1; // { dg-warning "\\\[-Wstringop-overflow" } + a.a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" } + sink (&a); +} + +// Verify warning for access to a definition with an initializer that doesn't +// initialize the one-element array member. +struct A1 a1__ = { 0 }; + +void ga1__ (void) +{ + a1__.a[0] = 0; + a1__.a[1] = 1; // { dg-warning "\\\[-Wstringop-overflow" } + a1__.a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" } + + struct A1 a = { 1 }; + a.a[0] = 0; + a.a[1] = 1; // { dg-warning "\\\[-Wstringop-overflow" } + a.a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" } + sink (&a); +} + +// Verify warning for access to a definition with an initializer that +// initializes the one-element array member to empty. +struct A1 a1_0 = { 0, { } }; + +void ga1_0_ (void) +{ + a1_0.a[0] = 0; + a1_0.a[1] = 1; // { dg-warning "\\\[-Wstringop-overflow" } + a1_0.a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" } + + struct A1 a = { 1, { } }; + a.a[0] = 0; + a.a[1] = 1; // { dg-warning "\\\[-Wstringop-overflow" } + a.a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" } + sink (&a); +} + +// Verify warning for access to a definition with an initializer that +// initializes the one-element array member. +struct A1 a1_1 = { 0, { 1 } }; + +void ga1_1 (void) +{ + a1_1.a[0] = 0; + a1_1.a[1] = 1; // { dg-warning "\\\[-Wstringop-overflow" } + a1_1.a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" } + + struct A1 a = { 0, { 1 } }; + a.a[0] = 0; + a.a[1] = 1; // { dg-warning "\\\[-Wstringop-overflow" } + a.a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" } + sink (&a); +} + + +// Verify no warning for an unknown struct object. +void ga1p (struct A1 *p) +{ + p->a[0] = 0; + p->a[3] = 3; + p->a[9] = 9; +} + + +// Verify warning for an extern struct object. Similar to the zero-length +// array case, a one-element trailing array can be initialized to at most +// a single element. +extern struct A1 a1x; + +void ga1x (void) +{ + a1x.a[0] = 0; + a1x.a[3] = 3; // { dg-warning "\\\[-Wstringop-overflow" } + a1x.a[9] = 9; // { dg-warning "\\\[-Wstringop-overflow" } +} + +// Exercise interior one-element array members (verify they're not +// treated as trailing. + +struct A1i +{ + char n; + char a[1]; // { dg-message "destination object declared here" } + char x; +}; + +// Verify warning for a definition with no initializer. +struct A1i a1i_; + +void ga1i_ (void) +{ + a1i_.a[0] = 0; + a1i_.a[1] = 1; // { dg-warning "\\\[-Wstringop-overflow" } + a1i_.a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" } + + struct A1i a; + a.a[0] = 1; + a.a[1] = 2; // { dg-warning "\\\[-Wstringop-overflow" } + a.a[2] = 3; // { dg-warning "\\\[-Wstringop-overflow" } + sink (&a); +} + +// Verify warning for access to a definition with an initializer that doesn't +// initialize the one-element array member. +struct A1i a1i__ = { 0 }; + +void ga1i__ (void) +{ + a1i__.a[0] = 0; + a1i__.a[1] = 1; // { dg-warning "\\\[-Wstringop-overflow" } + a1i__.a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" } + + struct A1i a = { 0 }; + a.a[0] = 0; + a.a[1] = 1; // { dg-warning "\\\[-Wstringop-overflow" } + a.a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" } + sink (&a); +} + +// Verify warning for access to a definition with an initializer that +// initializes the one-element array member to empty. +struct A1 a1i_0 = { 0, { } }; + +void ga1i_0_ (void) +{ + a1i_0.a[0] = 0; + a1i_0.a[1] = 1; // { dg-warning "\\\[-Wstringop-overflow" } + a1i_0.a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" } + + struct A1 a = { 0, { } }; + a.a[0] = 0; + a.a[1] = 1; // { dg-warning "\\\[-Wstringop-overflow" } + a.a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" } + sink (&a); +} + +// Verify warning for access to a definition with an initializer that +// initializes the one-element array member. +struct A1 a1i_1 = { 0, { 1 } }; + +void ga1i_1 (void) +{ + a1i_1.a[0] = 0; + a1i_1.a[1] = 1; // { dg-warning "\\\[-Wstringop-overflow" } + a1i_1.a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" } + + struct A1 a = { 0, { 1 } }; + a.a[0] = 1; + a.a[1] = 2; // { dg-warning "\\\[-Wstringop-overflow" } + a.a[2] = 3; // { dg-warning "\\\[-Wstringop-overflow" } + sink (&a); +} + + +// Verify no warning for an unknown struct object. +void ga1ip (struct A1i *p) +{ + p->a[0] = 0; + p->a[3] = 3; // { dg-warning "\\\[-Wstringop-overflow" } + p->a[9] = 9; // { dg-warning "\\\[-Wstringop-overflow" } +} + + +// Verify no warning for an extern struct object. +extern struct A1i a1ix; + +void ga1ix (void) +{ + a1ix.a[0] = 0; + a1ix.a[3] = 3; // { dg-warning "\\\[-Wstringop-overflow" } + a1ix.a[9] = 9; // { dg-warning "\\\[-Wstringop-overflow" } +} diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-8.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-8.C new file mode 100644 index 0000000..850414e --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-8.C @@ -0,0 +1,388 @@ +/* PR middle-end/91458 - inconsistent warning for writing past the end + of an array member + See Wstringop-overflow-3.C for the same test that exercises the other + warning. + { dg-do compile } + { dg-options "-O2 -Wall -Wno-stringop-overflow" } */ + +void sink (void*); + +// Exercise flexible array members. + +struct Ax +{ + char n; + char a[]; // { dg-message "while referencing .Ax::a." "pr91463" { xfail *-*-* } } +}; + +// Verify warning for a definition with no initializer. +Ax ax_; + +void gax_ () +{ + ax_.a[0] = 0; // { dg-warning "\\\[-Warray-bounds" "pr91463" { xfail *-*-* } } + ax_.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" "pr91463" { xfail *-*-* } } + ax_.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" "pr91463" { xfail *-*-* } } +} + +// Verify warning for access to a definition with an initializer that doesn't +// initialize the flexible array member. +Ax ax0 = { 0 }; + +void gax0 () +{ + ax0.a[0] = 0; // { dg-warning "\\\[-Warray-bounds" "pr91463" { xfail *-*-* } } + ax0.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" "pr91463" { xfail *-*-* } } + ax0.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" "pr91463" { xfail *-*-* } } +} + +// Verify warning for access to a definition with an initializer that +// initializes the flexible array member to empty. +Ax ax0_ = { 0, { } }; + +void gax0_ () +{ + ax0_.a[0] = 0; // { dg-warning "\\\[-Warray-bounds" "pr91463" { xfail *-*-* } } + ax0_.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" "pr91463" { xfail *-*-* } } + ax0_.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" "pr91463" { xfail *-*-* } } +} + +// Verify warning for out-of-bounds accesses to a definition with +// an initializer. +Ax ax1 = { 1, { 0 } }; + +void gax1 () +{ + ax1.a[0] = 0; + ax1.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" "pr91463" { xfail *-*-* } } + ax1.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" "pr91463" { xfail *-*-* } } +} + +Ax ax2 = { 2, { 1, 0 } }; + +void gax2 () +{ + ax2.a[0] = 0; + ax2.a[1] = 0; + ax2.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" "pr91463" { xfail *-*-* } } +} + + +// Verify no warning for an unknown struct object. +void gaxp (Ax *p) +{ + p->a[0] = 0; + p->a[3] = 0; + p->a[9] = 0; +} + + +// Verify no warning for an extern struct object whose array may be +// initialized to any number of elements. +extern Ax axx; + +void gaxx () +{ + axx.a[0] = 0; + axx.a[3] = 0; + axx.a[9] = 0; +} + +// Exercise zero-length array members. + +struct A0 +{ + char n; + char a[0]; // { dg-message "while referencing .A0::a." } +}; + +// Verify warning for a definition with no initializer. +A0 a0_; + +void ga0_ () +{ + a0_.a[0] = 0; // { dg-warning "\\\[-Warray-bounds" } + a0_.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" } + a0_.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" } +} + +// Verify warning for access to a definition with an initializer that doesn't +// initialize the flexible array member. +A0 a00 = { 0 }; + +void ga00 () +{ + a00.a[0] = 0; // { dg-warning "\\\[-Warray-bounds" } + a00.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" } + a00.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" } +} + +// Verify warning for access to a definition with an initializer that +// initializes the flexible array member to empty. +A0 a00_ = { 0, { } }; + +void ga00_ () +{ + a00_.a[0] = 0; // { dg-warning "\\\[-Warray-bounds" } + a00_.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" } + a00_.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" } +} + +// The following are rejected with +// error: too many initializers for 'char [0]' +// A0 a01 = { 1, { 0 } }; +// A0 a02 = { 2, { 1, 0 } }; + + +// Verify no warning for an unknown struct object. +void ga0p (A0 *p) +{ + p->a[0] = 0; + p->a[3] = 0; + p->a[9] = 0; +} + + +// Verify warning for an extern struct object which (unlike a true +// flexible array member) may not be initialized. +extern A0 a0x; + +void ga0x () +{ + a0x.a[0] = 0; // { dg-warning "\\\[-Warray-bounds" } + a0x.a[3] = 0; // { dg-warning "\\\[-Warray-bounds" } + a0x.a[9] = 0; // { dg-warning "\\\[-Warray-bounds" } +} + + +// Exercise trailing one-element array members. + +struct A1 +{ + char n; + char a[1]; // { dg-message "while referencing .A1::a." } +}; + +// Verify warning for a definition with no initializer. +A1 a1_; + +void ga1_ () +{ + a1_.a[0] = 0; + a1_.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" } + a1_.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" } +} + +// Verify warning for access to a definition with an initializer that doesn't +// initialize the one-element array member. +A1 a1__ = { 0 }; + +void ga1__ () +{ + a1__.a[0] = 0; + a1__.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" } + a1__.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" } +} + +// Verify warning for access to a definition with an initializer that +// initializes the one-element array member to empty. +A1 a1_0 = { 0, { } }; + +void ga1_0_ () +{ + a1_0.a[0] = 0; + a1_0.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" } + a1_0.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" } +} + +// Verify warning for access to a definition with an initializer that +// initializes the one-element array member. +A1 a1_1 = { 0, { 1 } }; + +void ga1_1 () +{ + a1_1.a[0] = 0; + a1_1.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" } + a1_1.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" } +} + + +// Verify no warning for an unknown struct object. +void ga1p (A1 *p) +{ + p->a[0] = 0; + p->a[3] = 0; + p->a[9] = 0; +} + + +// Verify warning for an extern struct object. Similar to the zero-length +// array case, a one-element trailing array can be initialized to at most +// a single element. +extern A1 a1x; + +void ga1x () +{ + a1x.a[0] = 0; + a1x.a[3] = 0; // { dg-warning "\\\[-Warray-bounds" } + a1x.a[9] = 0; // { dg-warning "\\\[-Warray-bounds" } +} + +// Exercise interior one-element array members (verify they're not +// treated as trailing. + +struct A1i +{ + char n; + char a[1]; // { dg-message "while referencing .A1i::a." } + char x; +}; + +// Verify warning for a definition with no initializer. +A1i a1i_; + +void ga1i_ () +{ + a1i_.a[0] = 0; + a1i_.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" } + a1i_.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" } +} + +// Verify warning for access to a definition with an initializer that doesn't +// initialize the one-element array member. +A1i a1i__ = { 0 }; + +void ga1i__ () +{ + a1i__.a[0] = 0; + a1i__.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" } + a1i__.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" } +} + +// Verify warning for access to a definition with an initializer that +// initializes the one-element array member to empty. +A1 a1i_0 = { 0, { } }; + +void ga1i_0_ () +{ + a1i_0.a[0] = 0; + a1i_0.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" } + a1i_0.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" } +} + +// Verify warning for access to a definition with an initializer that +// initializes the one-element array member. +A1 a1i_1 = { 0, { 1 } }; + +void ga1i_1 () +{ + a1i_1.a[0] = 0; + a1i_1.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" } + a1i_1.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" } +} + + +// Verify no warning for an unknown struct object. +void ga1ip (A1i *p) +{ + p->a[0] = 0; + p->a[3] = 0; // { dg-warning "\\\[-Warray-bounds" } + p->a[9] = 0; // { dg-warning "\\\[-Warray-bounds" } +} + + +// Verify no warning for an extern struct object. +extern A1i a1ix; + +void ga1ix () +{ + a1ix.a[0] = 0; + a1ix.a[3] = 0; // { dg-warning "\\\[-Warray-bounds" } + a1ix.a[9] = 0; // { dg-warning "\\\[-Warray-bounds" } +} + + +// Verify non-POD classes with flexible array members. + +struct Bx +{ + char n; + char a[]; // { dg-message "while referencing .Bx::a." "pr91463" { xfail *-*-* } } + + // Verify the warning for a constant. + Bx () { a[0] = 0; } // { dg-warning "\\\[-Warray-bounds" "pr91463" { xfail *-*-* } } + + // And also for a non-constant. Regardless of the subscript, the array + // of the object in function gxi() below has a zero size. + Bx (int i) { a[i] = 0; } // { dg-warning "\\\[-Warray-bounds" "pr91463" { xfail *-*-* } } +}; + +void gbx (void) +{ + struct Bx bx; + sink (&bx); +} + +void gbxi (int i) +{ + struct Bx bxi (i); + sink (&bxi); +} + +struct B0 +{ + char n; + char a[0]; // { dg-message "while referencing .B0::a." } + + B0 () { a[0] = 0; } // { dg-warning "\\\[-Warray-bounds" } +}; + + +void gb0 (void) +{ + struct B0 b0; + sink (&b0); +} + + +struct B1 +{ + char n; + char a[1]; // { dg-message "while referencing .B1::a." } + + B1 () { a[1] = 0; } // { dg-warning "\\\[-Warray-bounds" } +}; + +void gb1 (void) +{ + struct B1 b1; + sink (&b1); +} + + +struct B123 +{ + char a[123]; // { dg-message "while referencing .B123::a." } + + B123 () { a[123] = 0; } // { dg-warning "\\\[-Warray-bounds" } +}; + +void gb123 (void) +{ + struct B123 b123; + sink (&b123); +} + + +struct B234 +{ + char a[234]; // { dg-message "while referencing .B234::a." } + + B234 (int i) { a[i] = 0; } // { dg-warning "\\\[-Warray-bounds" } +}; + +void g234 (void) +{ + struct B234 b234 (234); + sink (&b234); +} diff --git a/gcc/testsuite/g++.dg/warn/Wstringop-overflow-3.C b/gcc/testsuite/g++.dg/warn/Wstringop-overflow-3.C new file mode 100644 index 0000000..99ce427 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wstringop-overflow-3.C @@ -0,0 +1,386 @@ +/* PR middle-end/91458 - inconsistent warning for writing past the end + of an array member + { dg-do compile } + { dg-options "-O2 -Wall -Wno-array-bounds" } */ + +void sink (void*); + +// Exercise flexible array members. + +struct Ax +{ + char n; + char a[]; // { dg-message "destination object declared here" } +}; + +// Verify warning for a definition with no initializer. +Ax ax_; + +void gax_ () +{ + ax_.a[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + ax_.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + ax_.a[2] = 0; // { dg-warning "\\\[-Wstringop-overflow" } +} + +// Verify warning for access to a definition with an initializer that doesn't +// initialize the flexible array member. +Ax ax0 = { 0 }; + +void gax0 () +{ + ax0.a[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + ax0.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + ax0.a[2] = 0; // { dg-warning "\\\[-Wstringop-overflow" } +} + +// Verify warning for access to a definition with an initializer that +// initializes the flexible array member to empty. +Ax ax0_ = { 0, { } }; + +void gax0_ () +{ + ax0_.a[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + ax0_.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + ax0_.a[2] = 0; // { dg-warning "\\\[-Wstringop-overflow" } +} + +// Verify warning for out-of-bounds accesses to a definition with +// an initializer. +Ax ax1 = { 1, { 0 } }; + +void gax1 () +{ + ax1.a[0] = 0; + ax1.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + ax1.a[2] = 0; // { dg-warning "\\\[-Wstringop-overflow" } +} + +Ax ax2 = { 2, { 1, 0 } }; + +void gax2 () +{ + ax2.a[0] = 0; + ax2.a[1] = 0; + ax2.a[2] = 0; // { dg-warning "\\\[-Wstringop-overflow" } +} + + +// Verify no warning for an unknown struct object. +void gaxp (Ax *p) +{ + p->a[0] = 0; + p->a[3] = 0; + p->a[9] = 0; +} + + +// Verify no warning for an extern struct object whose array may be +// initialized to any number of elements. +extern Ax axx; + +void gaxx () +{ + axx.a[0] = 0; + axx.a[3] = 0; + axx.a[9] = 0; +} + +// Exercise zero-length array members. + +struct A0 +{ + char n; + char a[0]; // { dg-message "destination object declared here" } +}; + +// Verify warning for a definition with no initializer. +A0 a0_; + +void ga0_ () +{ + a0_.a[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + a0_.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + a0_.a[2] = 0; // { dg-warning "\\\[-Wstringop-overflow" } +} + +// Verify warning for access to a definition with an initializer that doesn't +// initialize the flexible array member. +A0 a00 = { 0 }; + +void ga00 () +{ + a00.a[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + a00.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + a00.a[2] = 0; // { dg-warning "\\\[-Wstringop-overflow" } +} + +// Verify warning for access to a definition with an initializer that +// initializes the flexible array member to empty. +A0 a00_ = { 0, { } }; + +void ga00_ () +{ + a00_.a[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + a00_.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + a00_.a[2] = 0; // { dg-warning "\\\[-Wstringop-overflow" } +} + +// The following are rejected with +// error: too many initializers for 'char [0]' +// A0 a01 = { 1, { 0 } }; +// A0 a02 = { 2, { 1, 0 } }; + + +// Verify no warning for an unknown struct object. +void ga0p (A0 *p) +{ + p->a[0] = 0; + p->a[3] = 0; + p->a[9] = 0; +} + + +// Verify warning for an extern struct object which (unlike a true +// flexible array member) may not be initialized. +extern A0 a0x; + +void ga0x () +{ + a0x.a[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + a0x.a[3] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + a0x.a[9] = 0; // { dg-warning "\\\[-Wstringop-overflow" } +} + + +// Exercise trailing one-element array members. + +struct A1 +{ + char n; + char a[1]; // { dg-message "destination object declared here" } +}; + +// Verify warning for a definition with no initializer. +A1 a1_; + +void ga1_ () +{ + a1_.a[0] = 0; + a1_.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + a1_.a[2] = 0; // { dg-warning "\\\[-Wstringop-overflow" } +} + +// Verify warning for access to a definition with an initializer that doesn't +// initialize the one-element array member. +A1 a1__ = { 0 }; + +void ga1__ () +{ + a1__.a[0] = 0; + a1__.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + a1__.a[2] = 0; // { dg-warning "\\\[-Wstringop-overflow" } +} + +// Verify warning for access to a definition with an initializer that +// initializes the one-element array member to empty. +A1 a1_0 = { 0, { } }; + +void ga1_0_ () +{ + a1_0.a[0] = 0; + a1_0.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + a1_0.a[2] = 0; // { dg-warning "\\\[-Wstringop-overflow" } +} + +// Verify warning for access to a definition with an initializer that +// initializes the one-element array member. +A1 a1_1 = { 0, { 1 } }; + +void ga1_1 () +{ + a1_1.a[0] = 0; + a1_1.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + a1_1.a[2] = 0; // { dg-warning "\\\[-Wstringop-overflow" } +} + + +// Verify no warning for an unknown struct object. +void ga1p (A1 *p) +{ + p->a[0] = 0; + p->a[3] = 0; + p->a[9] = 0; +} + + +// Verify warning for an extern struct object. Similar to the zero-length +// array case, a one-element trailing array can be initialized to at most +// a single element. +extern A1 a1x; + +void ga1x () +{ + a1x.a[0] = 0; + a1x.a[3] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + a1x.a[9] = 0; // { dg-warning "\\\[-Wstringop-overflow" } +} + +// Exercise interior one-element array members (verify they're not +// treated as trailing. + +struct A1i +{ + char n; + char a[1]; // { dg-message "destination object declared here" } + char x; +}; + +// Verify warning for a definition with no initializer. +A1i a1i_; + +void ga1i_ () +{ + a1i_.a[0] = 0; + a1i_.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + a1i_.a[2] = 0; // { dg-warning "\\\[-Wstringop-overflow" } +} + +// Verify warning for access to a definition with an initializer that doesn't +// initialize the one-element array member. +A1i a1i__ = { 0 }; + +void ga1i__ () +{ + a1i__.a[0] = 0; + a1i__.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + a1i__.a[2] = 0; // { dg-warning "\\\[-Wstringop-overflow" } +} + +// Verify warning for access to a definition with an initializer that +// initializes the one-element array member to empty. +A1 a1i_0 = { 0, { } }; + +void ga1i_0_ () +{ + a1i_0.a[0] = 0; + a1i_0.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + a1i_0.a[2] = 0; // { dg-warning "\\\[-Wstringop-overflow" } +} + +// Verify warning for access to a definition with an initializer that +// initializes the one-element array member. +A1 a1i_1 = { 0, { 1 } }; + +void ga1i_1 () +{ + a1i_1.a[0] = 0; + a1i_1.a[1] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + a1i_1.a[2] = 0; // { dg-warning "\\\[-Wstringop-overflow" } +} + + +// Verify no warning for an unknown struct object. +void ga1ip (A1i *p) +{ + p->a[0] = 0; + p->a[3] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + p->a[9] = 0; // { dg-warning "\\\[-Wstringop-overflow" } +} + + +// Verify no warning for an extern struct object. +extern A1i a1ix; + +void ga1ix () +{ + a1ix.a[0] = 0; + a1ix.a[3] = 0; // { dg-warning "\\\[-Wstringop-overflow" } + a1ix.a[9] = 0; // { dg-warning "\\\[-Wstringop-overflow" } +} + + +// Verify non-POD classes with flexible array members. + +struct Bx +{ + char n; + char a[]; // { dg-message "destination object declared here" } + + // Verify the warning for a constant. + Bx () { a[0] = 0; } // { dg-warning "\\\[-Wstringop-overflow" } + + // And also for a non-constant. Regardless of the subscript, the array + // of the object in function gxi() below has a zero size. + Bx (int i) { a[i] = 0; } // { dg-warning "\\\[-Wstringop-overflow" } +}; + +void gbx (void) +{ + struct Bx bx; + sink (&bx); +} + +void gbxi (int i) +{ + struct Bx bxi (i); + sink (&bxi); +} + +struct B0 +{ + char n; + char a[0]; // { dg-message "destination object declared here" } + + B0 () { a[0] = 0; } // { dg-warning "\\\[-Wstringop-overflow" } +}; + + +void gb0 (void) +{ + struct B0 b0; + sink (&b0); +} + + +struct B1 +{ + char n; + char a[1]; // { dg-message "destination object declared here" } + + B1 () { a[1] = 0; } // { dg-warning "\\\[-Wstringop-overflow" } +}; + +void gb1 (void) +{ + struct B1 b1; + sink (&b1); +} + + +struct B123 +{ + char a[123]; // { dg-message "destination object declared here" } + + B123 () { a[123] = 0; } // { dg-warning "\\\[-Wstringop-overflow" } +}; + +void gb123 (void) +{ + struct B123 b123; + sink (&b123); +} + + +struct B234 +{ + char a[234]; // { dg-message "destination object declared here" } + + B234 (int i) { a[i] = 0; } // { dg-warning "\\\[-Wstringop-overflow" } +}; + +void g234 (void) +{ + struct B234 b234 (234); + sink (&b234); +} diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-15.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-15.c new file mode 100644 index 0000000..12f8f9d --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-15.c @@ -0,0 +1,62 @@ +/* PR middle-end/91458 - inconsistent warning for writing past the end + of an array member + Verify that the -Wstringop-overflow detection doesn't cause an ICE + for either kind of VLAs (member and non-member). + Diagnosing the accesses is the subject of pr82608. + { dg-do compile } + { dg-options "-O2 -Wall -Wno-array-bounds" } */ + +void sink (void*); + +void vla_unbounded (int n) +{ + char a[n]; + + a[0] = 0; + a[1] = 1; + a[n] = n; // { dg-warning "\\\[-Wstringop-overflow" "pr82608" { xfail *-*-* } } + + sink (&a); +} + +void vla_bounded (int n) +{ + if (n > 32) + n = 32; + + char a[n]; + + a[0] = 0; + a[1] = 1; + a[n] = n; // { dg-warning "\\\[-Wstringop-overflow" "pr82608" { xfail *-*-* } } + a[69] = n; // { dg-warning "\\\[-Wstringop-overflow" "pr82608" { xfail *-*-* } } + + sink (&a); +} + + +void member_vla_unbounded (int n) +{ + struct S { char i, a[n]; } s; + + s.a[0] = 0; + s.a[1] = 1; + s.a[n] = n; // { dg-warning "\\\[-Wstringop-overflow" "pr82608" { xfail *-*-* } } + + sink (&s); +} + +void member_vla_bounded (int n) +{ + if (n > 32) + n = 32; + + struct S { char i, a[n]; } s; + + s.a[0] = 0; + s.a[1] = 1; + s.a[n] = n; // { dg-warning "\\\[-Wstringop-overflow" "pr82608" { xfail *-*-* } } + s.a[69] = n; // { dg-warning "\\\[-Wstringop-overflow" "pr82608" { xfail *-*-* } } + + sink (&s); +} diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index d38352a..7bb5f52 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -4026,16 +4026,30 @@ handle_store (gimple_stmt_iterator *gsi) rhs_minlen = lenrange[0]; storing_nonzero_p = lenrange[1] > 0; - if (tree dstsize = compute_objsize (lhs, 1)) - if (compare_tree_int (dstsize, lenrange[2]) < 0) - { - location_t loc = gimple_nonartificial_location (stmt); - warning_n (loc, OPT_Wstringop_overflow_, - lenrange[2], - "%Gwriting %u byte into a region of size %E", - "%Gwriting %u bytes into a region of size %E", - stmt, lenrange[2], dstsize); - } + /* Avoid issuing multiple warnings for the same LHS or statement. + For example, -Warray-bounds may have already been issued for + an out-of-bounds subscript. */ + if (!TREE_NO_WARNING (lhs) && !gimple_no_warning_p (stmt)) + { + /* Set to the declaration referenced by LHS (if known). */ + tree decl = NULL_TREE; + if (tree dstsize = compute_objsize (lhs, 1, &decl)) + if (compare_tree_int (dstsize, lenrange[2]) < 0) + { + location_t loc = gimple_nonartificial_location (stmt); + if (warning_n (loc, OPT_Wstringop_overflow_, + lenrange[2], + "%Gwriting %u byte into a region of size %E", + "%Gwriting %u bytes into a region of size %E", + stmt, lenrange[2], dstsize)) + { + if (decl) + inform (DECL_SOURCE_LOCATION (decl), + "destination object declared here"); + gimple_set_no_warning (stmt, true); + } + } + } } else { diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 5ec4d17..c95b5ad 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -4388,8 +4388,8 @@ class vrp_prop : public ssa_propagation_engine void vrp_initialize (void); void vrp_finalize (bool); void check_all_array_refs (void); - void check_array_ref (location_t, tree, bool); - void check_mem_ref (location_t, tree, bool); + bool check_array_ref (location_t, tree, bool); + bool check_mem_ref (location_t, tree, bool); void search_for_addr_array (tree, location_t); class vr_values vr_values; @@ -4415,9 +4415,10 @@ class vrp_prop : public ssa_propagation_engine array subscript is a constant, check if it is outside valid range. If the array subscript is a RANGE, warn if it is non-overlapping with valid range. - IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside a ADDR_EXPR. */ + IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside a ADDR_EXPR. + Returns true if a warning has been issued. */ -void +bool vrp_prop::check_array_ref (location_t location, tree ref, bool ignore_off_by_one) { @@ -4426,7 +4427,7 @@ vrp_prop::check_array_ref (location_t location, tree ref, tree low_bound, up_bound, up_bound_p1; if (TREE_NO_WARNING (ref)) - return; + return false; low_sub = up_sub = TREE_OPERAND (ref, 1); up_bound = array_ref_up_bound (ref); @@ -4541,12 +4542,16 @@ vrp_prop::check_array_ref (location_t location, tree ref, if (warned) { ref = TREE_OPERAND (ref, 0); + if (TREE_CODE (ref) == COMPONENT_REF) + ref = TREE_OPERAND (ref, 1); if (DECL_P (ref)) inform (DECL_SOURCE_LOCATION (ref), "while referencing %qD", ref); TREE_NO_WARNING (ref) = 1; } + + return warned; } /* Checks one MEM_REF in REF, located at LOCATION, for out-of-bounds @@ -4556,14 +4561,15 @@ vrp_prop::check_array_ref (location_t location, tree ref, with valid range. IGNORE_OFF_BY_ONE is true if the MEM_REF is inside an ADDR_EXPR (used to allow one-past-the-end indices for code that takes - the address of the just-past-the-end element of an array). */ + the address of the just-past-the-end element of an array). + Returns true if a warning has been issued. */ -void +bool vrp_prop::check_mem_ref (location_t location, tree ref, bool ignore_off_by_one) { if (TREE_NO_WARNING (ref)) - return; + return false; tree arg = TREE_OPERAND (ref, 0); /* The constant and variable offset of the reference. */ @@ -4615,7 +4621,7 @@ vrp_prop::check_mem_ref (location_t location, tree ref, continue; } else - return; + return false; /* VAROFF should always be a SSA_NAME here (and not even INTEGER_CST) but there's no point in taking chances. */ @@ -4677,10 +4683,10 @@ vrp_prop::check_mem_ref (location_t location, tree ref, arg = TREE_OPERAND (arg, 0); if (TREE_CODE (arg) != STRING_CST && TREE_CODE (arg) != VAR_DECL) - return; + return false; } else - return; + return false; /* The type of the object being referred to. It can be an array, string literal, or a non-array type when the MEM_REF represents @@ -4695,7 +4701,7 @@ vrp_prop::check_mem_ref (location_t location, tree ref, || !COMPLETE_TYPE_P (reftype) || TREE_CODE (TYPE_SIZE_UNIT (reftype)) != INTEGER_CST || RECORD_OR_UNION_TYPE_P (reftype)) - return; + return false; offset_int eltsize; if (TREE_CODE (reftype) == ARRAY_TYPE) @@ -4797,11 +4803,11 @@ vrp_prop::check_mem_ref (location_t location, tree ref, if (warned) TREE_NO_WARNING (ref) = 1; - return; + return warned; } if (warn_array_bounds < 2) - return; + return false; /* At level 2 check also intermediate offsets. */ int i = 0; @@ -4812,8 +4818,13 @@ vrp_prop::check_mem_ref (location_t location, tree ref, if (warning_at (location, OPT_Warray_bounds, "intermediate array offset %wi is outside array bounds " "of %qT", tmpidx, reftype)) - TREE_NO_WARNING (ref) = 1; + { + TREE_NO_WARNING (ref) = 1; + return true; + } } + + return false; } /* Searches if the expr T, located at LOCATION computes @@ -4825,10 +4836,14 @@ vrp_prop::search_for_addr_array (tree t, location_t location) /* Check each ARRAY_REF and MEM_REF in the reference chain. */ do { + bool warned = false; if (TREE_CODE (t) == ARRAY_REF) - check_array_ref (location, t, true /*ignore_off_by_one*/); + warned = check_array_ref (location, t, true /*ignore_off_by_one*/); else if (TREE_CODE (t) == MEM_REF) - check_mem_ref (location, t, true /*ignore_off_by_one*/); + warned = check_mem_ref (location, t, true /*ignore_off_by_one*/); + + if (warned) + TREE_NO_WARNING (t) = true; t = TREE_OPERAND (t, 0); } @@ -4920,16 +4935,20 @@ check_array_bounds (tree *tp, int *walk_subtree, void *data) *walk_subtree = TRUE; + bool warned = false; vrp_prop *vrp_prop = (class vrp_prop *)wi->info; if (TREE_CODE (t) == ARRAY_REF) - vrp_prop->check_array_ref (location, t, false /*ignore_off_by_one*/); + warned = vrp_prop->check_array_ref (location, t, false/*ignore_off_by_one*/); else if (TREE_CODE (t) == MEM_REF) - vrp_prop->check_mem_ref (location, t, false /*ignore_off_by_one*/); + warned = vrp_prop->check_mem_ref (location, t, false /*ignore_off_by_one*/); else if (TREE_CODE (t) == ADDR_EXPR) { vrp_prop->search_for_addr_array (t, location); *walk_subtree = FALSE; } + /* Propagate the no-warning bit to the outer expression. */ + if (warned) + TREE_NO_WARNING (t) = true; return NULL_TREE; } -- cgit v1.1 From fc4f90f0c8eca75fb90c736476360584f68d7ef9 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 28 Aug 2019 18:27:30 +0000 Subject: compiler, runtime: provide index information on bounds check failure This implements https://golang.org/cl/161477 in the gofrontend. Updates golang/go#30116 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/191881 From-SVN: r274998 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/expressions.cc | 475 ++++++++++++++++++++++++--------------- gcc/go/gofrontend/expressions.h | 17 +- gcc/go/gofrontend/gogo.cc | 1 + gcc/go/gofrontend/runtime.cc | 7 + gcc/go/gofrontend/runtime.def | 69 ++++++ 6 files changed, 381 insertions(+), 190 deletions(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 18127de..f596a69 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -a6ddd0e1208a7d229c10be630c1110b3914038f5 +189ff44b2c26f29f41f0eb159e0d8f3fa508ecae The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 90a39a2..939a5f7 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -594,67 +594,110 @@ Expression::backend_numeric_constant_expression(Translate_context* context, return ret; } -// Return an expression which evaluates to true if VAL, of arbitrary integer -// type, is negative or is more than the maximum value of the Go type "int". +// Insert bounds checks for an index expression. Check that that VAL +// >= 0 and that it fits in an int. Then check that VAL OP BOUND is +// true. If any condition is false, call one of the CODE runtime +// functions, which will panic. -Expression* -Expression::check_bounds(Expression* val, Location loc) +void +Expression::check_bounds(Expression* val, Operator op, Expression* bound, + Runtime::Function code, + Runtime::Function code_u, + Runtime::Function code_extend, + Runtime::Function code_extend_u, + Statement_inserter* inserter, + Location loc) { - Type* val_type = val->type(); - Type* bound_type = Type::lookup_integer_type("int"); + go_assert(val->is_variable() || val->is_constant()); + go_assert(bound->is_variable() || bound->is_constant()); - int val_type_size; - bool val_is_unsigned = false; - if (val_type->integer_type() != NULL) - { - val_type_size = val_type->integer_type()->bits(); - val_is_unsigned = val_type->integer_type()->is_unsigned(); - } - else - { - if (!val_type->is_numeric_type() - || !Type::are_convertible(bound_type, val_type, NULL)) - { - go_assert(saw_errors()); - return Expression::make_boolean(true, loc); - } + Type* int_type = Type::lookup_integer_type("int"); + int int_type_size = int_type->integer_type()->bits(); - if (val_type->complex_type() != NULL) - val_type_size = val_type->complex_type()->bits(); - else - val_type_size = val_type->float_type()->bits(); + Type* val_type = val->type(); + if (val_type->integer_type() == NULL) + { + go_assert(saw_errors()); + return; } + int val_type_size = val_type->integer_type()->bits(); + bool val_is_unsigned = val_type->integer_type()->is_unsigned(); - Expression* negative_index = Expression::make_boolean(false, loc); - Expression* index_overflows = Expression::make_boolean(false, loc); + // Check that VAL >= 0. + Expression* check = NULL; if (!val_is_unsigned) { Expression* zero = Expression::make_integer_ul(0, val_type, loc); - negative_index = Expression::make_binary(OPERATOR_LT, val, zero, loc); + check = Expression::make_binary(OPERATOR_GE, val->copy(), zero, loc); } - int bound_type_size = bound_type->integer_type()->bits(); - if (val_type_size > bound_type_size - || (val_type_size == bound_type_size + // If VAL's type is larger than int, check that VAL fits in an int. + if (val_type_size > int_type_size + || (val_type_size == int_type_size && val_is_unsigned)) { mpz_t one; mpz_init_set_ui(one, 1UL); - // maxval = 2^(bound_type_size - 1) - 1 + // maxval = 2^(int_type_size - 1) - 1 mpz_t maxval; mpz_init(maxval); - mpz_mul_2exp(maxval, one, bound_type_size - 1); + mpz_mul_2exp(maxval, one, int_type_size - 1); mpz_sub_ui(maxval, maxval, 1); Expression* max = Expression::make_integer_z(&maxval, val_type, loc); mpz_clear(one); mpz_clear(maxval); - index_overflows = Expression::make_binary(OPERATOR_GT, val, max, loc); + Expression* cmp = Expression::make_binary(OPERATOR_LE, val->copy(), + max, loc); + if (check == NULL) + check = cmp; + else + check = Expression::make_binary(OPERATOR_ANDAND, check, cmp, loc); + } + + // For the final check we can assume that VAL fits in an int. + Expression* ival; + if (val_type == int_type) + ival = val->copy(); + else + ival = Expression::make_cast(int_type, val->copy(), loc); + + // BOUND is assumed to fit in an int. Either it comes from len or + // cap, or it was checked by an earlier call. + Expression* ibound; + if (bound->type() == int_type) + ibound = bound->copy(); + else + ibound = Expression::make_cast(int_type, bound->copy(), loc); + + Expression* cmp = Expression::make_binary(op, ival, ibound, loc); + if (check == NULL) + check = cmp; + else + check = Expression::make_binary(OPERATOR_ANDAND, check, cmp, loc); + + Runtime::Function c; + if (val_type_size > int_type_size) + { + if (val_is_unsigned) + c = code_extend_u; + else + c = code_extend; + } + else + { + if (val_is_unsigned) + c = code_u; + else + c = code; } - return Expression::make_binary(OPERATOR_OROR, negative_index, index_overflows, - loc); + Expression* ignore = Expression::make_boolean(true, loc); + Expression* crash = Runtime::make_call(c, loc, 2, + val->copy(), bound->copy()); + Expression* cond = Expression::make_conditional(check, ignore, crash, loc); + inserter->insert(Statement::make_statement(cond, true)); } void @@ -12666,7 +12709,8 @@ Array_index_expression::do_check_types(Gogo*) unsigned long v; if (this->start_->type()->integer_type() == NULL && !this->start_->type()->is_error() - && (!this->start_->numeric_constant_value(&nc) + && (!this->start_->type()->is_abstract() + || !this->start_->numeric_constant_value(&nc) || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT)) this->report_error(_("index must be integer")); if (this->end_ != NULL @@ -12674,7 +12718,8 @@ Array_index_expression::do_check_types(Gogo*) && !this->end_->type()->is_error() && !this->end_->is_nil_expression() && !this->end_->is_error_expression() - && (!this->end_->numeric_constant_value(&nc) + && (!this->end_->type()->is_abstract() + || !this->end_->numeric_constant_value(&nc) || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT)) this->report_error(_("slice end must be integer")); if (this->cap_ != NULL @@ -12682,7 +12727,8 @@ Array_index_expression::do_check_types(Gogo*) && !this->cap_->type()->is_error() && !this->cap_->is_nil_expression() && !this->cap_->is_error_expression() - && (!this->cap_->numeric_constant_value(&nc) + && (!this->cap_->type()->is_abstract() + || !this->cap_->numeric_constant_value(&nc) || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT)) this->report_error(_("slice capacity must be integer")); @@ -12799,13 +12845,21 @@ Array_index_expression::do_must_eval_subexpressions_in_order( return true; } -// Flatten array indexing by using temporary variables for slices and indexes. +// Flatten array indexing: add temporary variables and bounds checks. Expression* -Array_index_expression::do_flatten(Gogo*, Named_object*, +Array_index_expression::do_flatten(Gogo* gogo, Named_object*, Statement_inserter* inserter) { + if (this->is_flattened_) + return this; + this->is_flattened_ = true; + Location loc = this->location(); + + if (this->is_error_expression()) + return Expression::make_error(loc); + Expression* array = this->array_; Expression* start = this->start_; Expression* end = this->end_; @@ -12823,34 +12877,157 @@ Array_index_expression::do_flatten(Gogo*, Named_object*, return Expression::make_error(loc); } + Array_type* array_type = this->array_->type()->array_type(); + if (array_type == NULL) + { + go_assert(saw_errors()); + return Expression::make_error(loc); + } + Temporary_statement* temp; - if (array->type()->is_slice_type() && !array->is_variable()) + if (array_type->is_slice_type() && !array->is_variable()) { temp = Statement::make_temporary(NULL, array, loc); inserter->insert(temp); this->array_ = Expression::make_temporary_reference(temp, loc); + array = this->array_; } - if (!start->is_variable()) + if (!start->is_variable() && !start->is_constant()) { temp = Statement::make_temporary(NULL, start, loc); inserter->insert(temp); this->start_ = Expression::make_temporary_reference(temp, loc); + start = this->start_; } if (end != NULL && !end->is_nil_expression() - && !end->is_variable()) + && !end->is_variable() + && !end->is_constant()) { temp = Statement::make_temporary(NULL, end, loc); inserter->insert(temp); this->end_ = Expression::make_temporary_reference(temp, loc); + end = this->end_; } - if (cap != NULL && !cap->is_variable()) + if (cap != NULL && !cap->is_variable() && !cap->is_constant()) { temp = Statement::make_temporary(NULL, cap, loc); inserter->insert(temp); this->cap_ = Expression::make_temporary_reference(temp, loc); + cap = this->cap_; + } + + if (!this->needs_bounds_check_) + return this; + + Expression* len; + if (!array_type->is_slice_type()) + { + len = array_type->get_length(gogo, this->array_); + go_assert(len->is_constant()); + } + else + { + len = array_type->get_length(gogo, this->array_->copy()); + temp = Statement::make_temporary(NULL, len, loc); + inserter->insert(temp); + len = Expression::make_temporary_reference(temp, loc); + } + + Expression* scap = NULL; + if (array_type->is_slice_type()) + { + scap = array_type->get_capacity(gogo, this->array_->copy()); + temp = Statement::make_temporary(NULL, scap, loc); + inserter->insert(temp); + scap = Expression::make_temporary_reference(temp, loc); } + // The order of bounds checks here matches the order used by the gc + // compiler, as tested by issue30116[u].go. + + if (cap != NULL) + { + if (array_type->is_slice_type()) + Expression::check_bounds(cap, OPERATOR_LE, scap, + Runtime::PANIC_SLICE3_ACAP, + Runtime::PANIC_SLICE3_ACAP_U, + Runtime::PANIC_EXTEND_SLICE3_ACAP, + Runtime::PANIC_EXTEND_SLICE3_ACAP_U, + inserter, loc); + else + Expression::check_bounds(cap, OPERATOR_LE, len, + Runtime::PANIC_SLICE3_ALEN, + Runtime::PANIC_SLICE3_ALEN_U, + Runtime::PANIC_EXTEND_SLICE3_ALEN, + Runtime::PANIC_EXTEND_SLICE3_ALEN_U, + inserter, loc); + + Expression* start_bound = cap; + if (end != NULL && !end->is_nil_expression()) + { + Expression::check_bounds(end, OPERATOR_LE, cap, + Runtime::PANIC_SLICE3_B, + Runtime::PANIC_SLICE3_B_U, + Runtime::PANIC_EXTEND_SLICE3_B, + Runtime::PANIC_EXTEND_SLICE3_B_U, + inserter, loc); + start_bound = end; + } + + Expression::check_bounds(start, OPERATOR_LE, start_bound, + Runtime::PANIC_SLICE3_C, + Runtime::PANIC_SLICE3_C_U, + Runtime::PANIC_EXTEND_SLICE3_C, + Runtime::PANIC_EXTEND_SLICE3_C_U, + inserter, loc); + } + else if (end != NULL && !end->is_nil_expression()) + { + if (array_type->is_slice_type()) + Expression::check_bounds(end, OPERATOR_LE, scap, + Runtime::PANIC_SLICE_ACAP, + Runtime::PANIC_SLICE_ACAP_U, + Runtime::PANIC_EXTEND_SLICE_ACAP, + Runtime::PANIC_EXTEND_SLICE_ACAP_U, + inserter, loc); + else + Expression::check_bounds(end, OPERATOR_LE, len, + Runtime::PANIC_SLICE_ALEN, + Runtime::PANIC_SLICE_ALEN_U, + Runtime::PANIC_EXTEND_SLICE_ALEN, + Runtime::PANIC_EXTEND_SLICE_ALEN_U, + inserter, loc); + + Expression::check_bounds(start, OPERATOR_LE, end, + Runtime::PANIC_SLICE_B, + Runtime::PANIC_SLICE_B_U, + Runtime::PANIC_EXTEND_SLICE_B, + Runtime::PANIC_EXTEND_SLICE_B_U, + inserter, loc); + } + else if (end != NULL) + { + Expression* start_bound; + if (array_type->is_slice_type()) + start_bound = scap; + else + start_bound = len; + Expression::check_bounds(start, OPERATOR_LE, start_bound, + Runtime::PANIC_SLICE_B, + Runtime::PANIC_SLICE_B_U, + Runtime::PANIC_EXTEND_SLICE_B, + Runtime::PANIC_EXTEND_SLICE_B_U, + inserter, loc); + } + else + Expression::check_bounds(start, OPERATOR_LT, len, + Runtime::PANIC_INDEX, + Runtime::PANIC_INDEX_U, + Runtime::PANIC_EXTEND_INDEX, + Runtime::PANIC_EXTEND_INDEX_U, + inserter, loc); + return this; } @@ -12899,10 +13076,8 @@ Array_index_expression::do_get_backend(Translate_context* context) Type* int_type = Type::lookup_integer_type("int"); Btype* int_btype = int_type->get_backend(gogo); - // We need to convert the length and capacity to the Go "int" type here - // because the length of a fixed-length array could be of type "uintptr" - // and gimple disallows binary operations between "uintptr" and other - // integer types. FIXME. + // Convert the length and capacity to "int". FIXME: Do we need to + // do this? Bexpression* length = NULL; if (this->end_ == NULL || this->end_->is_nil_expression()) { @@ -12939,53 +13114,18 @@ Array_index_expression::do_get_backend(Translate_context* context) Bexpression* start = this->start_->get_backend(context); start = gogo->backend()->convert_expression(int_btype, start, loc); - Bexpression* crash = NULL; - Bexpression* bad_index = NULL; - if (this->needs_bounds_check_) - { - int code = (array_type->length() != NULL - ? (this->end_ == NULL - ? RUNTIME_ERROR_ARRAY_INDEX_OUT_OF_BOUNDS - : RUNTIME_ERROR_ARRAY_SLICE_OUT_OF_BOUNDS) - : (this->end_ == NULL - ? RUNTIME_ERROR_SLICE_INDEX_OUT_OF_BOUNDS - : RUNTIME_ERROR_SLICE_SLICE_OUT_OF_BOUNDS)); - crash = gogo->runtime_error(code, loc)->get_backend(context); - bad_index = Expression::check_bounds(this->start_, loc)->get_backend(context); - Bexpression* start_too_large = - gogo->backend()->binary_expression((this->end_ == NULL - ? OPERATOR_GE - : OPERATOR_GT), - start, - (this->end_ == NULL - ? length - : capacity), - loc); - bad_index = gogo->backend()->binary_expression(OPERATOR_OROR, - start_too_large, - bad_index, loc); - } - - Bfunction* bfn = context->function()->func_value()->get_decl(); if (this->end_ == NULL) { - // Simple array indexing. This has to return an l-value, so - // wrap the index check into START. - if (this->needs_bounds_check_) - start = - gogo->backend()->conditional_expression(bfn, int_btype, bad_index, - crash, start, loc); - + // Simple array indexing. Bexpression* ret; - if (array_type->length() != NULL) + if (!array_type->is_slice_type()) { Bexpression* array = this->array_->get_backend(context); ret = gogo->backend()->array_index_expression(array, start, loc); } else { - // Slice. Expression* valptr = array_type->get_value_pointer(gogo, this->array_, this->is_lvalue_); @@ -12999,31 +13139,7 @@ Array_index_expression::do_get_backend(Translate_context* context) return ret; } - // Array slice. - - if (this->cap_ != NULL) - { - cap_arg = gogo->backend()->convert_expression(int_btype, cap_arg, loc); - - if (this->needs_bounds_check_) - { - Bexpression* bounds_bcheck = - Expression::check_bounds(this->cap_, loc)->get_backend(context); - bad_index = - gogo->backend()->binary_expression(OPERATOR_OROR, bounds_bcheck, - bad_index, loc); - - Bexpression* cap_too_small = - gogo->backend()->binary_expression(OPERATOR_LT, cap_arg, start, loc); - Bexpression* cap_too_large = - gogo->backend()->binary_expression(OPERATOR_GT, cap_arg, capacity, loc); - Bexpression* bad_cap = - gogo->backend()->binary_expression(OPERATOR_OROR, cap_too_small, - cap_too_large, loc); - bad_index = gogo->backend()->binary_expression(OPERATOR_OROR, bad_cap, - bad_index, loc); - } - } + // Slice expression. Bexpression* end; if (this->end_->is_nil_expression()) @@ -13032,24 +13148,6 @@ Array_index_expression::do_get_backend(Translate_context* context) { end = this->end_->get_backend(context); end = gogo->backend()->convert_expression(int_btype, end, loc); - if (this->needs_bounds_check_) - { - Bexpression* bounds_bcheck = - Expression::check_bounds(this->end_, loc)->get_backend(context); - bad_index = - gogo->backend()->binary_expression(OPERATOR_OROR, bounds_bcheck, - bad_index, loc); - - Bexpression* end_too_small = - gogo->backend()->binary_expression(OPERATOR_LT, end, start, loc); - Bexpression* end_too_large = - gogo->backend()->binary_expression(OPERATOR_GT, end, cap_arg, loc); - Bexpression* bad_end = - gogo->backend()->binary_expression(OPERATOR_OROR, end_too_small, - end_too_large, loc); - bad_index = gogo->backend()->binary_expression(OPERATOR_OROR, bad_end, - bad_index, loc); - } } Bexpression* result_length = @@ -13081,12 +13179,7 @@ Array_index_expression::do_get_backend(Translate_context* context) init.push_back(result_length); init.push_back(result_capacity); - Bexpression* ret = - gogo->backend()->constructor_expression(struct_btype, init, loc); - if (this->needs_bounds_check_) - ret = gogo->backend()->conditional_expression(bfn, struct_btype, bad_index, - crash, ret, loc); - return ret; + return gogo->backend()->constructor_expression(struct_btype, init, loc); } // Export an array index expression. @@ -13164,7 +13257,15 @@ Expression* String_index_expression::do_flatten(Gogo*, Named_object*, Statement_inserter* inserter) { + if (this->is_flattened_) + return this; + this->is_flattened_ = true; + Location loc = this->location(); + + if (this->is_error_expression()) + return Expression::make_error(loc); + Expression* string = this->string_; Expression* start = this->start_; Expression* end = this->end_; @@ -13180,27 +13281,69 @@ String_index_expression::do_flatten(Gogo*, Named_object*, } Temporary_statement* temp; - if (!this->string_->is_variable()) + if (!string->is_variable()) { - temp = Statement::make_temporary(NULL, this->string_, loc); + temp = Statement::make_temporary(NULL, string, loc); inserter->insert(temp); this->string_ = Expression::make_temporary_reference(temp, loc); + string = this->string_; } - if (!this->start_->is_variable()) + if (!start->is_variable()) { - temp = Statement::make_temporary(NULL, this->start_, loc); + temp = Statement::make_temporary(NULL, start, loc); inserter->insert(temp); this->start_ = Expression::make_temporary_reference(temp, loc); + start = this->start_; } - if (this->end_ != NULL - && !this->end_->is_nil_expression() - && !this->end_->is_variable()) + if (end != NULL + && !end->is_nil_expression() + && !end->is_variable()) { - temp = Statement::make_temporary(NULL, this->end_, loc); + temp = Statement::make_temporary(NULL, end, loc); inserter->insert(temp); this->end_ = Expression::make_temporary_reference(temp, loc); + end = this->end_; } + Expression* len = Expression::make_string_info(string->copy(), + STRING_INFO_LENGTH, loc); + temp = Statement::make_temporary(NULL, len, loc); + inserter->insert(temp); + len = Expression::make_temporary_reference(temp, loc); + + // The order of bounds checks here matches the order used by the gc + // compiler, as tested by issue30116[u].go. + + if (end != NULL && !end->is_nil_expression()) + { + Expression::check_bounds(end, OPERATOR_LE, len, + Runtime::PANIC_SLICE_ALEN, + Runtime::PANIC_SLICE_ALEN_U, + Runtime::PANIC_EXTEND_SLICE_ALEN, + Runtime::PANIC_EXTEND_SLICE_ALEN_U, + inserter, loc); + Expression::check_bounds(start, OPERATOR_LE, end, + Runtime::PANIC_SLICE_B, + Runtime::PANIC_SLICE_B_U, + Runtime::PANIC_EXTEND_SLICE_B, + Runtime::PANIC_EXTEND_SLICE_B_U, + inserter, loc); + } + else if (end != NULL) + Expression::check_bounds(start, OPERATOR_LE, len, + Runtime::PANIC_SLICE_B, + Runtime::PANIC_SLICE_B_U, + Runtime::PANIC_EXTEND_SLICE_B, + Runtime::PANIC_EXTEND_SLICE_B_U, + inserter, loc); + else + Expression::check_bounds(start, OPERATOR_LT, len, + Runtime::PANIC_INDEX, + Runtime::PANIC_INDEX_U, + Runtime::PANIC_EXTEND_INDEX, + Runtime::PANIC_EXTEND_INDEX_U, + inserter, loc); + return this; } @@ -13245,7 +13388,8 @@ String_index_expression::do_check_types(Gogo*) unsigned long v; if (this->start_->type()->integer_type() == NULL && !this->start_->type()->is_error() - && (!this->start_->numeric_constant_value(&nc) + && (!this->start_->type()->is_abstract() + || !this->start_->numeric_constant_value(&nc) || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT)) this->report_error(_("index must be integer")); if (this->end_ != NULL @@ -13253,7 +13397,8 @@ String_index_expression::do_check_types(Gogo*) && !this->end_->type()->is_error() && !this->end_->is_nil_expression() && !this->end_->is_error_expression() - && (!this->end_->numeric_constant_value(&nc) + && (!this->end_->type()->is_abstract() + || !this->end_->numeric_constant_value(&nc) || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT)) this->report_error(_("slice end must be integer")); @@ -13303,14 +13448,7 @@ Bexpression* String_index_expression::do_get_backend(Translate_context* context) { Location loc = this->location(); - Expression* bad_index = Expression::check_bounds(this->start_, loc); - - int code = (this->end_ == NULL - ? RUNTIME_ERROR_STRING_INDEX_OUT_OF_BOUNDS - : RUNTIME_ERROR_STRING_SLICE_OUT_OF_BOUNDS); - Gogo* gogo = context->gogo(); - Bexpression* crash = gogo->runtime_error(code, loc)->get_backend(context); Type* int_type = Type::lookup_integer_type("int"); @@ -13342,21 +13480,9 @@ String_index_expression::do_get_backend(Translate_context* context) if (this->end_ == NULL) { - Expression* start_too_large = - Expression::make_binary(OPERATOR_GE, start, length, loc); - bad_index = Expression::make_binary(OPERATOR_OROR, start_too_large, - bad_index, loc); - ptr = gogo->backend()->pointer_offset_expression(ptr, bstart, loc); Btype* ubtype = Type::lookup_integer_type("uint8")->get_backend(gogo); - Bexpression* index = - gogo->backend()->indirect_expression(ubtype, ptr, true, loc); - - Btype* byte_btype = bytes->type()->points_to()->get_backend(gogo); - Bexpression* index_error = bad_index->get_backend(context); - return gogo->backend()->conditional_expression(bfn, byte_btype, - index_error, crash, - index, loc); + return gogo->backend()->indirect_expression(ubtype, ptr, true, loc); } Expression* end = NULL; @@ -13365,20 +13491,8 @@ String_index_expression::do_get_backend(Translate_context* context) else { go_assert(this->end_->is_variable()); - Expression* bounds_check = Expression::check_bounds(this->end_, loc); - bad_index = - Expression::make_binary(OPERATOR_OROR, bounds_check, bad_index, loc); end = Expression::make_cast(int_type, this->end_, loc); - - Expression* end_too_large = - Expression::make_binary(OPERATOR_GT, end, length, loc); - bad_index = Expression::make_binary(OPERATOR_OROR, end_too_large, - bad_index, loc); } - Expression* start_too_large = - Expression::make_binary(OPERATOR_GT, start->copy(), end->copy(), loc); - bad_index = Expression::make_binary(OPERATOR_OROR, start_too_large, - bad_index, loc); end = end->copy(); Bexpression* bend = end->get_backend(context); @@ -13405,12 +13519,7 @@ String_index_expression::do_get_backend(Translate_context* context) std::vector init; init.push_back(ptr); init.push_back(new_length); - Bexpression* bstrslice = - gogo->backend()->constructor_expression(str_btype, init, loc); - - Bexpression* index_error = bad_index->get_backend(context); - return gogo->backend()->conditional_expression(bfn, str_btype, index_error, - crash, bstrslice, loc); + return gogo->backend()->constructor_expression(str_btype, init, loc); } // Export a string index expression. diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h index 3b65e7a..4c743da 100644 --- a/gcc/go/gofrontend/expressions.h +++ b/gcc/go/gofrontend/expressions.h @@ -1059,10 +1059,11 @@ class Expression static Expression* import_expression(Import_expression*, Location); - // Return an expression which checks that VAL, of arbitrary integer type, - // is non-negative and is not more than the maximum integer value. - static Expression* - check_bounds(Expression* val, Location); + // Insert bounds checks for an index expression. + static void + check_bounds(Expression* val, Operator, Expression* bound, Runtime::Function, + Runtime::Function, Runtime::Function, Runtime::Function, + Statement_inserter*, Location); // Return an expression for constructing a direct interface type from a // pointer. @@ -2998,7 +2999,7 @@ class Array_index_expression : public Expression Expression* end, Expression* cap, Location location) : Expression(EXPRESSION_ARRAY_INDEX, location), array_(array), start_(start), end_(end), cap_(cap), type_(NULL), - is_lvalue_(false), needs_bounds_check_(true) + is_lvalue_(false), needs_bounds_check_(true), is_flattened_(false) { } // Return the array. @@ -3121,6 +3122,8 @@ class Array_index_expression : public Expression bool is_lvalue_; // Whether bounds check is needed. bool needs_bounds_check_; + // Whether this has already been flattened. + bool is_flattened_; }; // A string index. This is used for both indexing and slicing. @@ -3131,7 +3134,7 @@ class String_index_expression : public Expression String_index_expression(Expression* string, Expression* start, Expression* end, Location location) : Expression(EXPRESSION_STRING_INDEX, location), - string_(string), start_(start), end_(end) + string_(string), start_(start), end_(end), is_flattened_(false) { } // Return the string being indexed. @@ -3203,6 +3206,8 @@ class String_index_expression : public Expression // The end index of a slice. This may be NULL for a single index, // or it may be a nil expression for the length of the string. Expression* end_; + // Whether this has already been flattened. + bool is_flattened_; }; // An index into a map. diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 8a24070..7aec0cf 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -6300,6 +6300,7 @@ Function_declaration::get_or_make_decl(Gogo* gogo, Named_object* no) } if (this->asm_name_ == "runtime.gopanic" + || this->asm_name_.compare(0, 15, "runtime.goPanic") == 0 || this->asm_name_ == "__go_runtime_error" || this->asm_name_ == "runtime.panicdottype" || this->asm_name_ == "runtime.block") diff --git a/gcc/go/gofrontend/runtime.cc b/gcc/go/gofrontend/runtime.cc index e35658b..3cc5ded 100644 --- a/gcc/go/gofrontend/runtime.cc +++ b/gcc/go/gofrontend/runtime.cc @@ -30,6 +30,8 @@ enum Runtime_function_type RFT_BOOLPTR, // Go type int, C type intgo. RFT_INT, + // Go type uint, C type uintgo. + RFT_UINT, // Go type uint8, C type uint8_t. RFT_UINT8, // Go type uint16, C type uint16_t. @@ -113,6 +115,10 @@ runtime_function_type(Runtime_function_type bft) t = Type::lookup_integer_type("int"); break; + case RFT_UINT: + t = Type::lookup_integer_type("uint"); + break; + case RFT_UINT8: t = Type::lookup_integer_type("uint8"); break; @@ -262,6 +268,7 @@ convert_to_runtime_function_type(Runtime_function_type bft, Expression* e, case RFT_BOOL: case RFT_BOOLPTR: case RFT_INT: + case RFT_UINT: case RFT_UINT8: case RFT_UINT16: case RFT_INT32: diff --git a/gcc/go/gofrontend/runtime.def b/gcc/go/gofrontend/runtime.def index 7eac880..d7f5ee2 100644 --- a/gcc/go/gofrontend/runtime.def +++ b/gcc/go/gofrontend/runtime.def @@ -499,6 +499,75 @@ DEF_GO_RUNTIME(ATOMIC_OR_FETCH_1, "__atomic_or_fetch_1", P3(POINTER, UINT8, INT32), R1(UINT8)) +// Panics reporting an index or slice out of bounds error. +DEF_GO_RUNTIME(PANIC_INDEX, "runtime.goPanicIndex", + P2(INT, INT), R0()) +DEF_GO_RUNTIME(PANIC_INDEX_U, "runtime.goPanicIndexU", + P2(UINT, INT), R0()) +DEF_GO_RUNTIME(PANIC_SLICE_ALEN, "runtime.goPanicSliceAlen", + P2(INT, INT), R0()) +DEF_GO_RUNTIME(PANIC_SLICE_ALEN_U, "runtime.goPanicSliceAlenU", + P2(UINT, INT), R0()) +DEF_GO_RUNTIME(PANIC_SLICE_ACAP, "runtime.goPanicSliceAcap", + P2(INT, INT), R0()) +DEF_GO_RUNTIME(PANIC_SLICE_ACAP_U, "runtime.goPanicSliceAcapU", + P2(UINT, INT), R0()) +DEF_GO_RUNTIME(PANIC_SLICE_B, "runtime.goPanicSliceB", + P2(INT, INT), R0()) +DEF_GO_RUNTIME(PANIC_SLICE_B_U, "runtime.goPanicSliceBU", + P2(UINT, INT), R0()) +DEF_GO_RUNTIME(PANIC_SLICE3_ALEN, "runtime.goPanicSlice3Alen", + P2(INT, INT), R0()) +DEF_GO_RUNTIME(PANIC_SLICE3_ALEN_U, "runtime.goPanicSlice3AlenU", + P2(UINT, INT), R0()) +DEF_GO_RUNTIME(PANIC_SLICE3_ACAP, "runtime.goPanicSlice3Acap", + P2(INT, INT), R0()) +DEF_GO_RUNTIME(PANIC_SLICE3_ACAP_U, "runtime.goPanicSlice3AcapU", + P2(UINT, INT), R0()) +DEF_GO_RUNTIME(PANIC_SLICE3_B, "runtime.goPanicSlice3B", + P2(INT, INT), R0()) +DEF_GO_RUNTIME(PANIC_SLICE3_B_U, "runtime.goPanicSlice3BU", + P2(UINT, INT), R0()) +DEF_GO_RUNTIME(PANIC_SLICE3_C, "runtime.goPanicSlice3C", + P2(INT, INT), R0()) +DEF_GO_RUNTIME(PANIC_SLICE3_C_U, "runtime.goPanicSlice3CU", + P2(UINT, INT), R0()) + +// Panics reporting an index or slice out of bounds error with a +// 64-bit index type. These are only used by 32-bit targets. +DEF_GO_RUNTIME(PANIC_EXTEND_INDEX, "runtime.goPanicExtendIndex", + P2(INT64, INT), R0()) +DEF_GO_RUNTIME(PANIC_EXTEND_INDEX_U, "runtime.goPanicExtendIndexU", + P2(UINT64, INT), R0()) +DEF_GO_RUNTIME(PANIC_EXTEND_SLICE_ALEN, "runtime.goPanicExtendSliceAlen", + P2(INT64, INT), R0()) +DEF_GO_RUNTIME(PANIC_EXTEND_SLICE_ALEN_U, "runtime.goPanicExtendSliceAlenU", + P2(UINT64, INT), R0()) +DEF_GO_RUNTIME(PANIC_EXTEND_SLICE_ACAP, "runtime.goPanicExtendSliceAcap", + P2(INT64, INT), R0()) +DEF_GO_RUNTIME(PANIC_EXTEND_SLICE_ACAP_U, "runtime.goPanicExtendSliceAcapU", + P2(UINT64, INT), R0()) +DEF_GO_RUNTIME(PANIC_EXTEND_SLICE_B, "runtime.goPanicExtendSliceB", + P2(INT64, INT), R0()) +DEF_GO_RUNTIME(PANIC_EXTEND_SLICE_B_U, "runtime.goPanicExtendSliceBU", + P2(UINT64, INT), R0()) +DEF_GO_RUNTIME(PANIC_EXTEND_SLICE3_ALEN, "runtime.goPanicExtendSlice3Alen", + P2(INT64, INT), R0()) +DEF_GO_RUNTIME(PANIC_EXTEND_SLICE3_ALEN_U, "runtime.goPanicExtendSlice3AlenU", + P2(UINT64, INT), R0()) +DEF_GO_RUNTIME(PANIC_EXTEND_SLICE3_ACAP, "runtime.goPanicExtendSlice3Acap", + P2(INT64, INT), R0()) +DEF_GO_RUNTIME(PANIC_EXTEND_SLICE3_ACAP_U, "runtime.goPanicExtendSlice3AcapU", + P2(UINT64, INT), R0()) +DEF_GO_RUNTIME(PANIC_EXTEND_SLICE3_B, "runtime.goPanicExtendSlice3B", + P2(INT64, INT), R0()) +DEF_GO_RUNTIME(PANIC_EXTEND_SLICE3_B_U, "runtime.goPanicExtendSlice3BU", + P2(UINT64, INT), R0()) +DEF_GO_RUNTIME(PANIC_EXTEND_SLICE3_C, "runtime.goPanicExtendSlice3C", + P2(INT64, INT), R0()) +DEF_GO_RUNTIME(PANIC_EXTEND_SLICE3_C_U, "runtime.goPanicExtendSlice3CU", + P2(UINT64, INT), R0()) + // Remove helper macros. #undef ABFT6 #undef ABFT2 -- cgit v1.1 From 4ee38894afaf5839960e9c4750672c4f904575fe Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 28 Aug 2019 18:45:45 +0000 Subject: compiler: handle unsafe conversion expression in escape analysis Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/192037 From-SVN: r275000 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/escape.cc | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index f596a69..54a5935 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -189ff44b2c26f29f41f0eb159e0d8f3fa508ecae +5d15923ada640befb236d5fe94f0c724e98e99d7 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/escape.cc b/gcc/go/gofrontend/escape.cc index 4cfb480..db3afc7 100644 --- a/gcc/go/gofrontend/escape.cc +++ b/gcc/go/gofrontend/escape.cc @@ -1706,6 +1706,15 @@ Escape_analysis_assign::expression(Expression** pexpr) } break; + case Expression::EXPRESSION_UNSAFE_CONVERSION: + { + Unsafe_type_conversion_expression* uce = + (*pexpr)->unsafe_conversion_expression(); + Node* expr_node = Node::make_node(uce->expr()); + this->assign(n, expr_node); + } + break; + case Expression::EXPRESSION_FIXED_ARRAY_CONSTRUCTION: case Expression::EXPRESSION_SLICE_CONSTRUCTION: { -- cgit v1.1 From ab0f6d4c5fa6880d5461e2b6bad1879d6a84744f Mon Sep 17 00:00:00 2001 From: "Steven G. Kargl" Date: Wed, 28 Aug 2019 19:54:23 +0000 Subject: re PR fortran/91564 (ICE in gimplify_expr, at gimplify.c:14147) 2019-08-28 Steven G. Kargl PR fortran/91564 * check.c (gfc_check_kill_sub): Additional checks on status dummy argument. 2019-08-28 Steven G. Kargl PR fortran/91564 * gfortran.dg/pr91564.f90: New test. From-SVN: r275005 --- gcc/fortran/ChangeLog | 6 ++++++ gcc/fortran/check.c | 16 ++++++++++++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gfortran.dg/pr91564.f90 | 16 ++++++++++++++++ 4 files changed, 43 insertions(+) create mode 100644 gcc/testsuite/gfortran.dg/pr91564.f90 (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 6b760ce..b118913 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,9 @@ +2019-08-28 Steven G. Kargl + + PR fortran/91564 + * check.c (gfc_check_kill_sub): Additional checks on status dummy + argument. + 2019-08-28 Mark Eggleston * intrinsics.text: Corrected stated standard for intrinsics diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c index 2bd8bc3..a04f9fb 100644 --- a/gcc/fortran/check.c +++ b/gcc/fortran/check.c @@ -3301,6 +3301,22 @@ gfc_check_kill_sub (gfc_expr *pid, gfc_expr *sig, gfc_expr *status) if (!scalar_check (status, 2)) return false; + + if (status->expr_type != EXPR_VARIABLE) + { + gfc_error ("STATUS at %L shall be an INTENT(OUT) variable", + &status->where); + return false; + } + + if (status->expr_type == EXPR_VARIABLE + && status->symtree && status->symtree->n.sym + && status->symtree->n.sym->attr.intent == INTENT_IN) + { + gfc_error ("%qs at %L shall be an INTENT(OUT) variable", + status->symtree->name, &status->where); + return false; + } } return true; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0e7c31b..06d8b1b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-08-28 Steven G. Kargl + + PR fortran/91564 + * gfortran.dg/pr91564.f90: New test. + 2019-08-28 Martin Sebor PR tree-optimization/91457 diff --git a/gcc/testsuite/gfortran.dg/pr91564.f90 b/gcc/testsuite/gfortran.dg/pr91564.f90 new file mode 100644 index 0000000..57783ab --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr91564.f90 @@ -0,0 +1,16 @@ +! { dg-do compile } +! PR fortran/91564 +! Contributed by Gerhard Steinmetz. +program p + integer i, j + call kill (1, 2, 3) ! { dg-error "shall be an INTENT" } + i = 42 + call bar(i, j) +end + +subroutine bar(n, m) + integer, intent(in) :: n + integer, intent(inout) :: m + call kill (1, 3, n) ! { dg-error "shall be an INTENT" } + call kill (1, 3, m) +end subroutine bar -- cgit v1.1 From 6e12721acde2080202889b3839acca52646b0d28 Mon Sep 17 00:00:00 2001 From: "Steven G. Kargl" Date: Wed, 28 Aug 2019 20:16:57 +0000 Subject: re PR fortran/91565 (ICE in gfc_simplify_reshape, at fortran/simplify.c:6707 etc.) 2019-08-28 Steven G. Kargl PR fortran/91565 * simplify.c (gfc_simplify_reshape): Add additional checks of the ORDER dummy argument. 2019-08-28 Steven G. Kargl PR fortran/91565 * gfortran.dg/pr91565.f90: New test. From-SVN: r275007 --- gcc/fortran/ChangeLog | 6 ++++++ gcc/fortran/simplify.c | 34 +++++++++++++++++++++++++++++++--- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gfortran.dg/pr91565.f90 | 17 +++++++++++++++++ 4 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/pr91565.f90 (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index b118913..5e3d7b9 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,5 +1,11 @@ 2019-08-28 Steven G. Kargl + PR fortran/91565 + * simplify.c (gfc_simplify_reshape): Add additional checks of the + ORDER dummy argument. + +2019-08-28 Steven G. Kargl + PR fortran/91564 * check.c (gfc_check_kill_sub): Additional checks on status dummy argument. diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c index 5ab7c81..7fc18d5 100644 --- a/gcc/fortran/simplify.c +++ b/gcc/fortran/simplify.c @@ -6668,6 +6668,9 @@ gfc_simplify_reshape (gfc_expr *source, gfc_expr *shape_exp, mpz_init (index); rank = 0; + for (i = 0; i < GFC_MAX_DIMENSIONS; i++) + x[i] = 0; + for (;;) { e = gfc_constructor_lookup_expr (shape_exp->value.constructor, rank); @@ -6692,8 +6695,28 @@ gfc_simplify_reshape (gfc_expr *source, gfc_expr *shape_exp, } else { - for (i = 0; i < rank; i++) - x[i] = 0; + mpz_t size; + int order_size, shape_size; + + if (order_exp->rank != shape_exp->rank) + { + gfc_error ("Shapes of ORDER at %L and SHAPE at %L are different", + &order_exp->where, &shape_exp->where); + return &gfc_bad_expr; + } + + gfc_array_size (shape_exp, &size); + shape_size = mpz_get_ui (size); + mpz_clear (size); + gfc_array_size (order_exp, &size); + order_size = mpz_get_ui (size); + mpz_clear (size); + if (order_size != shape_size) + { + gfc_error ("Sizes of ORDER at %L and SHAPE at %L are different", + &order_exp->where, &shape_exp->where); + return &gfc_bad_expr; + } for (i = 0; i < rank; i++) { @@ -6704,7 +6727,12 @@ gfc_simplify_reshape (gfc_expr *source, gfc_expr *shape_exp, gcc_assert (order[i] >= 1 && order[i] <= rank); order[i]--; - gcc_assert (x[order[i]] == 0); + if (x[order[i]] != 0) + { + gfc_error ("ORDER at %L is not a permutation of the size of " + "SHAPE at %L", &order_exp->where, &shape_exp->where); + return &gfc_bad_expr; + } x[order[i]] = 1; } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 06d8b1b..7dc95f3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2019-08-28 Steven G. Kargl + PR fortran/91565 + * gfortran.dg/pr91565.f90: New test. + +2019-08-28 Steven G. Kargl + PR fortran/91564 * gfortran.dg/pr91564.f90: New test. diff --git a/gcc/testsuite/gfortran.dg/pr91565.f90 b/gcc/testsuite/gfortran.dg/pr91565.f90 new file mode 100644 index 0000000..b43a57a --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr91565.f90 @@ -0,0 +1,17 @@ +! { dg-do compile } +! PR fortran/91565 +! Contributed by Gerhard Steinmetz +program p + integer, parameter :: a(2) = [2,2] ! { dg-error "\(1\)" } + print *, reshape([1,2,3,4,5,6], [2,3], order=a) ! { dg-error "not a permutation" } +end + +subroutine foo + integer, parameter :: a(1) = 1 ! { dg-error "\(1\)" } + print *, reshape([1,2,3,4,5,6], [2,3], order=a) ! { dg-error "are different" } +end + +subroutine bar + integer, parameter :: a(1,2) = 1 ! { dg-error "\(1\)" } + print *, reshape([1,2,3,4,5,6], [2,3], order=a) ! { dg-error "are different" } +end -- cgit v1.1 From 4742dbe71804b3db099eb0eb8620dff2c79a71cf Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Wed, 28 Aug 2019 20:31:31 +0000 Subject: PR c++/91360 - Implement C++20 P1143R2: constinit. * c-common.c (c_common_reswords): Add constinit and __constinit. (keyword_is_decl_specifier): Handle RID_CONSTINIT. * c-common.h (enum rid): Add RID_CONSTINIT, RID_FIRST_CXX20, and RID_LAST_CXX20. (D_CXX20): Define. * c-cppbuiltin.c (c_cpp_builtins): Define __cpp_constinit. * c-format.c (cxx_keywords): Add "constinit". * c.opt (Wc++2a-compat, Wc++20-compat): New options. * cp-tree.h (TINFO_VAR_DECLARED_CONSTINIT): Define. (LOOKUP_CONSTINIT): Define. (enum cp_decl_spec): Add ds_constinit. * decl.c (check_tag_decl): Give an error for constinit in type declarations. (check_initializer): Also check LOOKUP_CONSTINIT. (cp_finish_decl): Add checking for a constinit declaration. Set TINFO_VAR_DECLARED_CONSTINIT. (grokdeclarator): Add checking for a declaration with the constinit specifier. * lex.c (init_reswords): Handle D_CXX20. * parser.c (cp_lexer_get_preprocessor_token): Pass a better location to warning_at. Warn about C++20 keywords. (cp_keyword_starts_decl_specifier_p): Handle RID_CONSTINIT. (cp_parser_diagnose_invalid_type_name): Add an inform about constinit. (cp_parser_decomposition_declaration): Maybe pass LOOKUP_CONSTINIT to cp_finish_decl. (cp_parser_decl_specifier_seq): Handle RID_CONSTINIT. (cp_parser_init_declarator): Maybe pass LOOKUP_CONSTINIT to cp_finish_decl. (set_and_check_decl_spec_loc): Add "constinit". * pt.c (tsubst_decl): Set TINFO_VAR_DECLARED_CONSTINIT. (instantiate_decl): Maybe pass LOOKUP_CONSTINIT to cp_finish_decl. * typeck2.c (store_init_value): If a constinit variable wasn't initialized using a constant initializer, give an error. * doc/invoke.texi: Document -Wc++20-compat. * g++.dg/cpp2a/constinit1.C: New test. * g++.dg/cpp2a/constinit2.C: New test. * g++.dg/cpp2a/constinit3.C: New test. * g++.dg/cpp2a/constinit4.C: New test. * g++.dg/cpp2a/constinit5.C: New test. * g++.dg/cpp2a/constinit6.C: New test. * g++.dg/cpp2a/constinit7.C: New test. * g++.dg/cpp2a/constinit8.C: New test. * g++.dg/cpp2a/constinit9.C: New test. * g++.dg/cpp2a/constinit10.C: New test. * g++.dg/cpp2a/constinit11.C: New test. * g++.dg/cpp2a/constinit12.C: New test. From-SVN: r275008 --- gcc/ChangeLog | 5 ++ gcc/c-family/ChangeLog | 12 +++++ gcc/c-family/c-common.c | 8 +++- gcc/c-family/c-common.h | 6 +++ gcc/c-family/c-cppbuiltin.c | 1 + gcc/c-family/c-format.c | 1 + gcc/c-family/c.opt | 7 +++ gcc/cp/ChangeLog | 29 ++++++++++++ gcc/cp/cp-tree.h | 9 ++++ gcc/cp/decl.c | 71 +++++++++++++++++++++++++--- gcc/cp/lex.c | 2 + gcc/cp/parser.c | 44 +++++++++++++++--- gcc/cp/pt.c | 8 +++- gcc/cp/typeck2.c | 17 ++++++- gcc/doc/invoke.texi | 7 +++ gcc/testsuite/ChangeLog | 16 +++++++ gcc/testsuite/g++.dg/cpp2a/constinit1.C | 38 +++++++++++++++ gcc/testsuite/g++.dg/cpp2a/constinit10.C | 26 +++++++++++ gcc/testsuite/g++.dg/cpp2a/constinit11.C | 79 ++++++++++++++++++++++++++++++++ gcc/testsuite/g++.dg/cpp2a/constinit12.C | 14 ++++++ gcc/testsuite/g++.dg/cpp2a/constinit2.C | 14 ++++++ gcc/testsuite/g++.dg/cpp2a/constinit3.C | 58 +++++++++++++++++++++++ gcc/testsuite/g++.dg/cpp2a/constinit4.C | 16 +++++++ gcc/testsuite/g++.dg/cpp2a/constinit5.C | 27 +++++++++++ gcc/testsuite/g++.dg/cpp2a/constinit6.C | 5 ++ gcc/testsuite/g++.dg/cpp2a/constinit7.C | 11 +++++ gcc/testsuite/g++.dg/cpp2a/constinit8.C | 18 ++++++++ gcc/testsuite/g++.dg/cpp2a/constinit9.C | 24 ++++++++++ 28 files changed, 556 insertions(+), 17 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/constinit1.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/constinit10.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/constinit11.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/constinit12.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/constinit2.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/constinit3.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/constinit4.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/constinit5.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/constinit6.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/constinit7.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/constinit8.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/constinit9.C (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 77dbf87..8b5ccd2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-08-28 Marek Polacek + + PR c++/91360 - Implement C++20 P1143R2: constinit. + * doc/invoke.texi: Document -Wc++20-compat. + 2019-08-28 Martin Sebor PR tree-optimization/91457 diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 0376a7b..d0a19e3 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,15 @@ +2019-08-28 Marek Polacek + + PR c++/91360 - Implement C++20 P1143R2: constinit. + * c-common.c (c_common_reswords): Add constinit and __constinit. + (keyword_is_decl_specifier): Handle RID_CONSTINIT. + * c-common.h (enum rid): Add RID_CONSTINIT, RID_FIRST_CXX20, and + RID_LAST_CXX20. + (D_CXX20): Define. + * c-cppbuiltin.c (c_cpp_builtins): Define __cpp_constinit. + * c-format.c (cxx_keywords): Add "constinit". + * c.opt (Wc++2a-compat, Wc++20-compat): New options. + 2019-08-27 Jakub Jelinek PR c++/91415 diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 61ee754..abc85cb 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -326,8 +326,9 @@ static bool nonnull_check_p (tree, unsigned HOST_WIDE_INT); C --std=c89: D_C99 | D_CXXONLY | D_OBJC | D_CXX_OBJC C --std=c99: D_CXXONLY | D_OBJC ObjC is like C except that D_OBJC and D_CXX_OBJC are not set - C++ --std=c++98: D_CONLY | D_CXX11 | D_OBJC - C++ --std=c++11: D_CONLY | D_OBJC + C++ --std=c++98: D_CONLY | D_CXX11 | D_CXX20 | D_OBJC + C++ --std=c++11: D_CONLY | D_CXX20 | D_OBJC + C++ --std=c++2a: D_CONLY | D_OBJC ObjC++ is like C++ except that D_OBJC is not set If -fno-asm is used, D_ASM is added to the mask. If @@ -392,6 +393,7 @@ const struct c_common_resword c_common_reswords[] = { "__complex__", RID_COMPLEX, 0 }, { "__const", RID_CONST, 0 }, { "__const__", RID_CONST, 0 }, + { "__constinit", RID_CONSTINIT, D_CXXONLY }, { "__decltype", RID_DECLTYPE, D_CXXONLY }, { "__direct_bases", RID_DIRECT_BASES, D_CXXONLY }, { "__extension__", RID_EXTENSION, 0 }, @@ -462,6 +464,7 @@ const struct c_common_resword c_common_reswords[] = { "class", RID_CLASS, D_CXX_OBJC | D_CXXWARN }, { "const", RID_CONST, 0 }, { "constexpr", RID_CONSTEXPR, D_CXXONLY | D_CXX11 | D_CXXWARN }, + { "constinit", RID_CONSTINIT, D_CXXONLY | D_CXX20 | D_CXXWARN }, { "const_cast", RID_CONSTCAST, D_CXXONLY | D_CXXWARN }, { "continue", RID_CONTINUE, 0 }, { "decltype", RID_DECLTYPE, D_CXXONLY | D_CXX11 | D_CXXWARN }, @@ -7927,6 +7930,7 @@ keyword_is_decl_specifier (enum rid keyword) case RID_TYPEDEF: case RID_FRIEND: case RID_CONSTEXPR: + case RID_CONSTINIT: return true; default: return false; diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 117d729..17bd7b1 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -180,6 +180,9 @@ enum rid /* C++11 */ RID_CONSTEXPR, RID_DECLTYPE, RID_NOEXCEPT, RID_NULLPTR, RID_STATIC_ASSERT, + /* C++20 */ + RID_CONSTINIT, + /* char8_t */ RID_CHAR8, @@ -250,6 +253,8 @@ enum rid RID_FIRST_CXX11 = RID_CONSTEXPR, RID_LAST_CXX11 = RID_STATIC_ASSERT, + RID_FIRST_CXX20 = RID_CONSTINIT, + RID_LAST_CXX20 = RID_CONSTINIT, RID_FIRST_AT = RID_AT_ENCODE, RID_LAST_AT = RID_AT_IMPLEMENTATION, RID_FIRST_PQ = RID_IN, @@ -427,6 +432,7 @@ extern machine_mode c_default_pointer_mode; #define D_CXX_CONCEPTS 0x0400 /* In C++, only with concepts. */ #define D_TRANSMEM 0X0800 /* C++ transactional memory TS. */ #define D_CXX_CHAR8_T 0X1000 /* In C++, only with -fchar8_t. */ +#define D_CXX20 0x2000 /* In C++, C++20 only. */ #define D_CXX_CONCEPTS_FLAGS D_CXXONLY | D_CXX_CONCEPTS #define D_CXX_CHAR8_T_FLAGS D_CXXONLY | D_CXX_CHAR8_T diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c index 6006e95..6b18246 100644 --- a/gcc/c-family/c-cppbuiltin.c +++ b/gcc/c-family/c-cppbuiltin.c @@ -986,6 +986,7 @@ c_cpp_builtins (cpp_reader *pfile) { /* Set feature test macros for C++2a. */ cpp_define (pfile, "__cpp_conditional_explicit=201806"); + cpp_define (pfile, "__cpp_constinit=201907"); cpp_define (pfile, "__cpp_nontype_template_parameter_class=201806"); cpp_define (pfile, "__cpp_impl_destroying_delete=201806"); } diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c index 6b05996..91bae3d 100644 --- a/gcc/c-family/c-format.c +++ b/gcc/c-family/c-format.c @@ -2958,6 +2958,7 @@ static const token_t cxx_keywords[] = NAME ("catch", NULL), NAME ("constexpr if", NULL), NAME ("constexpr", NULL), + NAME ("constinit", NULL), NAME ("consteval", NULL), NAME ("decltype", NULL), NAME ("nullptr", NULL), diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 257cadf..4c468d0 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -400,6 +400,13 @@ Wc++17-compat C++ ObjC++ Var(warn_cxx17_compat) Warning LangEnabledBy(C++ ObjC++,Wall) Warn about C++ constructs whose meaning differs between ISO C++ 2014 and ISO C++ 2017. +Wc++2a-compat +C++ ObjC++ Warning Alias(Wc++20-compat) Undocumented + +Wc++20-compat +C++ ObjC++ Var(warn_cxx20_compat) Warning LangEnabledBy(C++ ObjC++,Wall) +Warn about C++ constructs whose meaning differs between ISO C++ 2017 and ISO C++ 2020. + Wcast-function-type C ObjC C++ ObjC++ Var(warn_cast_function_type) Warning EnabledBy(Wextra) Warn about casts between incompatible function types. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 08a44b6..2e7c26c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,32 @@ +2019-08-28 Marek Polacek + + PR c++/91360 - Implement C++20 P1143R2: constinit. + * cp-tree.h (TINFO_VAR_DECLARED_CONSTINIT): Define. + (LOOKUP_CONSTINIT): Define. + (enum cp_decl_spec): Add ds_constinit. + * decl.c (check_tag_decl): Give an error for constinit in type + declarations. + (check_initializer): Also check LOOKUP_CONSTINIT. + (cp_finish_decl): Add checking for a constinit declaration. Set + TINFO_VAR_DECLARED_CONSTINIT. + (grokdeclarator): Add checking for a declaration with the constinit + specifier. + * lex.c (init_reswords): Handle D_CXX20. + * parser.c (cp_lexer_get_preprocessor_token): Pass a better location + to warning_at. Warn about C++20 keywords. + (cp_keyword_starts_decl_specifier_p): Handle RID_CONSTINIT. + (cp_parser_diagnose_invalid_type_name): Add an inform about constinit. + (cp_parser_decomposition_declaration): Maybe pass LOOKUP_CONSTINIT to + cp_finish_decl. + (cp_parser_decl_specifier_seq): Handle RID_CONSTINIT. + (cp_parser_init_declarator): Maybe pass LOOKUP_CONSTINIT to + cp_finish_decl. + (set_and_check_decl_spec_loc): Add "constinit". + * pt.c (tsubst_decl): Set TINFO_VAR_DECLARED_CONSTINIT. + (instantiate_decl): Maybe pass LOOKUP_CONSTINIT to cp_finish_decl. + * typeck2.c (store_init_value): If a constinit variable wasn't + initialized using a constant initializer, give an error. + 2019-08-28 Nathan Sidwell PR c++/90613 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 225dbb6..0e514d5 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -443,6 +443,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; SWITCH_STMT_NO_BREAK_P (in SWITCH_STMT) LAMBDA_EXPR_CAPTURE_OPTIMIZED (in LAMBDA_EXPR) IMPLICIT_CONV_EXPR_BRACED_INIT (in IMPLICIT_CONV_EXPR) + TINFO_VAR_DECLARED_CONSTINIT (in TEMPLATE_INFO) 3: (TREE_REFERENCE_EXPR) (in NON_LVALUE_EXPR) (commented-out). ICS_BAD_FLAG (in _CONV) FN_TRY_BLOCK_P (in TRY_BLOCK) @@ -1435,6 +1436,11 @@ typedef struct qualified_typedef_usage_s qualified_typedef_usage_t; #define TINFO_USED_TEMPLATE_ID(NODE) \ (TREE_LANG_FLAG_1 (TEMPLATE_INFO_CHECK (NODE))) +/* Non-zero if this variable template specialization was declared with the + `constinit' specifier. */ +#define TINFO_VAR_DECLARED_CONSTINIT(NODE) \ + (TREE_LANG_FLAG_2 (TEMPLATE_INFO_CHECK (NODE))) + struct GTY(()) tree_template_info { struct tree_base base; tree tmpl; @@ -5502,6 +5508,8 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG }; #define LOOKUP_DELEGATING_CONS (LOOKUP_NO_NON_INTEGRAL << 1) /* Allow initialization of a flexible array members. */ #define LOOKUP_ALLOW_FLEXARRAY_INIT (LOOKUP_DELEGATING_CONS << 1) +/* Require constant initialization of a non-constant variable. */ +#define LOOKUP_CONSTINIT (LOOKUP_ALLOW_FLEXARRAY_INIT << 1) #define LOOKUP_NAMESPACES_ONLY(F) \ (((F) & LOOKUP_PREFER_NAMESPACES) && !((F) & LOOKUP_PREFER_TYPES)) @@ -5815,6 +5823,7 @@ enum cp_decl_spec { ds_alias, ds_constexpr, ds_complex, + ds_constinit, ds_thread, ds_type_spec, ds_redefined_builtin_type_spec, diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 8478170..c5cc22a 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -4962,6 +4962,9 @@ check_tag_decl (cp_decl_specifier_seq *declspecs, else if (decl_spec_seq_has_spec_p (declspecs, ds_constexpr)) error_at (declspecs->locations[ds_constexpr], "% cannot be used for type declarations"); + else if (decl_spec_seq_has_spec_p (declspecs, ds_constinit)) + error_at (declspecs->locations[ds_constinit], + "% cannot be used for type declarations"); } if (declspecs->attributes && warn_attributes && declared_type) @@ -6595,11 +6598,12 @@ check_initializer (tree decl, tree init, int flags, vec **cleanups) about aggregate initialization of non-aggregate classes. */ flags |= LOOKUP_ALREADY_DIGESTED; } - else if (DECL_DECLARED_CONSTEXPR_P (decl)) + else if (DECL_DECLARED_CONSTEXPR_P (decl) + || (flags & LOOKUP_CONSTINIT)) { - /* Declared constexpr, but no suitable initializer; massage - init appropriately so we can pass it into store_init_value - for the error. */ + /* Declared constexpr or constinit, but no suitable initializer; + massage init appropriately so we can pass it into + store_init_value for the error. */ if (CLASS_TYPE_P (type) && (!init || TREE_CODE (init) == TREE_LIST)) { @@ -7162,6 +7166,10 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, DECL_INITIAL (decl) = NULL_TREE; } + /* Handle `constinit' on variable templates. */ + if (flags & LOOKUP_CONSTINIT) + TINFO_VAR_DECLARED_CONSTINIT (DECL_TEMPLATE_INFO (decl)) = true; + /* Generally, initializers in templates are expanded when the template is instantiated. But, if DECL is a variable constant then it can be used in future constant expressions, so its value @@ -7253,6 +7261,18 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, if (VAR_P (decl)) { + duration_kind dk = decl_storage_duration (decl); + /* [dcl.constinit]/1 "The constinit specifier shall be applied + only to a declaration of a variable with static or thread storage + duration." */ + if ((flags & LOOKUP_CONSTINIT) + && !(dk == dk_thread || dk == dk_static)) + { + error ("% can only be applied to a variable with static " + "or thread storage duration"); + return; + } + /* If this is a local variable that will need a mangled name, register it now. We must do this before processing the initializer for the variable, since the initialization might @@ -10477,6 +10497,7 @@ grokdeclarator (const cp_declarator *declarator, bool template_parm_flag = false; bool typedef_p = decl_spec_seq_has_spec_p (declspecs, ds_typedef); bool constexpr_p = decl_spec_seq_has_spec_p (declspecs, ds_constexpr); + bool constinit_p = decl_spec_seq_has_spec_p (declspecs, ds_constinit); bool late_return_type_p = false; bool array_parameter_p = false; location_t saved_loc = input_location; @@ -10763,6 +10784,24 @@ grokdeclarator (const cp_declarator *declarator, return error_mark_node; } + if (constinit_p && typedef_p) + { + error_at (declspecs->locations[ds_constinit], + "% cannot appear in a typedef declaration"); + return error_mark_node; + } + + /* [dcl.spec]/2 "At most one of the constexpr, consteval, and constinit + keywords shall appear in a decl-specifier-seq." */ + if (constinit_p && constexpr_p) + { + error_at (min_location (declspecs->locations[ds_constinit], + declspecs->locations[ds_constexpr]), + "can use at most one of the % and % " + "specifiers"); + return error_mark_node; + } + /* If there were multiple types specified in the decl-specifier-seq, issue an error message. */ if (declspecs->multiple_types_p) @@ -11155,6 +11194,12 @@ grokdeclarator (const cp_declarator *declarator, "a parameter cannot be declared %"); constexpr_p = 0; } + else if (constinit_p) + { + error_at (declspecs->locations[ds_constinit], + "a parameter cannot be declared %"); + constexpr_p = 0; + } } /* Give error if `virtual' is used outside of class declaration. */ @@ -11597,6 +11642,13 @@ grokdeclarator (const cp_declarator *declarator, "an array", name); return error_mark_node; } + if (constinit_p) + { + error_at (declspecs->locations[ds_constinit], + "% on function return type is not " + "allowed"); + return error_mark_node; + } if (ctype == NULL_TREE && decl_context == FIELD @@ -12794,10 +12846,17 @@ grokdeclarator (const cp_declarator *declarator, else if (constexpr_p) { error_at (declspecs->locations[ds_constexpr], - "non-static data member %qE declared %", - unqualified_id); + "non-static data member %qE declared " + "%", unqualified_id); constexpr_p = false; } + else if (constinit_p) + { + error_at (declspecs->locations[ds_constinit], + "non-static data member %qE declared " + "%", unqualified_id); + constinit_p = false; + } decl = build_decl (id_loc, FIELD_DECL, unqualified_id, type); DECL_NONADDRESSABLE_P (decl) = bitfield; if (bitfield && !unqualified_id) diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 12567da..5b43723 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -229,6 +229,8 @@ init_reswords (void) if (cxx_dialect < cxx11) mask |= D_CXX11; + if (cxx_dialect < cxx2a) + mask |= D_CXX20; if (!flag_concepts) mask |= D_CXX_CONCEPTS; if (!flag_tm) diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 3825753..93cdadd 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -834,14 +834,28 @@ cp_lexer_get_preprocessor_token (cp_lexer *lexer, cp_token *token) { /* Warn about the C++0x keyword (but still treat it as an identifier). */ - warning (OPT_Wc__11_compat, - "identifier %qE is a keyword in C++11", - token->u.value); + warning_at (token->location, OPT_Wc__11_compat, + "identifier %qE is a keyword in C++11", + token->u.value); /* Clear out the C_RID_CODE so we don't warn about this particular identifier-turned-keyword again. */ C_SET_RID_CODE (token->u.value, RID_MAX); } + if (warn_cxx20_compat + && C_RID_CODE (token->u.value) >= RID_FIRST_CXX20 + && C_RID_CODE (token->u.value) <= RID_LAST_CXX20) + { + /* Warn about the C++20 keyword (but still treat it as + an identifier). */ + warning_at (token->location, OPT_Wc__20_compat, + "identifier %qE is a keyword in C++20", + token->u.value); + + /* Clear out the C_RID_CODE so we don't warn about this + particular identifier-turned-keyword again. */ + C_SET_RID_CODE (token->u.value, RID_MAX); + } token->keyword = RID_MAX; } @@ -986,6 +1000,7 @@ cp_keyword_starts_decl_specifier_p (enum rid keyword) case RID_DECLTYPE: case RID_UNDERLYING_TYPE: case RID_CONSTEXPR: + case RID_CONSTINIT: return true; default: @@ -3353,6 +3368,9 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree id, && id_equal (id, "thread_local")) inform (location, "C++11 % only available with " "%<-std=c++11%> or %<-std=gnu++11%>"); + else if (cxx_dialect < cxx2a && id == ridpointers[(int)RID_CONSTINIT]) + inform (location, "C++20 % only available with " + "%<-std=c++2a%> or %<-std=gnu++2a%>"); else if (!flag_concepts && id == ridpointers[(int)RID_CONCEPT]) inform (location, "% only available with %<-fconcepts%>"); else if (processing_template_decl && current_class_type @@ -13839,9 +13857,12 @@ cp_parser_decomposition_declaration (cp_parser *parser, if (decl != error_mark_node) { + int flags = (decl_spec_seq_has_spec_p (decl_specifiers, ds_constinit) + ? LOOKUP_CONSTINIT : 0); cp_maybe_mangle_decomp (decl, prev, v.length ()); cp_finish_decl (decl, initializer, non_constant_p, NULL_TREE, - is_direct_init ? LOOKUP_NORMAL : LOOKUP_IMPLICIT); + (is_direct_init ? LOOKUP_NORMAL : LOOKUP_IMPLICIT) + | flags); cp_finish_decomp (decl, prev, v.length ()); } } @@ -13993,7 +14014,8 @@ cp_parser_decl_specifier_seq (cp_parser* parser, { /* decl-specifier: friend - constexpr */ + constexpr + constinit */ case RID_FRIEND: if (!at_class_scope_p ()) { @@ -14015,6 +14037,11 @@ cp_parser_decl_specifier_seq (cp_parser* parser, cp_lexer_consume_token (parser->lexer); break; + case RID_CONSTINIT: + ds = ds_constinit; + cp_lexer_consume_token (parser->lexer); + break; + case RID_CONCEPT: ds = ds_concept; cp_lexer_consume_token (parser->lexer); @@ -20532,6 +20559,8 @@ cp_parser_init_declarator (cp_parser* parser, declarations. */ if (!member_p && decl && decl != error_mark_node && !range_for_decl_p) { + int cf = (decl_spec_seq_has_spec_p (decl_specifiers, ds_constinit) + ? LOOKUP_CONSTINIT : 0); cp_finish_decl (decl, initializer, !is_non_constant_init, asm_specification, @@ -20540,7 +20569,7 @@ cp_parser_init_declarator (cp_parser* parser, `explicit' constructor is OK. Otherwise, an `explicit' constructor cannot be used. */ ((is_direct_init || !is_initialized) - ? LOOKUP_NORMAL : LOOKUP_IMPLICIT)); + ? LOOKUP_NORMAL : LOOKUP_IMPLICIT) | cf); } else if ((cxx_dialect != cxx98) && friend_p && decl && TREE_CODE (decl) == FUNCTION_DECL) @@ -29470,7 +29499,8 @@ set_and_check_decl_spec_loc (cp_decl_specifier_seq *decl_specs, "typedef", "using", "constexpr", - "__complex" + "__complex", + "constinit" }; gcc_rich_location richloc (location); richloc.add_fixit_remove (); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 1758511..54d36f9 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -13955,6 +13955,10 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) DECL_TEMPLATE_INFO (r) = build_template_info (tmpl, argvec); SET_DECL_IMPLICIT_INSTANTIATION (r); + /* Remember whether we require constant initialization of + a non-constant template variable. */ + TINFO_VAR_DECLARED_CONSTINIT (DECL_TEMPLATE_INFO (r)) + = TINFO_VAR_DECLARED_CONSTINIT (DECL_TEMPLATE_INFO (t)); if (!error_operand_p (r) || (complain & tf_error)) register_specialization (r, gen_tmpl, argvec, false, hash); } @@ -24744,7 +24748,9 @@ instantiate_decl (tree d, bool defer_ok, bool expl_inst_class_mem_p) push_nested_class (DECL_CONTEXT (d)); const_init = DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (code_pattern); - cp_finish_decl (d, init, const_init, NULL_TREE, 0); + int flags = (TINFO_VAR_DECLARED_CONSTINIT (DECL_TEMPLATE_INFO (d)) + ? LOOKUP_CONSTINIT : 0); + cp_finish_decl (d, init, const_init, NULL_TREE, flags); if (enter_context) pop_nested_class (); diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 02c3ad5..d5098fa 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -885,7 +885,22 @@ store_init_value (tree decl, tree init, vec** cleanups, int flags) if (!TYPE_REF_P (type)) TREE_CONSTANT (decl) = const_init && decl_maybe_constant_var_p (decl); if (!const_init) - value = oldval; + { + /* [dcl.constinit]/2 "If a variable declared with the constinit + specifier has dynamic initialization, the program is + ill-formed." */ + if (flags & LOOKUP_CONSTINIT) + { + error_at (location_of (decl), + "% variable %qD does not have a constant " + "initializer", decl); + if (require_constant_expression (value)) + cxx_constant_init (value, decl); + value = error_mark_node; + } + else + value = oldval; + } } value = cp_fully_fold_init (value); diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 549e043..1391a56 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -295,6 +295,7 @@ Objective-C and Objective-C++ Dialects}. -Wno-builtin-declaration-mismatch @gol -Wno-builtin-macro-redefined -Wc90-c99-compat -Wc99-c11-compat @gol -Wc++-compat -Wc++11-compat -Wc++14-compat -Wc++17-compat @gol +-Wc++20-compat @gol -Wcast-align -Wcast-align=strict -Wcast-function-type -Wcast-qual @gol -Wchar-subscripts -Wcatch-value -Wcatch-value=@var{n} @gol -Wclobbered -Wcomment -Wconditionally-supported @gol @@ -6792,6 +6793,12 @@ and ISO C++ 2014. This warning is enabled by @option{-Wall}. Warn about C++ constructs whose meaning differs between ISO C++ 2014 and ISO C++ 2017. This warning is enabled by @option{-Wall}. +@item -Wc++20-compat @r{(C++ and Objective-C++ only)} +@opindex Wc++20-compat +@opindex Wno-c++20-compat +Warn about C++ constructs whose meaning differs between ISO C++ 2017 +and ISO C++ 2020. This warning is enabled by @option{-Wall}. + @item -Wcast-qual @opindex Wcast-qual @opindex Wno-cast-qual diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7dc95f3..77fa37f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,19 @@ +2019-08-28 Marek Polacek + + PR c++/91360 - Implement C++20 P1143R2: constinit. + * g++.dg/cpp2a/constinit1.C: New test. + * g++.dg/cpp2a/constinit2.C: New test. + * g++.dg/cpp2a/constinit3.C: New test. + * g++.dg/cpp2a/constinit4.C: New test. + * g++.dg/cpp2a/constinit5.C: New test. + * g++.dg/cpp2a/constinit6.C: New test. + * g++.dg/cpp2a/constinit7.C: New test. + * g++.dg/cpp2a/constinit8.C: New test. + * g++.dg/cpp2a/constinit9.C: New test. + * g++.dg/cpp2a/constinit10.C: New test. + * g++.dg/cpp2a/constinit11.C: New test. + * g++.dg/cpp2a/constinit12.C: New test. + 2019-08-28 Steven G. Kargl PR fortran/91565 diff --git a/gcc/testsuite/g++.dg/cpp2a/constinit1.C b/gcc/testsuite/g++.dg/cpp2a/constinit1.C new file mode 100644 index 0000000..9d1c028 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/constinit1.C @@ -0,0 +1,38 @@ +// PR c++/91360 - Implement C++20 P1143R2: constinit +// { dg-do compile { target c++2a } } +// Test basic usage of 'constinit'. + +const char *g() { return "dynamic init"; } +constexpr const char *f(bool p) { return p ? "constant init" : g(); } // { dg-error "call to non-.constexpr. function" } + +constinit const char *c = f(true); +constinit const char *d = f(false); // { dg-error "variable .d. does not have a constant initializer" } +// { dg-message "in .constexpr. expansion of" "" { target *-*-* } .-1 } +static constinit const char *e = f(true); + +constexpr int foo(int x) { return x; } +constinit int i = foo(42); +constinit int j // { dg-error "variable .j. does not have a constant initializer" } + = foo(i); // { dg-error "not usable in a constant expression" } + +int y = 42; +constinit int x // { dg-error "variable .x. does not have a constant initializer" } + = y; // { dg-error "not usable in a constant expression" } + +constinit int z; +const constinit unsigned cst = 1u; + +void +fn () +{ + static constinit int m = foo(42); + static constinit int n // { dg-error "variable .n. does not have a constant initializer" } + = foo(m); // { dg-error "not usable in a constant expression" } + + // Make sure we can still modify constinit variables. + c = "foo"; + i = 10; + m = 90; + // ... unless they're 'const'. + cst *= 2; // { dg-error "assignment of read-only variable" } +} diff --git a/gcc/testsuite/g++.dg/cpp2a/constinit10.C b/gcc/testsuite/g++.dg/cpp2a/constinit10.C new file mode 100644 index 0000000..a50f285 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/constinit10.C @@ -0,0 +1,26 @@ +// PR c++/91360 - Implement C++20 P1143R2: constinit +// { dg-do compile { target c++2a } } +// From PR83428. + +struct S1 +{ + constexpr S1 (); + int m_i; +}; + +struct alignas(64) S2 +{ + constexpr S2 () + : m_tabS1() + {} + + S1 m_tabS1[7]; +}; + +constinit S2 objX; // { dg-error ".constinit. variable .objX. does not have a constant initializer" } +// { dg-error "used before its definition" "" { target *-*-* } .-1 } +// // { dg-message "in .constexpr. expansion of" "" { target *-*-* } .-2 } + +constexpr S1::S1 () +: m_i(14) +{} diff --git a/gcc/testsuite/g++.dg/cpp2a/constinit11.C b/gcc/testsuite/g++.dg/cpp2a/constinit11.C new file mode 100644 index 0000000..ab3715b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/constinit11.C @@ -0,0 +1,79 @@ +// PR c++/91360 - Implement C++20 P1143R2: constinit +// { dg-do compile { target c++2a } } + +int foo (); +constexpr int constfoo () { return 42; } +int gl = 42; + +struct nonliteral { + int m; + nonliteral() : m() { } + nonliteral(int n) : m(n) { } + ~nonliteral() {} +}; + +struct literal { + int m; + constexpr literal() : m() { } + constexpr literal(int n) : m(n) { } +}; + +struct pod { + int m; +}; + +struct S { + static constinit pod p; + static constinit pod pc; + static const constinit nonliteral n; +}; + +struct W { + int w = 42; +}; + +constinit W w; + +constinit const int &r1 = gl; +constinit thread_local const int &r2 = gl; +constinit const int &r3 // { dg-error "variable .r3. does not have a constant initializer" } + = foo (); // { dg-error "call to non-.constexpr. function" } +constinit const literal &r4 = 42; +constinit const nonliteral &r5 // { dg-error "variable .r5. does not have a constant initializer" } + = 42; // { dg-error "call to non-.constexpr. function" } +constinit const int &r6 = nonliteral(2).m; // { dg-error "variable .r6. does not have a constant initializer|call to non-.constexpr. function" } + +constinit pod p1; +constinit pod p2 = { 42 }; +constinit pod p3 = { constfoo() }; +constinit pod p4 = { foo() }; // { dg-error "variable .p4. does not have a constant initializer|call to non-.constexpr. function" } + +constexpr literal lit; +constinit literal l1 = lit; +constinit literal l2 = 42; +constinit literal l3 = constfoo(); +constinit literal l4 = foo(); // { dg-error "variable .l4. does not have a constant initializer|call to non-.constexpr. function" } +constinit literal l5 = {}; +constinit literal l6{}; +constinit thread_local literal l7 = lit; +constinit thread_local literal l8 = 42; +constinit thread_local literal l9 = constfoo(); +constinit thread_local literal l10 = foo(); // { dg-error "variable .l10. does not have a constant initializer|call to non-.constexpr. function" } +constinit thread_local literal l11{}; + +pod S::p; +constinit pod S::pc(S::p); // { dg-error "variable .S::pc. does not have a constant initializer|not usable" } + +constinit const nonliteral S::n(42); // { dg-error "variable .S::n. does not have a constant initializer|call to non-.constexpr. function" } +constinit int n1 = nonliteral{42}.m; // { dg-error "variable .n1. does not have a constant initializer|temporary of non-literal type" } +constinit int n2 = literal{42}.m; + +void +fn1 () +{ + const int c = 42; + static constinit const int &l // { dg-error "variable .l. does not have a constant initializer" } + = c; // { dg-error "not a constant" } + static const int &l2 = 10; + static const int &l3 = gl; +} diff --git a/gcc/testsuite/g++.dg/cpp2a/constinit12.C b/gcc/testsuite/g++.dg/cpp2a/constinit12.C new file mode 100644 index 0000000..b5b736f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/constinit12.C @@ -0,0 +1,14 @@ +// PR c++/91360 - Implement C++20 P1143R2: constinit +// { dg-do compile { target c++2a } } + +struct S { + S(int) { } +}; + +template +struct U { + T m; + constexpr U(int i) : m(i) { } // { dg-error "call to non-.constexpr. function" } +}; + +constinit U u(42); // { dg-error "does not have a constant initializer|called in a constant expression" } diff --git a/gcc/testsuite/g++.dg/cpp2a/constinit2.C b/gcc/testsuite/g++.dg/cpp2a/constinit2.C new file mode 100644 index 0000000..3e9f578 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/constinit2.C @@ -0,0 +1,14 @@ +// PR c++/91360 - Implement C++20 P1143R2: constinit +// { dg-do compile { target c++11 } } +// Test that 'constinit' isn't recognized pre-C++2a, but '__constinit' is. + +constinit int g = 42; // { dg-error ".constinit. does not name a type" "" { target c++17_down } } +__constinit int g2 = 42; +static __constinit int g3 = 42; + +void +fn () +{ + static constinit int x = 69; // { dg-error ".constinit. does not name a type" "" { target c++17_down } } + static __constinit int x2 = 69; +} diff --git a/gcc/testsuite/g++.dg/cpp2a/constinit3.C b/gcc/testsuite/g++.dg/cpp2a/constinit3.C new file mode 100644 index 0000000..316937e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/constinit3.C @@ -0,0 +1,58 @@ +// PR c++/91360 - Implement C++20 P1143R2: constinit +// { dg-do compile { target c++2a } } + +constinit constinit int v1; // { dg-error "duplicate .constinit." } +constexpr constinit int v2 = 1; // { dg-error "can use at most one of the .constinit. and .constexpr. specifiers" } +constinit constexpr int v3 = 1; // { dg-error "an use at most one of the .constinit. and .constexpr. specifiers" } + +extern static constinit int v4; // { dg-error "conflicting specifiers" } +extern thread_local constinit int v5; +extern constinit int v6; + +constinit typedef int T; // { dg-error ".constinit. cannot appear in a typedef declaration" } + +struct S2 { + constinit int m1; // { dg-error "non-static data member .m1. declared .constinit." } + constinit unsigned int b : 32; // { dg-error " non-static data member .b. declared .constinit." } +}; + +struct S3 { + constinit S3() {} // { dg-error ".constinit. on function return type is not allowed" } + constinit ~S3() {} // { dg-error ".constinit. on function return type is not allowed" } +}; + +constinit struct S4 { // { dg-error ".constinit. cannot be used for type declarations" } +}; + +template // { dg-error "a parameter cannot be declared .constinit." } +struct X { }; + +int +fn1 () +{ + // Not static storage + constinit int a1 = 42; // { dg-error ".constinit. can only be applied to a variable with static or thread storage" } + constinit int a2 = 42; // { dg-error ".constinit. can only be applied to a variable with static or thread storage" } + extern constinit int e1; + + return 0; +} + +constinit int // { dg-error ".constinit. on function return type is not allowed" } +fn3 () +{ +} + +void +fn2 (int i, constinit int p) // { dg-error "a parameter cannot be declared .constinit." } +{ + constinit auto l = [i](){ return i; }; // { dg-error ".constinit. can only be applied to a variable with static or thread storage" } +} + +struct B { int d; }; + +void +fn3 (B b) +{ + constinit auto [ a ] = b; // { dg-error ".constinit. can only be applied to a variable with static or thread storage" } +} diff --git a/gcc/testsuite/g++.dg/cpp2a/constinit4.C b/gcc/testsuite/g++.dg/cpp2a/constinit4.C new file mode 100644 index 0000000..748a7ff --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/constinit4.C @@ -0,0 +1,16 @@ +// PR c++/91360 - Implement C++20 P1143R2: constinit +// { dg-do compile { target c++2a } } + +struct S { }; +constinit extern S s; +constinit S s2 = { }; + +struct T { + int i; +}; + +constinit T t; +struct U : T { + int j; +}; +constinit U u; diff --git a/gcc/testsuite/g++.dg/cpp2a/constinit5.C b/gcc/testsuite/g++.dg/cpp2a/constinit5.C new file mode 100644 index 0000000..3d21f48 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/constinit5.C @@ -0,0 +1,27 @@ +// PR c++/91360 - Implement C++20 P1143R2: constinit +// { dg-do compile { target c++2a } } +// Check that we preserve DECL_DECLARED_CONSTINIT_P in duplicate_decls. + +int gl = 42; + +struct S { + constinit static int m; + constinit static int n; + constinit static const int &r1; + constinit static const int &r2; +}; + +int S::m = 42; +int nonconst; +constinit int S::n = nonconst; // { dg-error "variable .S::n. does not have a constant initializer" } +// { dg-error "not usable in a constant expression" "" { target *-*-* } .-1 } + +const int &S::r1 = gl; +const int &S::r2 = 42; + +struct T { + constinit static thread_local const int &r1; + constinit static thread_local const int &r2; +}; +constinit thread_local const int &T::r1 = gl; +constinit thread_local const int &T::r2 = 42; // { dg-error "variable .T::r2. does not have a constant initializer|not a constant expression" } diff --git a/gcc/testsuite/g++.dg/cpp2a/constinit6.C b/gcc/testsuite/g++.dg/cpp2a/constinit6.C new file mode 100644 index 0000000..73e7883 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/constinit6.C @@ -0,0 +1,5 @@ +// PR c++/91360 - Implement C++20 P1143R2: constinit +// { dg-do compile { target c++17_down } } +// { dg-options "-Wc++20-compat" } + +int constinit; // { dg-warning "identifier .constinit. is a keyword" } diff --git a/gcc/testsuite/g++.dg/cpp2a/constinit7.C b/gcc/testsuite/g++.dg/cpp2a/constinit7.C new file mode 100644 index 0000000..e9a0da3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/constinit7.C @@ -0,0 +1,11 @@ +// PR c++/91360 - Implement C++20 P1143R2: constinit +// { dg-do compile { target c++11 } } + +struct T { + constexpr T(int) {} + ~T(); +}; +__constinit T x = { 42 }; +// ??? This should be rejected in C++14: copy initialization is not a constant +// expression on a non-literal type in C++14. But 'constinit' is C++20 only. +__constinit T y = 42; diff --git a/gcc/testsuite/g++.dg/cpp2a/constinit8.C b/gcc/testsuite/g++.dg/cpp2a/constinit8.C new file mode 100644 index 0000000..c6b2975 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/constinit8.C @@ -0,0 +1,18 @@ +// PR c++/91360 - Implement C++20 P1143R2: constinit +// { dg-do compile { target c++2a } } +// Variable templates. + +int nonconst; + +template +constinit T v1 = 42; + +template +constinit T v2 = nonconst; // { dg-error "does not have a constant initializer|not usable" } + +void +fn () +{ + v1; + v2; +} diff --git a/gcc/testsuite/g++.dg/cpp2a/constinit9.C b/gcc/testsuite/g++.dg/cpp2a/constinit9.C new file mode 100644 index 0000000..4c7f8925 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/constinit9.C @@ -0,0 +1,24 @@ +// PR c++/91360 - Implement C++20 P1143R2: constinit +// { dg-do run { target c++2a } } +// A run-time test. + +constexpr int foo (int x) { return x; } +constinit int b = foo(42); + +int +main () +{ + if (b != 42) + __builtin_abort (); + // We can still modify 'b'. + b = 10; + if (b != 10) + __builtin_abort (); + + constinit static int s = foo(14); + if (s != 14) + __builtin_abort (); + s++; + if (s != 15) + __builtin_abort (); +} -- cgit v1.1 From c980510a5ab79614fcbaf5f411b1273dc9a8c7ca Mon Sep 17 00:00:00 2001 From: "Steven G. Kargl" Date: Wed, 28 Aug 2019 20:36:00 +0000 Subject: re PR fortran/91551 (ICE in sort_actual, at fortran/intrinsic.c:4193) 2019-08-28 Steven G. Kargl PR fortran/91551 * intrinsic.c (sort_actual): ALLOCATED has one argument. Check for no argument case. 2019-08-28 Steven G. Kargl PR fortran/91551 * gfortran.dg/allocated_3.f90 From-SVN: r275009 --- gcc/fortran/ChangeLog | 6 ++++ gcc/fortran/intrinsic.c | 54 ++++++++++++++++++------------- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gfortran.dg/allocated_3.f90 | 6 ++++ 4 files changed, 49 insertions(+), 22 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/allocated_3.f90 (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 5e3d7b9..0f2efb2 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,5 +1,11 @@ 2019-08-28 Steven G. Kargl + PR fortran/91551 + * intrinsic.c (sort_actual): ALLOCATED has one argument. Check for + no argument case. + +2019-08-28 Steven G. Kargl + PR fortran/91565 * simplify.c (gfc_simplify_reshape): Add additional checks of the ORDER dummy argument. diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c index 1b6eeda..764e350 100644 --- a/gcc/fortran/intrinsic.c +++ b/gcc/fortran/intrinsic.c @@ -4190,35 +4190,45 @@ sort_actual (const char *name, gfc_actual_arglist **ap, /* ALLOCATED has two mutually exclusive keywords, but only one can be present at time and neither is optional. */ - if (strcmp (name, "allocated") == 0 && a->name) + if (strcmp (name, "allocated") == 0) { - if (strcmp (a->name, "scalar") == 0) + if (!a) { - if (a->next) - goto whoops; - if (a->expr->rank != 0) - { - gfc_error ("Scalar entity required at %L", &a->expr->where); - return false; - } - return true; + gfc_error ("ALLOCATED intrinsic at %L requires an array or scalar " + "allocatable entity", where); + return false; } - else if (strcmp (a->name, "array") == 0) + + if (a->name) { - if (a->next) - goto whoops; - if (a->expr->rank == 0) + if (strcmp (a->name, "scalar") == 0) + { + if (a->next) + goto whoops; + if (a->expr->rank != 0) + { + gfc_error ("Scalar entity required at %L", &a->expr->where); + return false; + } + return true; + } + else if (strcmp (a->name, "array") == 0) { - gfc_error ("Array entity required at %L", &a->expr->where); + if (a->next) + goto whoops; + if (a->expr->rank == 0) + { + gfc_error ("Array entity required at %L", &a->expr->where); + return false; + } + return true; + } + else + { + gfc_error ("Invalid keyword %qs in %qs intrinsic function at %L", + a->name, name, &a->expr->where); return false; } - return true; - } - else - { - gfc_error ("Invalid keyword %qs in %qs intrinsic function at %L", - a->name, name, &a->expr->where); - return false; } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 77fa37f..bd9fe70 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-08-28 Steven G. Kargl + + PR fortran/91551 + * gfortran.dg/allocated_3.f90 + 2019-08-28 Marek Polacek PR c++/91360 - Implement C++20 P1143R2: constinit. diff --git a/gcc/testsuite/gfortran.dg/allocated_3.f90 b/gcc/testsuite/gfortran.dg/allocated_3.f90 new file mode 100644 index 0000000..66748d6 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/allocated_3.f90 @@ -0,0 +1,6 @@ +! { dg-do compile } +! PR fortran/91551 +! Contributed by Gerhard Steinmetz +program p + if (allocated()) stop 1 ! { dg-error "requires an array or scalar allocatable" } +end -- cgit v1.1 From 32b1d51f16fe56b34e979fcfba4bc74dbd3592a9 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 28 Aug 2019 20:39:32 +0000 Subject: runtime: move osinit to Go This is a step toward updating libgo to 1.13. This adds the 1.13 version of the osinit function to Go code, and removes the corresponding code from the C runtime. This should simplify future updates. Some additional 1.13 code was brought in to simplify this change. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/191717 From-SVN: r275010 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 54a5935..3ae07c4 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -5d15923ada640befb236d5fe94f0c724e98e99d7 +db738935c77443840994e5a9f77e619e67a4c43a The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From c085c154df2f292967ac6337d5e8ab4e1a17d4ff Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Wed, 28 Aug 2019 22:40:43 +0100 Subject: * es.po: Update. From-SVN: r275012 --- gcc/po/ChangeLog | 4 +++ gcc/po/es.po | 81 +++++++++++++++++++++----------------------------------- 2 files changed, 34 insertions(+), 51 deletions(-) (limited to 'gcc') diff --git a/gcc/po/ChangeLog b/gcc/po/ChangeLog index ac90b05..b8d6f01 100644 --- a/gcc/po/ChangeLog +++ b/gcc/po/ChangeLog @@ -1,3 +1,7 @@ +2019-08-28 Joseph Myers + + * es.po: Update. + 2019-08-23 Joseph Myers * zh_CN.po: Update. diff --git a/gcc/po/es.po b/gcc/po/es.po index 2f3a219..5b6e205 100644 --- a/gcc/po/es.po +++ b/gcc/po/es.po @@ -43,7 +43,7 @@ msgstr "" "Project-Id-Version: gcc 9.1.0\n" "Report-Msgid-Bugs-To: https://gcc.gnu.org/bugs/\n" "POT-Creation-Date: 2019-05-02 20:28+0000\n" -"PO-Revision-Date: 2019-05-17 05:23+0200\n" +"PO-Revision-Date: 2019-08-28 09:32+0200\n" "Last-Translator: Antonio Ceballos Roa \n" "Language-Team: Spanish \n" "Language: es\n" @@ -174,17 +174,11 @@ msgstr "compilación terminada.\n" #: diagnostic.c:618 msgid "In file included from" -msgstr "" +msgstr "En el fichero incluido desde" #: diagnostic.c:619 -#, fuzzy -#| msgid "" -#| ",\n" -#| " from %s:%u" msgid " from" -msgstr "" -",\n" -" de %s:%u" +msgstr " desde" #: diagnostic.c:991 #, c-format @@ -796,10 +790,9 @@ msgstr "" "%s.\n" #: gcov-tool.c:528 -#, fuzzy, c-format -#| msgid "Copyright %s 2018 Free Software Foundation, Inc.\n" +#, c-format msgid "Copyright %s 2019 Free Software Foundation, Inc.\n" -msgstr "Copyright %s 2018 Free Software Foundation, Inc.\n" +msgstr "Copyright %s 2019 Free Software Foundation, Inc.\n" #: gcov-tool.c:531 gcov.c:925 #, c-format @@ -867,10 +860,9 @@ msgid " -h, --help Print this help, then exit\n" msgstr " -h, --help Muestra esta información, y finaliza\n" #: gcov.c:894 -#, fuzzy, c-format -#| msgid " -n, --no-output Do not create an output file\n" +#, c-format msgid " -i, --json-format Output JSON intermediate format into .gcov.json.gz file\n" -msgstr " -n, --no-output No crea un fichero de salida\n" +msgstr " -i, --json-format Salida con formato JSON intermedia en el fichero .gcov.json.gz\n" #: gcov.c:895 #, c-format @@ -912,10 +904,9 @@ msgid " -p, --preserve-paths Preserve all pathname components\n" msgstr " -p, --preserve-paths Preserva todos los nombres de ruta de los componentes\n" #: gcov.c:903 -#, fuzzy, c-format -#| msgid " -k, --use-colors Emit colored output\n" +#, c-format msgid " -q, --use-hotness-colors Emit perf-like colored output for hot lines\n" -msgstr " -k, --use-colors Emite salida con colores\n" +msgstr " -q, --use-hotness-colors Emite salida con colores de tipo perf para las líneas calientes\n" #: gcov.c:904 #, c-format @@ -928,10 +919,9 @@ msgid " -s, --source-prefix DIR Source prefix to elide\n" msgstr " -s, --source-prefix DIR Prefijo de fuente a omitir\n" #: gcov.c:906 -#, fuzzy, c-format -#| msgid " -n, --no-output Do not create an output file\n" +#, c-format msgid " -t, --stdout Output to stdout instead of a file\n" -msgstr " -n, --no-output No crea un fichero de salida\n" +msgstr " -t, --stdout Salida en stdout en lugar de un fichero\n" #: gcov.c:907 #, c-format @@ -959,10 +949,9 @@ msgid "gcov %s%s\n" msgstr "gcov %s%s\n" #: gcov.c:1250 -#, fuzzy, c-format -#| msgid "Treat the input file as already preprocessed." +#, c-format msgid "'%s' file is already processed\n" -msgstr "Trata al fichero de entrada como previamente preprocesado." +msgstr "El fichero '%s' ya está procesado\n" #: gcov.c:1364 #, c-format @@ -990,16 +979,14 @@ msgid "\n" msgstr "\n" #: gcov.c:1489 -#, fuzzy, c-format -#| msgid "%s: Cannot open output file: %s\n" +#, c-format msgid "Cannot open JSON output file %s\n" -msgstr "%s: No se puede abrir el fichero de salida: %s\n" +msgstr "No se puede abrir el fichero de salida JSON %s\n" #: gcov.c:1497 -#, fuzzy, c-format -#| msgid "Error writing output file '%s'\n" +#, c-format msgid "Error writing JSON output file %s\n" -msgstr "Error al escribir el fichero de salida '%s'\n" +msgstr "Error al escribir el fichero de salida JSON %s\n" #: gcov.c:1664 #, c-format @@ -1266,10 +1253,8 @@ msgid "this is the insn:" msgstr "este es la insn:" #: lra-constraints.c:2971 -#, fuzzy -#| msgid "unable to generate reloads for:" msgid "unable to generate reloads for impossible constraints:" -msgstr "no se pueden generar recargas para:" +msgstr "no se pueden generar recargas para restricciones imposibles:" #: lra-constraints.c:3962 reload.c:3814 msgid "unable to generate reloads for:" @@ -1327,12 +1312,13 @@ msgid " All options with the desired characteristics have already been displayed msgstr "Ya se mostraron todas las opciones con las características deseadas\n" #: opts.c:1581 -#, fuzzy, c-format -#| msgid "invalid argument %qs to %qs" +#, c-format msgid "" " Known valid arguments for %s option:\n" " " -msgstr "argumento %qs no válido para %qs" +msgstr "" +" Argumentos válidos conocidos para la opción %s:\n" +" " #: opts.c:1631 msgid "The following options are target specific" @@ -1430,16 +1416,12 @@ msgid "created and used with differing settings of '%s'" msgstr "creado y usado con diferentes opciones de '%s'" #: targhooks.c:2038 -#, fuzzy -#| msgid "created and used with different settings of -fpic" msgid "created and used with different settings of %<-fpic%>" -msgstr "creado y usado con diferentes opciones de -fpic" +msgstr "creado y usado con diferentes opciones de %<-fpic%>" #: targhooks.c:2040 -#, fuzzy -#| msgid "created and used with different settings of -fpie" msgid "created and used with different settings of %<-fpie%>" -msgstr "creado y usado con diferentes opciones de -fpie" +msgstr "creado y usado con diferentes opciones de %<-fpie%>" #: tlink.c:387 #, c-format @@ -1703,16 +1685,14 @@ msgid "The maximum number of instructions when inlining for size." msgstr "El número máximo de instrucciones cuando se hace inclusión en línea por tamaño." #: params.def:97 -#, fuzzy, no-c-format -#| msgid "Use subroutines for function prologues and epilogues." +#, no-c-format msgid "Instruction accounted for function prologue, epilogue and other overhead." -msgstr "Usa subrutinas para los prólogos y epílogos de función." +msgstr "Instrucción contabilizada para el prólogo y epílogo de la función y otras sobrecargas." #: params.def:103 -#, fuzzy, no-c-format -#| msgid "Use subroutines for function prologues and epilogues." +#, no-c-format msgid "Time accounted for function prologue, epilogue and other overhead." -msgstr "Usa subrutinas para los prólogos y epílogos de función." +msgstr "Tiempo contabilizado para el prólogo y epílogo de la función y otras sobrecargas." #: params.def:109 #, no-c-format @@ -1946,10 +1926,9 @@ msgstr "El número máximo de eliminación de opciones en un solo bucle." # 'desfactorizar' no me gusta. ¿Alguna sugerencia? - cfuga #: params.def:393 -#, fuzzy, no-c-format -#| msgid "The maximum number of insns to duplicate when unfactoring computed gotos." +#, no-c-format msgid "The maximum number of insns in loop header duplicated by the copy loop headers pass." -msgstr "El número máximo de insns a duplicar al desfactorizar gotos calculados." +msgstr "El número máximo de instrucciones en encabezamiento de bucle a duplicar en el paso de encabezamientos de bucles." #: params.def:400 #, no-c-format -- cgit v1.1 From 737c5bac68732abe28a374658fe85396f92b9ef5 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Thu, 29 Aug 2019 00:16:24 +0000 Subject: Daily bump. From-SVN: r275021 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 1f39dbb..b37e648 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20190828 +20190829 -- cgit v1.1 From 8a902edbbdb53a00209e88b6182457941ff196a9 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Thu, 29 Aug 2019 03:11:50 +0000 Subject: Implement P1152R4: Deprecating some uses of volatile. PR c++/91361 * c-opts.c (c_common_post_options): Enable -Wvolatile by default for C++2a, unless -Wno-deprecated. * c.opt (Wvolatile): New warning. * cp-gimplify.c (cp_fold): Set TREE_THIS_VOLATILE. * decl.c (grokdeclarator): Warn about a volatile-qualified structured binding and return type. (grokparms): Warn about a volatile-qualified function parameter. * expr.c (mark_use) : Emit a -Wvolatile warning. * typeck.c (cp_build_unary_op): Emit a -Wvolatile warning for pre and post ++/-- on a volatile operand. (genericize_compound_lvalue): Use a better location. Don't lose TREE_THIS_VOLATILE. (cp_build_modify_expr): Emit a -Wvolatile warning for a compound assignment whose LHS is volatile-qualified. Build the assignment with a more precise location. * doc/invoke.texi: Document -Wvolatile. * c-c++-common/Wbool-operation-1.c: Use -Wno-volatile in C++. * c-c++-common/gomp/atomic-1.c: Likewise. * c-c++-common/gomp/atomic-9.c: Likewise. * c-c++-common/gomp/depend-iterator-1.c: Likewise. * c-c++-common/gomp/loop-1.c: Adjust warning location for C++. * c-c++-common/gomp/order-3.c: Likewise. * c-c++-common/pr69733.c: Use -Wno-volatile in C++. * c-c++-common/spec-barrier-2.c: Likewise. * c-c++-common/tm/pr54893.c: Likewise. * g++.dg/cpp0x/pr65327.C: Add dg-warning. * g++.dg/cpp0x/rv-conv2.C: Likewise. * g++.dg/cpp0x/rv1n.C: Likewise. * g++.dg/cpp0x/rv1p.C: Likewise. * g++.dg/cpp0x/rv2n.C: Likewise. * g++.dg/cpp0x/rv2p.C: Likewise. * g++.dg/cpp0x/rv3n.C: Likewise. * g++.dg/cpp0x/rv3p.C: Likewise. * g++.dg/cpp0x/rv4n.C: Likewise. * g++.dg/cpp0x/rv4p.C: Likewise. * g++.dg/cpp0x/rv5n.C: Likewise. * g++.dg/cpp0x/rv5p.C: Likewise. * g++.dg/cpp0x/rv6n.C: Likewise. * g++.dg/cpp0x/rv6p.C: Likewise. * g++.dg/cpp0x/rv7n.C: Likewise. * g++.dg/cpp0x/rv7p.C: Likewise. * g++.dg/cpp0x/rv8p.C: Likewise. * g++.dg/cpp0x/trailing14.C: Use -Wno-volatile. * g++.dg/cpp1y/new1.C: Add dg-warning. * g++.dg/cpp2a/volatile1.C: New test. * g++.dg/cpp2a/volatile2.C: New test. * g++.dg/cpp2a/volatile3.C: New test. * g++.dg/cpp2a/volatile4.C: New test. * g++.dg/expr/bool3.C: Add dg-warning. * g++.dg/expr/bool4.C: Likewise. * g++.dg/expr/cond9.C: Likewise. * g++.dg/ext/vector25.C: Likewise. * g++.dg/gomp/depend-iterator-1.C: Use -Wno-volatile. * g++.dg/inherit/covariant21.C: Add dg-warning. * g++.dg/init/ref18.C: Likewise. * g++.dg/ipa/pr63838.C: Likewise. * g++.dg/overload/rvalue2.C: Likewise. * g++.dg/parse/semicolon4.C: Likewise. * g++.dg/warn/Wreturn-type-4.C: Likewise. * g++.dg/warn/pr36069.C: Likewise. * g++.old-deja/g++.mike/p9506.C: Likewise. * g++.old-deja/g++.other/volatile1.C: Likewise. From-SVN: r275022 --- gcc/ChangeLog | 6 + gcc/c-family/ChangeLog | 8 ++ gcc/c-family/c-opts.c | 4 + gcc/c-family/c.opt | 4 + gcc/cp/ChangeLog | 17 +++ gcc/cp/cp-gimplify.c | 3 + gcc/cp/decl.c | 18 +++ gcc/cp/expr.c | 22 ++++ gcc/cp/typeck.c | 24 +++- gcc/doc/invoke.texi | 15 ++- gcc/testsuite/ChangeLog | 53 +++++++- gcc/testsuite/c-c++-common/Wbool-operation-1.c | 1 + gcc/testsuite/c-c++-common/gomp/atomic-1.c | 1 + gcc/testsuite/c-c++-common/gomp/atomic-9.c | 1 + .../c-c++-common/gomp/depend-iterator-1.c | 2 + gcc/testsuite/c-c++-common/gomp/loop-1.c | 12 +- gcc/testsuite/c-c++-common/gomp/order-3.c | 12 +- gcc/testsuite/c-c++-common/pr69733.c | 2 +- gcc/testsuite/c-c++-common/spec-barrier-2.c | 1 + gcc/testsuite/c-c++-common/tm/pr54893.c | 1 + gcc/testsuite/g++.dg/cpp0x/pr65327.C | 2 +- gcc/testsuite/g++.dg/cpp0x/rv-conv2.C | 6 +- gcc/testsuite/g++.dg/cpp0x/rv1n.C | 4 +- gcc/testsuite/g++.dg/cpp0x/rv1p.C | 4 +- gcc/testsuite/g++.dg/cpp0x/rv2n.C | 4 +- gcc/testsuite/g++.dg/cpp0x/rv2p.C | 4 +- gcc/testsuite/g++.dg/cpp0x/rv3n.C | 4 +- gcc/testsuite/g++.dg/cpp0x/rv3p.C | 4 +- gcc/testsuite/g++.dg/cpp0x/rv4n.C | 4 +- gcc/testsuite/g++.dg/cpp0x/rv4p.C | 4 +- gcc/testsuite/g++.dg/cpp0x/rv5n.C | 4 +- gcc/testsuite/g++.dg/cpp0x/rv5p.C | 4 +- gcc/testsuite/g++.dg/cpp0x/rv6n.C | 4 +- gcc/testsuite/g++.dg/cpp0x/rv6p.C | 4 +- gcc/testsuite/g++.dg/cpp0x/rv7n.C | 4 +- gcc/testsuite/g++.dg/cpp0x/rv7p.C | 4 +- gcc/testsuite/g++.dg/cpp0x/rv8p.C | 4 +- gcc/testsuite/g++.dg/cpp0x/trailing14.C | 2 +- gcc/testsuite/g++.dg/cpp1y/new1.C | 2 +- gcc/testsuite/g++.dg/cpp2a/volatile1.C | 141 ++++++++++++++++++++ gcc/testsuite/g++.dg/cpp2a/volatile2.C | 142 +++++++++++++++++++++ gcc/testsuite/g++.dg/cpp2a/volatile3.C | 142 +++++++++++++++++++++ gcc/testsuite/g++.dg/cpp2a/volatile4.C | 142 +++++++++++++++++++++ gcc/testsuite/g++.dg/expr/bool3.C | 2 + gcc/testsuite/g++.dg/expr/bool4.C | 2 +- gcc/testsuite/g++.dg/expr/cond9.C | 2 +- gcc/testsuite/g++.dg/ext/vector25.C | 2 +- gcc/testsuite/g++.dg/gomp/depend-iterator-1.C | 2 + gcc/testsuite/g++.dg/inherit/covariant21.C | 6 +- gcc/testsuite/g++.dg/init/ref18.C | 2 +- gcc/testsuite/g++.dg/ipa/pr63838.C | 6 +- gcc/testsuite/g++.dg/overload/rvalue2.C | 2 +- gcc/testsuite/g++.dg/parse/semicolon4.C | 2 +- gcc/testsuite/g++.dg/warn/Wreturn-type-4.C | 1 + gcc/testsuite/g++.dg/warn/pr36069.C | 2 + gcc/testsuite/g++.old-deja/g++.mike/p9506.C | 2 +- gcc/testsuite/g++.old-deja/g++.other/volatile1.C | 2 +- 57 files changed, 814 insertions(+), 67 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/volatile1.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/volatile2.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/volatile3.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/volatile4.C (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8b5ccd2..c4a7b30 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2019-08-28 Marek Polacek + Implement P1152R4: Deprecating some uses of volatile. + PR c++/91361 + * doc/invoke.texi: Document -Wvolatile. + +2019-08-28 Marek Polacek + PR c++/91360 - Implement C++20 P1143R2: constinit. * doc/invoke.texi: Document -Wc++20-compat. diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index d0a19e3..8b4e75c 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,5 +1,13 @@ 2019-08-28 Marek Polacek + Implement P1152R4: Deprecating some uses of volatile. + PR c++/91361 + * c-opts.c (c_common_post_options): Enable -Wvolatile by + default for C++2a, unless -Wno-deprecated. + * c.opt (Wvolatile): New warning. + +2019-08-28 Marek Polacek + PR c++/91360 - Implement C++20 P1143R2: constinit. * c-common.c (c_common_reswords): Add constinit and __constinit. (keyword_is_decl_specifier): Handle RID_CONSTINIT. diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c index da783e4..fa8cd0c 100644 --- a/gcc/c-family/c-opts.c +++ b/gcc/c-family/c-opts.c @@ -919,6 +919,10 @@ c_common_post_options (const char **pfilename) if (!global_options_set.x_warn_comma_subscript) warn_comma_subscript = (cxx_dialect >= cxx2a && warn_deprecated); + /* -Wvolatile is enabled by default in C++20. */ + if (!global_options_set.x_warn_volatile) + warn_volatile = (cxx_dialect >= cxx2a && warn_deprecated); + /* Declone C++ 'structors if -Os. */ if (flag_declone_ctor_dtor == -1) flag_declone_ctor_dtor = optimize_size; diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 4c468d0..f8a1a1d 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -1228,6 +1228,10 @@ Wno-vla-larger-than C ObjC C++ LTO ObjC++ Alias(Wvla-larger-than=,18446744073709551615EiB,none) Warning -Wno-vla-larger-than Disable Wvla-larger-than= warning. Equivalent to Wvla-larger-than= or larger. +Wvolatile +C++ ObjC++ Var(warn_volatile) Warning +Warn about deprecated uses of volatile qualifier. + Wvolatile-register-var C ObjC C++ ObjC++ Var(warn_volatile_register_var) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) Warn when a register variable is declared volatile. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2e7c26c..818d32b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,22 @@ 2019-08-28 Marek Polacek + Implement P1152R4: Deprecating some uses of volatile. + PR c++/91361 + * cp-gimplify.c (cp_fold): Set TREE_THIS_VOLATILE. + * decl.c (grokdeclarator): Warn about a volatile-qualified structured + binding and return type. + (grokparms): Warn about a volatile-qualified function parameter. + * expr.c (mark_use) : Emit a -Wvolatile warning. + * typeck.c (cp_build_unary_op): Emit a -Wvolatile warning for pre and + post ++/-- on a volatile operand. + (genericize_compound_lvalue): Use a better location. Don't lose + TREE_THIS_VOLATILE. + (cp_build_modify_expr): Emit a -Wvolatile warning for a compound + assignment whose LHS is volatile-qualified. Build the assignment with + a more precise location. + +2019-08-28 Marek Polacek + PR c++/91360 - Implement C++20 P1143R2: constinit. * cp-tree.h (TINFO_VAR_DECLARED_CONSTINIT): Define. (LOOKUP_CONSTINIT): Define. diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index 065dcb7..49fa47a 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -2507,6 +2507,9 @@ cp_fold (tree x) else x = org_x; } + if (code == MODIFY_EXPR && TREE_CODE (x) == MODIFY_EXPR) + TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x); + break; case VEC_COND_EXPR: diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index c5cc22a..2aef330 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -11233,6 +11233,10 @@ grokdeclarator (const cp_declarator *declarator, if (concept_p) error_at (declspecs->locations[ds_concept], "structured binding declaration cannot be %qs", "concept"); + /* [dcl.struct.bind] "A cv that includes volatile is deprecated." */ + if (type_quals & TYPE_QUAL_VOLATILE) + warning_at (declspecs->locations[ds_volatile], OPT_Wvolatile, + "%-qualified structured binding is deprecated"); switch (storage_class) { case sc_none: @@ -11623,6 +11627,13 @@ grokdeclarator (const cp_declarator *declarator, if (SCALAR_TYPE_P (type) || VOID_TYPE_P (type)) warning_at (typespec_loc, OPT_Wignored_qualifiers, "type " "qualifiers ignored on function return type"); + /* [dcl.fct] "A volatile-qualified return type is + deprecated." */ + if (type_quals & TYPE_QUAL_VOLATILE) + warning_at (typespec_loc, OPT_Wvolatile, + "%-qualified return type is " + "deprecated"); + /* We now know that the TYPE_QUALS don't apply to the decl, but to its return type. */ type_quals = TYPE_UNQUALIFIED; @@ -13378,6 +13389,13 @@ grokparms (tree parmlist, tree *parms) cp_warn_deprecated_use (deptype); } + /* [dcl.fct] "A parameter with volatile-qualified type is + deprecated." */ + if (CP_TYPE_VOLATILE_P (type)) + warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wvolatile, + "%-qualified parameter is " + "deprecated"); + /* Top-level qualifiers on the parameters are ignored for function types. */ type = cp_build_qualified_type (type, 0); diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c index 9160043..212a7f9 100644 --- a/gcc/cp/expr.c +++ b/gcc/cp/expr.c @@ -207,6 +207,28 @@ mark_use (tree expr, bool rvalue_p, bool read_p, recurse_op[0] = true; break; + case MODIFY_EXPR: + { + tree lhs = TREE_OPERAND (expr, 0); + /* [expr.ass] "A simple assignment whose left operand is of + a volatile-qualified type is deprecated unless the assignment + is either a discarded-value expression or appears in an + unevaluated context." */ + if (read_p + && !cp_unevaluated_operand + && (TREE_THIS_VOLATILE (lhs) + || CP_TYPE_VOLATILE_P (TREE_TYPE (lhs))) + && !TREE_THIS_VOLATILE (expr)) + { + warning_at (location_of (expr), OPT_Wvolatile, + "using value of simple assignment with %-" + "qualified left operand is deprecated"); + /* Make sure not to warn about this assignment again. */ + TREE_THIS_VOLATILE (expr) = true; + } + break; + } + default: break; } diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index c09bb30..d4f2d981 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -6459,6 +6459,17 @@ cp_build_unary_op (enum tree_code code, tree xarg, bool noconvert, complain)) return error_mark_node; + /* [depr.volatile.type] "Postfix ++ and -- expressions and + prefix ++ and -- expressions of volatile-qualified arithmetic + and pointer types are deprecated." */ + if (TREE_THIS_VOLATILE (arg) || CP_TYPE_VOLATILE_P (TREE_TYPE (arg))) + warning_at (location, OPT_Wvolatile, + "%qs expression of %-qualified type is " + "deprecated", + ((code == PREINCREMENT_EXPR + || code == POSTINCREMENT_EXPR) + ? "++" : "--")); + /* Forbid using -- or ++ in C++17 on `bool'. */ if (TREE_CODE (declared_type) == BOOLEAN_TYPE) { @@ -8278,6 +8289,15 @@ cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, && MAYBE_CLASS_TYPE_P (TREE_TYPE (lhstype))) || MAYBE_CLASS_TYPE_P (lhstype))); + /* An expression of the form E1 op= E2. [expr.ass] says: + "Such expressions are deprecated if E1 has volatile-qualified + type." We warn here rather than in cp_genericize_r because + for compound assignments we are supposed to warn even if the + assignment is a discarded-value expression. */ + if (TREE_THIS_VOLATILE (lhs) || CP_TYPE_VOLATILE_P (lhstype)) + warning_at (loc, OPT_Wvolatile, + "compound assignment with %-qualified left " + "operand is deprecated"); /* Preevaluate the RHS to make sure its evaluation is complete before the lvalue-to-rvalue conversion of the LHS: @@ -8450,8 +8470,8 @@ cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, goto ret; } - result = build2 (modifycode == NOP_EXPR ? MODIFY_EXPR : INIT_EXPR, - lhstype, lhs, newrhs); + result = build2_loc (loc, modifycode == NOP_EXPR ? MODIFY_EXPR : INIT_EXPR, + lhstype, lhs, newrhs); TREE_SIDE_EFFECTS (result) = 1; if (!plain_assign) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 1391a56..aa9886e 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -243,7 +243,7 @@ in the following sections. -Wno-non-template-friend -Wold-style-cast @gol -Woverloaded-virtual -Wno-pmf-conversions @gol -Wno-class-conversion -Wno-terminate @gol --Wsign-promo -Wvirtual-inheritance} +-Wsign-promo -Wvirtual-inheritance -Wvolatile} @item Objective-C and Objective-C++ Language Options @xref{Objective-C and Objective-C++ Dialect Options,,Options Controlling @@ -3516,6 +3516,19 @@ result in a call to @code{terminate}. Disable the warning about the case when a conversion function converts an object to the same type, to a base class of that type, or to void; such a conversion function will never be called. + +@item -Wvolatile @r{(C++ and Objective-C++ only)} +@opindex Wvolatile +@opindex Wno-volatile +Warn about deprecated uses of the volatile qualifier. This includes postfix +and prefix @code{++} and @code{--} expressions of volatile-qualified types, +using simple assignments where the left operand is a volatile-qualified +non-class type for their value, compound assignments where the left operand +is a volatile-qualified non-class type, volatile-qualified function return +type, volatile-qualified parameter type, and structured bindings of a +volatile-qualified type. This usage was deprecated in C++20. + +Enabled by default with @option{-std=c++2a}. @end table @node Objective-C and Objective-C++ Dialect Options diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bd9fe70..3a503ac 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,7 +1,58 @@ +2019-08-28 Marek Polacek + + Implement P1152R4: Deprecating some uses of volatile. + PR c++/91361 + * c-c++-common/Wbool-operation-1.c: Use -Wno-volatile in C++. + * c-c++-common/gomp/atomic-1.c: Likewise. + * c-c++-common/gomp/atomic-9.c: Likewise. + * c-c++-common/gomp/depend-iterator-1.c: Likewise. + * c-c++-common/gomp/loop-1.c: Adjust warning location for C++. + * c-c++-common/gomp/order-3.c: Likewise. + * c-c++-common/pr69733.c: Use -Wno-volatile in C++. + * c-c++-common/spec-barrier-2.c: Likewise. + * c-c++-common/tm/pr54893.c: Likewise. + * g++.dg/cpp0x/pr65327.C: Add dg-warning. + * g++.dg/cpp0x/rv-conv2.C: Likewise. + * g++.dg/cpp0x/rv1n.C: Likewise. + * g++.dg/cpp0x/rv1p.C: Likewise. + * g++.dg/cpp0x/rv2n.C: Likewise. + * g++.dg/cpp0x/rv2p.C: Likewise. + * g++.dg/cpp0x/rv3n.C: Likewise. + * g++.dg/cpp0x/rv3p.C: Likewise. + * g++.dg/cpp0x/rv4n.C: Likewise. + * g++.dg/cpp0x/rv4p.C: Likewise. + * g++.dg/cpp0x/rv5n.C: Likewise. + * g++.dg/cpp0x/rv5p.C: Likewise. + * g++.dg/cpp0x/rv6n.C: Likewise. + * g++.dg/cpp0x/rv6p.C: Likewise. + * g++.dg/cpp0x/rv7n.C: Likewise. + * g++.dg/cpp0x/rv7p.C: Likewise. + * g++.dg/cpp0x/rv8p.C: Likewise. + * g++.dg/cpp0x/trailing14.C: Use -Wno-volatile. + * g++.dg/cpp1y/new1.C: Add dg-warning. + * g++.dg/cpp2a/volatile1.C: New test. + * g++.dg/cpp2a/volatile2.C: New test. + * g++.dg/cpp2a/volatile3.C: New test. + * g++.dg/cpp2a/volatile4.C: New test. + * g++.dg/expr/bool3.C: Add dg-warning. + * g++.dg/expr/bool4.C: Likewise. + * g++.dg/expr/cond9.C: Likewise. + * g++.dg/ext/vector25.C: Likewise. + * g++.dg/gomp/depend-iterator-1.C: Use -Wno-volatile. + * g++.dg/inherit/covariant21.C: Add dg-warning. + * g++.dg/init/ref18.C: Likewise. + * g++.dg/ipa/pr63838.C: Likewise. + * g++.dg/overload/rvalue2.C: Likewise. + * g++.dg/parse/semicolon4.C: Likewise. + * g++.dg/warn/Wreturn-type-4.C: Likewise. + * g++.dg/warn/pr36069.C: Likewise. + * g++.old-deja/g++.mike/p9506.C: Likewise. + * g++.old-deja/g++.other/volatile1.C: Likewise. + 2019-08-28 Steven G. Kargl PR fortran/91551 - * gfortran.dg/allocated_3.f90 + * gfortran.dg/allocated_3.f90 2019-08-28 Marek Polacek diff --git a/gcc/testsuite/c-c++-common/Wbool-operation-1.c b/gcc/testsuite/c-c++-common/Wbool-operation-1.c index 0489187..ce87705 100644 --- a/gcc/testsuite/c-c++-common/Wbool-operation-1.c +++ b/gcc/testsuite/c-c++-common/Wbool-operation-1.c @@ -1,6 +1,7 @@ /* PR c/77490 */ /* { dg-do compile } */ /* { dg-options "-Wall -Wno-psabi" } */ +/* { dg-additional-options "-Wno-volatile" { target c++ } } */ #ifndef __cplusplus # define bool _Bool diff --git a/gcc/testsuite/c-c++-common/gomp/atomic-1.c b/gcc/testsuite/c-c++-common/gomp/atomic-1.c index 3e4bc56..1facf45 100644 --- a/gcc/testsuite/c-c++-common/gomp/atomic-1.c +++ b/gcc/testsuite/c-c++-common/gomp/atomic-1.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-additional-options "-Wno-volatile" { target c++ } } */ int x; volatile int y; diff --git a/gcc/testsuite/c-c++-common/gomp/atomic-9.c b/gcc/testsuite/c-c++-common/gomp/atomic-9.c index c07da8f..3554839 100644 --- a/gcc/testsuite/c-c++-common/gomp/atomic-9.c +++ b/gcc/testsuite/c-c++-common/gomp/atomic-9.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-fopenmp -fdump-tree-ompexp" } */ +/* { dg-additional-options "-Wno-volatile" { target c++ } } */ /* { dg-require-effective-target cas_int } */ volatile int *bar(void); diff --git a/gcc/testsuite/c-c++-common/gomp/depend-iterator-1.c b/gcc/testsuite/c-c++-common/gomp/depend-iterator-1.c index 4fb01c1..6fa6021 100644 --- a/gcc/testsuite/c-c++-common/gomp/depend-iterator-1.c +++ b/gcc/testsuite/c-c++-common/gomp/depend-iterator-1.c @@ -1,3 +1,5 @@ +/* { dg-additional-options "-Wno-volatile" { target c++ } } */ + int arr[64], arr2[64]; struct S { int a[4]; } k; short arr4[4]; diff --git a/gcc/testsuite/c-c++-common/gomp/loop-1.c b/gcc/testsuite/c-c++-common/gomp/loop-1.c index d2f943a..4fb995c 100644 --- a/gcc/testsuite/c-c++-common/gomp/loop-1.c +++ b/gcc/testsuite/c-c++-common/gomp/loop-1.c @@ -100,8 +100,8 @@ f4 (int *a) #pragma omp loop order(concurrent) bind(parallel) for (i = 0; i < 64; i++) { - #pragma omp atomic read - a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" } */ + #pragma omp atomic read /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" "" { target c++ } } */ + a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" "" { target c } } */ } #pragma omp loop order(concurrent) bind(parallel) for (i = 0; i < 64; i++) @@ -172,8 +172,8 @@ f5 (int *a) #pragma omp loop for (i = 0; i < 64; i++) { - #pragma omp atomic read - a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" } */ + #pragma omp atomic read /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" "" { target c++ } } */ + a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" "" { target c } } */ } #pragma omp loop for (i = 0; i < 64; i++) @@ -245,8 +245,8 @@ f6 (int *a) #pragma omp loop for (i = 0; i < 64; i++) { - #pragma omp atomic read - a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" } */ + #pragma omp atomic read /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" "" { target c++ } } */ + a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" "" { target c } } */ } #pragma omp loop for (i = 0; i < 64; i++) diff --git a/gcc/testsuite/c-c++-common/gomp/order-3.c b/gcc/testsuite/c-c++-common/gomp/order-3.c index 2d51bf3..e33386d 100644 --- a/gcc/testsuite/c-c++-common/gomp/order-3.c +++ b/gcc/testsuite/c-c++-common/gomp/order-3.c @@ -50,8 +50,8 @@ f1 (int *a) #pragma omp simd order(concurrent) for (i = 0; i < 64; i++) { - #pragma omp atomic read - a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" } */ + #pragma omp atomic read /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" "" { target c++ } } */ + a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" "" { target c } } */ } #pragma omp simd order(concurrent) for (i = 0; i < 64; i++) @@ -112,8 +112,8 @@ f2 (int *a) #pragma omp for simd order(concurrent) for (i = 0; i < 64; i++) { - #pragma omp atomic read - a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" } */ + #pragma omp atomic read /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" "" { target c++ } } */ + a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" "" { target c } } */ } #pragma omp for simd order(concurrent) for (i = 0; i < 64; i++) @@ -174,8 +174,8 @@ f3 (int *a) #pragma omp for order(concurrent) for (i = 0; i < 64; i++) { - #pragma omp atomic read - a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" } */ + #pragma omp atomic read /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" "" { target c++ } } */ + a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" "" { target c } } */ } #pragma omp for order(concurrent) for (i = 0; i < 64; i++) diff --git a/gcc/testsuite/c-c++-common/pr69733.c b/gcc/testsuite/c-c++-common/pr69733.c index 57ec1ec..ab70f49 100644 --- a/gcc/testsuite/c-c++-common/pr69733.c +++ b/gcc/testsuite/c-c++-common/pr69733.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-W -fdiagnostics-show-caret" } */ +/* { dg-additional-options "-Wno-volatile" { target c++ } } */ typedef const double cd; double val; @@ -21,4 +22,3 @@ cd val2() {return val;} /* { dg-warning "qualifiers ignored" } */ cd val2() {return val;} ^~ { dg-end-multiline-output "" } */ - diff --git a/gcc/testsuite/c-c++-common/spec-barrier-2.c b/gcc/testsuite/c-c++-common/spec-barrier-2.c index b09567e..a27ec54 100644 --- a/gcc/testsuite/c-c++-common/spec-barrier-2.c +++ b/gcc/testsuite/c-c++-common/spec-barrier-2.c @@ -1,4 +1,5 @@ /* { dg-do run } */ +/* { dg-additional-options "-Wno-volatile" { target c++ } } */ /* Even on targets that don't need the optional failval parameter, side-effects on the operand should still be calculated. */ diff --git a/gcc/testsuite/c-c++-common/tm/pr54893.c b/gcc/testsuite/c-c++-common/tm/pr54893.c index 3766078..266cbe9 100644 --- a/gcc/testsuite/c-c++-common/tm/pr54893.c +++ b/gcc/testsuite/c-c++-common/tm/pr54893.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-fgnu-tm -fdump-ipa-tmipa" } */ +/* { dg-additional-options "-Wno-volatile" { target c++ } } */ /* Test that volatiles are allowed inside relaxed transactions. */ diff --git a/gcc/testsuite/g++.dg/cpp0x/pr65327.C b/gcc/testsuite/g++.dg/cpp0x/pr65327.C index 5176b3c..6e888eb 100644 --- a/gcc/testsuite/g++.dg/cpp0x/pr65327.C +++ b/gcc/testsuite/g++.dg/cpp0x/pr65327.C @@ -11,7 +11,7 @@ foo () static constexpr volatile int k = 5; } -constexpr volatile int +constexpr volatile int // { dg-warning "deprecated" "" { target c++2a } } bar () { return i; diff --git a/gcc/testsuite/g++.dg/cpp0x/rv-conv2.C b/gcc/testsuite/g++.dg/cpp0x/rv-conv2.C index 9b9b154..2f2a1fa 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv-conv2.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv-conv2.C @@ -1,16 +1,16 @@ // PR c++/89705 // { dg-do compile { target c++11 } } -struct W { operator const volatile int(); }; +struct W { operator const volatile int(); }; // { dg-warning "deprecated" "" { target c++2a } } const int& rci = W(); struct X { operator const int(); }; int&& rri = X(); -struct Y { operator volatile int(); }; +struct Y { operator volatile int(); }; // { dg-warning "deprecated" "" { target c++2a } } int&& rri2 = Y(); -struct Z { operator const volatile int(); }; +struct Z { operator const volatile int(); }; // { dg-warning "deprecated" "" { target c++2a } } volatile int&& rri3 = Z(); enum E { A }; diff --git a/gcc/testsuite/g++.dg/cpp0x/rv1n.C b/gcc/testsuite/g++.dg/cpp0x/rv1n.C index f5e7568..a762fc8 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv1n.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv1n.C @@ -26,8 +26,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 1 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/rv1p.C b/gcc/testsuite/g++.dg/cpp0x/rv1p.C index a909727..e2a983a 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv1p.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv1p.C @@ -26,8 +26,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 1 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/rv2n.C b/gcc/testsuite/g++.dg/cpp0x/rv2n.C index 65eda80..2871ccf 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv2n.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv2n.C @@ -25,8 +25,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 2 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/rv2p.C b/gcc/testsuite/g++.dg/cpp0x/rv2p.C index 25a42ba..bab0dce 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv2p.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv2p.C @@ -25,8 +25,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 2 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/rv3n.C b/gcc/testsuite/g++.dg/cpp0x/rv3n.C index 4549438..35cdba9 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv3n.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv3n.C @@ -25,8 +25,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 3 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/rv3p.C b/gcc/testsuite/g++.dg/cpp0x/rv3p.C index 2d7d78d..b25aa26 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv3p.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv3p.C @@ -25,8 +25,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 3 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/rv4n.C b/gcc/testsuite/g++.dg/cpp0x/rv4n.C index 29deb3f..6941a13 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv4n.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv4n.C @@ -25,8 +25,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 4 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/rv4p.C b/gcc/testsuite/g++.dg/cpp0x/rv4p.C index 0e4903b..cd0d631 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv4p.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv4p.C @@ -25,8 +25,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 4 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/rv5n.C b/gcc/testsuite/g++.dg/cpp0x/rv5n.C index f11d07a..086aa46 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv5n.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv5n.C @@ -25,8 +25,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 5 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/rv5p.C b/gcc/testsuite/g++.dg/cpp0x/rv5p.C index 63441a3..34c1017 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv5p.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv5p.C @@ -25,8 +25,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 5 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/rv6n.C b/gcc/testsuite/g++.dg/cpp0x/rv6n.C index 0ebbe33..b21d22a 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv6n.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv6n.C @@ -25,8 +25,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 6 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/rv6p.C b/gcc/testsuite/g++.dg/cpp0x/rv6p.C index 26714f0..fee692b 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv6p.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv6p.C @@ -25,8 +25,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 6 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/rv7n.C b/gcc/testsuite/g++.dg/cpp0x/rv7n.C index d9e371b..5bc313c 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv7n.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv7n.C @@ -25,8 +25,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 7 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/rv7p.C b/gcc/testsuite/g++.dg/cpp0x/rv7p.C index 60a3583..b0b8f96 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv7p.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv7p.C @@ -25,8 +25,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 7 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/rv8p.C b/gcc/testsuite/g++.dg/cpp0x/rv8p.C index e12da4b..287fb93 100644 --- a/gcc/testsuite/g++.dg/cpp0x/rv8p.C +++ b/gcc/testsuite/g++.dg/cpp0x/rv8p.C @@ -25,8 +25,8 @@ struct A A source(); const A c_source(); - volatile A v_source(); -const volatile A cv_source(); + volatile A v_source(); // { dg-warning "deprecated" "" { target c++2a } } +const volatile A cv_source(); // { dg-warning "deprecated" "" { target c++2a } } // 8 at a time diff --git a/gcc/testsuite/g++.dg/cpp0x/trailing14.C b/gcc/testsuite/g++.dg/cpp0x/trailing14.C index 2544d0b..4ebb374 100644 --- a/gcc/testsuite/g++.dg/cpp0x/trailing14.C +++ b/gcc/testsuite/g++.dg/cpp0x/trailing14.C @@ -1,6 +1,6 @@ // PR c++/65775 // { dg-do compile { target c++11 } } -// { dg-options "-Wignored-qualifiers" } +// { dg-options "-Wignored-qualifiers -Wno-volatile" } using Qi = int const volatile; Qi q1(); // { dg-warning "1: type qualifiers ignored" } diff --git a/gcc/testsuite/g++.dg/cpp1y/new1.C b/gcc/testsuite/g++.dg/cpp1y/new1.C index 5e4f1bf..b9ad64d 100644 --- a/gcc/testsuite/g++.dg/cpp1y/new1.C +++ b/gcc/testsuite/g++.dg/cpp1y/new1.C @@ -65,7 +65,7 @@ void test_unused() { volatile double d = 0.0; double *p = new double (); - d += 1.0; + d += 1.0; // { dg-warning "deprecated" "" { target c++2a } } delete p; } diff --git a/gcc/testsuite/g++.dg/cpp2a/volatile1.C b/gcc/testsuite/g++.dg/cpp2a/volatile1.C new file mode 100644 index 0000000..e47591b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/volatile1.C @@ -0,0 +1,141 @@ +// PR c++/91361 - P1152R4: Deprecating some uses of volatile. +// { dg-do compile { target c++17 } } + +#define ACCESS_ONCE(x) (*(volatile __typeof(x) *)&(x)) + +struct S { + volatile int a : 4; + int b : 2; +}; + +struct T { + int a : 4; + int b : 2; +}; + +union U { + char c; + int i; +}; + +struct W { + W(); + W(volatile W&); + W& operator=(volatile W&) volatile; +}; + +volatile int // { dg-warning ".volatile.-qualified return type is deprecated" "" { target c++2a } } +fn (volatile int i) // { dg-warning ".volatile.-qualified parameter is deprecated" "" { target c++2a } } +{ + volatile int v = 10; + int *volatile p = nullptr; + + // Pre/post ++/--. + v++; // { dg-warning "expression of .volatile.-qualified type is deprecated" "" { target c++2a } } + ++v; // { dg-warning "expression of .volatile.-qualified type is deprecated" "" { target c++2a } } + v--; // { dg-warning "expression of .volatile.-qualified type is deprecated" "" { target c++2a } } + --v; // { dg-warning "expression of .volatile.-qualified type is deprecated" "" { target c++2a } } + p++; // { dg-warning "expression of .volatile.-qualified type is deprecated" "" { target c++2a } } + ++p; // { dg-warning "expression of .volatile.-qualified type is deprecated" "" { target c++2a } } + p--; // { dg-warning "expression of .volatile.-qualified type is deprecated" "" { target c++2a } } + --p; // { dg-warning "expression of .volatile.-qualified type is deprecated" "" { target c++2a } } + return v + i + *p; +} + +void +fn2 () +{ + volatile int vi = 42; + int i = 24; + + // Discarded-value expression ([expr.context]). + // The lvalue-to-rvalue conversion is applied here: + vi; + // ...but not here. Otherwise we'd write to VI and then immediately read it. + vi = 42; + vi = i; + vi = i = 42; + i = vi = 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + &(vi = i); // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + (vi = 42, 45); + (i = vi = 42, 10); // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + i = vi; // LHS not volatile. + i = (vi = i, 42); + static_cast(vi = i); + static_cast(i = vi = 42); // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + (void)(vi = i); + (void)(i = vi = 42); // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + + // Unevaluated operand. + decltype(vi = 42) x = vi; + decltype(i = vi = 42) x3 = i; + + // Compound assignments. + vi += i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + vi -= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + vi %= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + vi ^= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + vi |= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + vi /= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + vi = vi += 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + vi += vi = 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + i *= vi; + decltype(vi -= 42) x2 = vi; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + + // Structured bindings. + int a[] = { 10, 5 }; + const auto & [cxr, cyr] = a; + const volatile auto & [cvxr, cvyr] = a; // { dg-warning ".volatile.-qualified structured binding is deprecated" "" { target c++2a } } + volatile auto & [vxr, vyr] = a; // { dg-warning ".volatile.-qualified structured binding is deprecated" "" { target c++2a } } +} + +void +fn3 () +{ + volatile int i, j, k = 0; + i = j = k; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + + ACCESS_ONCE(j); + + S s; + s.b = 1; + + volatile U u; + u.c = 42; + i = u.c = 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + u.c += 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + + volatile T t; + t.a = 3; + j = t.a = 3; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + t.a += 3; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + + volatile int *src = &i; + *src; // No assignment, don't warn. +} + +void +fn4 () +{ + volatile W vw; + W w; + // Assignment to objects of a class is defined by the copy/move assignment + // operator. + vw = w; + w = vw; +} + +template +void raccoon () +{ + volatile T t, u; + t = 42; + u = t = 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } + t &= 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" "" { target c++2a } } +} + +void +fn5 () +{ + raccoon(); +} diff --git a/gcc/testsuite/g++.dg/cpp2a/volatile2.C b/gcc/testsuite/g++.dg/cpp2a/volatile2.C new file mode 100644 index 0000000..1a7889a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/volatile2.C @@ -0,0 +1,142 @@ +// PR c++/91361 - P1152R4: Deprecating some uses of volatile. +// { dg-do compile { target c++2a } } +// { dg-options "-Wno-volatile" } + +#define ACCESS_ONCE(x) (*(volatile __typeof(x) *)&(x)) + +struct S { + volatile int a : 4; + int b : 2; +}; + +struct T { + int a : 4; + int b : 2; +}; + +union U { + char c; + int i; +}; + +struct W { + W(); + W(volatile W&); + W& operator=(volatile W&) volatile; +}; + +volatile int +fn (volatile int i) +{ + volatile int v = 10; + int *volatile p = nullptr; + + // Pre/post ++/--. + v++; + ++v; + v--; + --v; + p++; + ++p; + p--; + --p; + return v + i + *p; +} + +void +fn2 () +{ + volatile int vi = 42; + int i = 24; + + // Discarded-value expression ([expr.context]). + // The lvalue-to-rvalue conversion is applied here: + vi; + // ...but not here. Otherwise we'd write to VI and then immediately read it. + vi = 42; + vi = i; + vi = i = 42; + i = vi = 42; + &(vi = i); + (vi = 42, 45); + (i = vi = 42, 10); + i = vi; // LHS not volatile. + i = (vi = i, 42); + static_cast(vi = i); + static_cast(i = vi = 42); + (void)(vi = i); + (void)(i = vi = 42); + + // Unevaluated operand. + decltype(vi = 42) x = vi; + decltype(i = vi = 42) x3 = i; + + // Compound assignments. + vi += i; + vi -= i; + vi %= i; + vi ^= i; + vi |= i; + vi /= i; + vi = vi += 42; + vi += vi = 42; + i *= vi; + decltype(vi -= 42) x2 = vi; + + // Structured bindings. + int a[] = { 10, 5 }; + const auto & [cxr, cyr] = a; + const volatile auto & [cvxr, cvyr] = a; + volatile auto & [vxr, vyr] = a; +} + +void +fn3 () +{ + volatile int i, j, k = 0; + i = j = k; + + ACCESS_ONCE(j); + + S s; + s.b = 1; + + volatile U u; + u.c = 42; + i = u.c = 42; + u.c += 42; + + volatile T t; + t.a = 3; + j = t.a = 3; + t.a += 3; + + volatile int *src = &i; + *src; // No assignment, don't warn. +} + +void +fn4 () +{ + volatile W vw; + W w; + // Assignment to objects of a class is defined by the copy/move assignment + // operator. + vw = w; + w = vw; +} + +template +void raccoon () +{ + volatile T t, u; + t = 42; + u = t = 42; + t &= 42; +} + +void +fn5 () +{ + raccoon(); +} diff --git a/gcc/testsuite/g++.dg/cpp2a/volatile3.C b/gcc/testsuite/g++.dg/cpp2a/volatile3.C new file mode 100644 index 0000000..f10a297 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/volatile3.C @@ -0,0 +1,142 @@ +// PR c++/91361 - P1152R4: Deprecating some uses of volatile. +// { dg-do compile { target c++17 } } +// { dg-options "-Wvolatile" } + +#define ACCESS_ONCE(x) (*(volatile __typeof(x) *)&(x)) + +struct S { + volatile int a : 4; + int b : 2; +}; + +struct T { + int a : 4; + int b : 2; +}; + +union U { + char c; + int i; +}; + +struct W { + W(); + W(volatile W&); + W& operator=(volatile W&) volatile; +}; + +volatile int // { dg-warning ".volatile.-qualified return type is deprecated" } +fn (volatile int i) // { dg-warning ".volatile.-qualified parameter is deprecated" } +{ + volatile int v = 10; + int *volatile p = nullptr; + + // Pre/post ++/--. + v++; // { dg-warning "expression of .volatile.-qualified type is deprecated" } + ++v; // { dg-warning "expression of .volatile.-qualified type is deprecated" } + v--; // { dg-warning "expression of .volatile.-qualified type is deprecated" } + --v; // { dg-warning "expression of .volatile.-qualified type is deprecated" } + p++; // { dg-warning "expression of .volatile.-qualified type is deprecated" } + ++p; // { dg-warning "expression of .volatile.-qualified type is deprecated" } + p--; // { dg-warning "expression of .volatile.-qualified type is deprecated" } + --p; // { dg-warning "expression of .volatile.-qualified type is deprecated" } + return v + i + *p; +} + +void +fn2 () +{ + volatile int vi = 42; + int i = 24; + + // Discarded-value expression ([expr.context]). + // The lvalue-to-rvalue conversion is applied here: + vi; + // ...but not here. Otherwise we'd write to VI and then immediately read it. + vi = 42; + vi = i; + vi = i = 42; + i = vi = 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + &(vi = i); // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + (vi = 42, 45); + (i = vi = 42, 10); // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + i = vi; // LHS not volatile. + i = (vi = i, 42); + static_cast(vi = i); + static_cast(i = vi = 42); // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + (void)(vi = i); + (void)(i = vi = 42); // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + + // Unevaluated operand. + decltype(vi = 42) x = vi; + decltype(i = vi = 42) x3 = i; + + // Compound assignments. + vi += i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + vi -= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + vi %= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + vi ^= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + vi |= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + vi /= i; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + vi = vi += 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + vi += vi = 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + i *= vi; + decltype(vi -= 42) x2 = vi; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + + // Structured bindings. + int a[] = { 10, 5 }; + const auto & [cxr, cyr] = a; + const volatile auto & [cvxr, cvyr] = a; // { dg-warning ".volatile.-qualified structured binding is deprecated" } + volatile auto & [vxr, vyr] = a; // { dg-warning ".volatile.-qualified structured binding is deprecated" } +} + +void +fn3 () +{ + volatile int i, j, k = 0; + i = j = k; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + + ACCESS_ONCE(j); + + S s; + s.b = 1; + + volatile U u; + u.c = 42; + i = u.c = 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + u.c += 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + + volatile T t; + t.a = 3; + j = t.a = 3; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + t.a += 3; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + + volatile int *src = &i; + *src; // No assignment, don't warn. +} + +void +fn4 () +{ + volatile W vw; + W w; + // Assignment to objects of a class is defined by the copy/move assignment + // operator. + vw = w; + w = vw; +} + +template +void raccoon () +{ + volatile T t, u; + t = 42; + u = t = 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } + t &= 42; // { dg-warning "assignment with .volatile.-qualified left operand is deprecated" } +} + +void +fn5 () +{ + raccoon(); +} diff --git a/gcc/testsuite/g++.dg/cpp2a/volatile4.C b/gcc/testsuite/g++.dg/cpp2a/volatile4.C new file mode 100644 index 0000000..2148cde --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/volatile4.C @@ -0,0 +1,142 @@ +// PR c++/91361 - P1152R4: Deprecating some uses of volatile. +// { dg-do compile { target c++2a } } +// { dg-options "-Wno-deprecated" } + +#define ACCESS_ONCE(x) (*(volatile __typeof(x) *)&(x)) + +struct S { + volatile int a : 4; + int b : 2; +}; + +struct T { + int a : 4; + int b : 2; +}; + +union U { + char c; + int i; +}; + +struct W { + W(); + W(volatile W&); + W& operator=(volatile W&) volatile; +}; + +volatile int +fn (volatile int i) +{ + volatile int v = 10; + int *volatile p = nullptr; + + // Pre/post ++/--. + v++; + ++v; + v--; + --v; + p++; + ++p; + p--; + --p; + return v + i + *p; +} + +void +fn2 () +{ + volatile int vi = 42; + int i = 24; + + // Discarded-value expression ([expr.context]). + // The lvalue-to-rvalue conversion is applied here: + vi; + // ...but not here. Otherwise we'd write to VI and then immediately read it. + vi = 42; + vi = i; + vi = i = 42; + i = vi = 42; + &(vi = i); + (vi = 42, 45); + (i = vi = 42, 10); + i = vi; // LHS not volatile. + i = (vi = i, 42); + static_cast(vi = i); + static_cast(i = vi = 42); + (void)(vi = i); + (void)(i = vi = 42); + + // Unevaluated operand. + decltype(vi = 42) x = vi; + decltype(i = vi = 42) x3 = i; + + // Compound assignments. + vi += i; + vi -= i; + vi %= i; + vi ^= i; + vi |= i; + vi /= i; + vi = vi += 42; + vi += vi = 42; + i *= vi; + decltype(vi -= 42) x2 = vi; + + // Structured bindings. + int a[] = { 10, 5 }; + const auto & [cxr, cyr] = a; + const volatile auto & [cvxr, cvyr] = a; + volatile auto & [vxr, vyr] = a; +} + +void +fn3 () +{ + volatile int i, j, k = 0; + i = j = k; + + ACCESS_ONCE(j); + + S s; + s.b = 1; + + volatile U u; + u.c = 42; + i = u.c = 42; + u.c += 42; + + volatile T t; + t.a = 3; + j = t.a = 3; + t.a += 3; + + volatile int *src = &i; + *src; // No assignment, don't warn. +} + +void +fn4 () +{ + volatile W vw; + W w; + // Assignment to objects of a class is defined by the copy/move assignment + // operator. + vw = w; + w = vw; +} + +template +void raccoon () +{ + volatile T t, u; + t = 42; + u = t = 42; + t &= 42; +} + +void +fn5 () +{ + raccoon(); +} diff --git a/gcc/testsuite/g++.dg/expr/bool3.C b/gcc/testsuite/g++.dg/expr/bool3.C index 373c202..f27399c 100644 --- a/gcc/testsuite/g++.dg/expr/bool3.C +++ b/gcc/testsuite/g++.dg/expr/bool3.C @@ -13,8 +13,10 @@ int main() b++; // { dg-warning "deprecated" "" { target { ! c++17 } } } // { dg-error "forbidden" "" { target c++17 } .-1 } + // { dg-warning ".volatile.-qualified type is deprecated" "" { target c++2a } .-2 } b++; // { dg-warning "deprecated" "" { target { ! c++17 } } } // { dg-error "forbidden" "" { target c++17 } .-1 } + // { dg-warning ".volatile.-qualified type is deprecated" "" { target c++2a } .-2 } i = b; if (i != 1) abort (); diff --git a/gcc/testsuite/g++.dg/expr/bool4.C b/gcc/testsuite/g++.dg/expr/bool4.C index dce51ec..5891bc3 100644 --- a/gcc/testsuite/g++.dg/expr/bool4.C +++ b/gcc/testsuite/g++.dg/expr/bool4.C @@ -8,6 +8,6 @@ int main() { my_bool b = false; b--; // { dg-error "" } + // { dg-warning ".volatile.-qualified type is deprecated" "" { target c++2a } .-1 } return 0; } - diff --git a/gcc/testsuite/g++.dg/expr/cond9.C b/gcc/testsuite/g++.dg/expr/cond9.C index b344c1f..f7e092e 100644 --- a/gcc/testsuite/g++.dg/expr/cond9.C +++ b/gcc/testsuite/g++.dg/expr/cond9.C @@ -4,7 +4,7 @@ struct A { // { dg-message "A" } A(int); }; -void foo(volatile A a) { +void foo(volatile A a) { // { dg-warning "deprecated" "" { target c++2a } } 1 ? a : 0; // { dg-error "qualifiers|lvalue|no match" } 1 ? 0 : a; // { dg-error "qualifiers|lvalue|no match" } } diff --git a/gcc/testsuite/g++.dg/ext/vector25.C b/gcc/testsuite/g++.dg/ext/vector25.C index 6c1f5d0..339865d 100644 --- a/gcc/testsuite/g++.dg/ext/vector25.C +++ b/gcc/testsuite/g++.dg/ext/vector25.C @@ -2,5 +2,5 @@ volatile int i __attribute__((vector_size(8))); void foo() { - i += i; + i += i; // { dg-warning "deprecated" "" { target c++2a } } } diff --git a/gcc/testsuite/g++.dg/gomp/depend-iterator-1.C b/gcc/testsuite/g++.dg/gomp/depend-iterator-1.C index 6f4aa97..d12670c 100644 --- a/gcc/testsuite/g++.dg/gomp/depend-iterator-1.C +++ b/gcc/testsuite/g++.dg/gomp/depend-iterator-1.C @@ -1,3 +1,5 @@ +// { dg-additional-options "-Wno-volatile" } + int arr[64], arr2[64]; struct S { int a[4]; } k; short arr4[4]; diff --git a/gcc/testsuite/g++.dg/inherit/covariant21.C b/gcc/testsuite/g++.dg/inherit/covariant21.C index 42cdf87..769cb14 100644 --- a/gcc/testsuite/g++.dg/inherit/covariant21.C +++ b/gcc/testsuite/g++.dg/inherit/covariant21.C @@ -6,12 +6,12 @@ struct C : A, B {}; struct X { - virtual B* foo(volatile int); + virtual B* foo(volatile int); // { dg-warning "deprecated" "" { target c++2a } } }; struct Y : X { - virtual C* foo(volatile int); + virtual C* foo(volatile int); // { dg-warning "deprecated" "" { target c++2a } } }; -C* Y::foo(volatile int) { return 0; } +C* Y::foo(volatile int) { return 0; } // { dg-warning "deprecated" "" { target c++2a } } diff --git a/gcc/testsuite/g++.dg/init/ref18.C b/gcc/testsuite/g++.dg/init/ref18.C index e704077..81ac76a 100644 --- a/gcc/testsuite/g++.dg/init/ref18.C +++ b/gcc/testsuite/g++.dg/init/ref18.C @@ -1,6 +1,6 @@ // PR c++/49395 -volatile int foo(); +volatile int foo(); // { dg-warning "deprecated" "" { target c++2a } } struct A { volatile int i; }; typedef volatile int vi; diff --git a/gcc/testsuite/g++.dg/ipa/pr63838.C b/gcc/testsuite/g++.dg/ipa/pr63838.C index d23b313..5b6b11d 100644 --- a/gcc/testsuite/g++.dg/ipa/pr63838.C +++ b/gcc/testsuite/g++.dg/ipa/pr63838.C @@ -7,12 +7,12 @@ __attribute__((noinline, noclone)) static void bar (int); volatile int v; void (*fn) (); -struct S { S () { v++; } ~S () { v++; } }; +struct S { S () { v++; } ~S () { v++; } }; // { dg-warning "deprecated" "" { target c++2a } } __attribute__((noinline, noclone)) static void foo (int x) { - v++; + v++; // { dg-warning "deprecated" "" { target c++2a } } if (x == 5) bar (x); } @@ -20,7 +20,7 @@ foo (int x) __attribute__((noinline, noclone)) static void bar (int x) { - v++; + v++; // { dg-warning "deprecated" "" { target c++2a } } if (x == 6) foo (x); else if (x == 5) diff --git a/gcc/testsuite/g++.dg/overload/rvalue2.C b/gcc/testsuite/g++.dg/overload/rvalue2.C index 8a2290d..a829fb5 100644 --- a/gcc/testsuite/g++.dg/overload/rvalue2.C +++ b/gcc/testsuite/g++.dg/overload/rvalue2.C @@ -7,5 +7,5 @@ template void f(const T&); int main() { volatile int i = 0; - f(i++); + f(i++); // { dg-warning "deprecated" "" { target c++2a } } } diff --git a/gcc/testsuite/g++.dg/parse/semicolon4.C b/gcc/testsuite/g++.dg/parse/semicolon4.C index 5135ec1..bdd1c84 100644 --- a/gcc/testsuite/g++.dg/parse/semicolon4.C +++ b/gcc/testsuite/g++.dg/parse/semicolon4.C @@ -25,7 +25,7 @@ struct E1 } const; // { dg-error "'const' can only be specified for objects and functions" } void foo ( -struct E2 +struct E2 // { dg-warning "deprecated" "" { target c++2a } } { // { dg-error "types may not be defined in parameter types" } int i; } volatile); diff --git a/gcc/testsuite/g++.dg/warn/Wreturn-type-4.C b/gcc/testsuite/g++.dg/warn/Wreturn-type-4.C index 4f02678..24a6b41 100644 --- a/gcc/testsuite/g++.dg/warn/Wreturn-type-4.C +++ b/gcc/testsuite/g++.dg/warn/Wreturn-type-4.C @@ -3,6 +3,7 @@ /* { dg-options "-Wignored-qualifiers" } */ volatile void bar(); /* { dg-warning "type qualifiers ignored" } */ +// { dg-warning ".volatile.-qualified return type is deprecated" "" { target c++2a } .-1 } struct A { diff --git a/gcc/testsuite/g++.dg/warn/pr36069.C b/gcc/testsuite/g++.dg/warn/pr36069.C index efb35c2..7b16635 100644 --- a/gcc/testsuite/g++.dg/warn/pr36069.C +++ b/gcc/testsuite/g++.dg/warn/pr36069.C @@ -6,11 +6,13 @@ struct foo { bool a; volatile bool b,c; foo() { a = b = c = false; } // { dg-bogus "parentheses" } + // { dg-warning "deprecated" "" { target c++2a } .-1 } }; int main() { bool a; volatile bool b,c; a = b = c = false; // { dg-bogus "parentheses" } + // { dg-warning "deprecated" "" { target c++2a } .-1 } foo A; } diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p9506.C b/gcc/testsuite/g++.old-deja/g++.mike/p9506.C index db16e37..9759464 100644 --- a/gcc/testsuite/g++.old-deja/g++.mike/p9506.C +++ b/gcc/testsuite/g++.old-deja/g++.mike/p9506.C @@ -3,5 +3,5 @@ char * volatile p; void foo() { - --p = 0; + --p = 0; // { dg-warning "deprecated" "" { target c++2a } } } diff --git a/gcc/testsuite/g++.old-deja/g++.other/volatile1.C b/gcc/testsuite/g++.old-deja/g++.other/volatile1.C index 7d818fb..a93ef58 100644 --- a/gcc/testsuite/g++.old-deja/g++.other/volatile1.C +++ b/gcc/testsuite/g++.old-deja/g++.other/volatile1.C @@ -5,7 +5,7 @@ class f_class // { dg-message "note" "candidates" } { }; -volatile f_class +volatile f_class // { dg-warning "deprecated" "" { target c++2a } } ret_v_f_class() { f_class t; -- cgit v1.1 From f48e4da3259d52076f86aa081cece40dfda7b235 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 29 Aug 2019 08:07:35 +0000 Subject: re PR tree-optimization/91568 (internal compiler error: in vect_schedule_slp_instance, at tree-vect-slp.c:3922) 2019-08-29 Richard Biener PR tree-optimization/91568 * tree-vectorizer.h (_slp_tree::max_nunits): Add. (vect_update_max_nunits): Add overload for poly_uint64. * tree-vect-slp.c (vect_create_new_slp_node): Initialize it. (vect_build_slp_tree): Record max_nunits into the subtree and merge it upwards. (vect_print_slp_tree): Print max_nunits. * gfortran.dg/pr91568.f: New testcase. From-SVN: r275023 --- gcc/ChangeLog | 10 ++++++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gfortran.dg/pr91568.f | 11 +++++++++++ gcc/tree-vect-slp.c | 20 +++++++++++++++----- gcc/tree-vectorizer.h | 19 +++++++++++++++---- 5 files changed, 56 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/pr91568.f (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c4a7b30..49ab435 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2019-08-29 Richard Biener + + PR tree-optimization/91568 + * tree-vectorizer.h (_slp_tree::max_nunits): Add. + (vect_update_max_nunits): Add overload for poly_uint64. + * tree-vect-slp.c (vect_create_new_slp_node): Initialize it. + (vect_build_slp_tree): Record max_nunits into the subtree + and merge it upwards. + (vect_print_slp_tree): Print max_nunits. + 2019-08-28 Marek Polacek Implement P1152R4: Deprecating some uses of volatile. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3a503ac..3a4f36e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-08-29 Richard Biener + + PR tree-optimization/91568 + * gfortran.dg/pr91568.f: New testcase. + 2019-08-28 Marek Polacek Implement P1152R4: Deprecating some uses of volatile. diff --git a/gcc/testsuite/gfortran.dg/pr91568.f b/gcc/testsuite/gfortran.dg/pr91568.f new file mode 100644 index 0000000..4ada559 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr91568.f @@ -0,0 +1,11 @@ +! { dg-do compile } +! { dg-options "-Ofast" } + subroutine h3dall(z,hvec,hder,nterms) + complex *16 hvec(0:1),hder(0:1) + complex *16 z,zinv,ztmp/1.0/ + zinv=1.0/z + do i=1,nterms + ztmp=zinv*i + hder(i)=hvec(i-1)-ztmp*hvec(i) + enddo + end diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index 52f2a06..9b86b67 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -129,6 +129,7 @@ vect_create_new_slp_node (vec scalar_stmts) SLP_TREE_TWO_OPERATORS (node) = false; SLP_TREE_DEF_TYPE (node) = vect_internal_def; node->refcnt = 1; + node->max_nunits = 1; unsigned i; FOR_EACH_VEC_ELT (scalar_stmts, i, stmt_info) @@ -1067,14 +1068,22 @@ vect_build_slp_tree (vec_info *vinfo, dump_printf_loc (MSG_NOTE, vect_location, "re-using %sSLP tree %p\n", *leader ? "" : "failed ", *leader); if (*leader) - (*leader)->refcnt++; + { + (*leader)->refcnt++; + vect_update_max_nunits (max_nunits, (*leader)->max_nunits); + } return *leader; } + poly_uint64 this_max_nunits = 1; slp_tree res = vect_build_slp_tree_2 (vinfo, stmts, group_size, max_nunits, matches, npermutes, tree_size, bst_map); - /* Keep a reference for the bst_map use. */ if (res) - res->refcnt++; + { + res->max_nunits = this_max_nunits; + vect_update_max_nunits (max_nunits, this_max_nunits); + /* Keep a reference for the bst_map use. */ + res->refcnt++; + } bst_map->put (stmts.copy (), res); return res; } @@ -1473,9 +1482,10 @@ vect_print_slp_tree (dump_flags_t dump_kind, dump_location_t loc, dump_metadata_t metadata (dump_kind, loc.get_impl_location ()); dump_user_location_t user_loc = loc.get_user_location (); - dump_printf_loc (metadata, user_loc, "node%s %p\n", + dump_printf_loc (metadata, user_loc, "node%s %p (max_nunits=%u)\n", SLP_TREE_DEF_TYPE (node) != vect_internal_def - ? " (external)" : "", node); + ? " (external)" : "", node, + estimated_poly_value (node->max_nunits)); FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt_info) dump_printf_loc (metadata, user_loc, "\tstmt %d %G", i, stmt_info->stmt); if (SLP_TREE_CHILDREN (node).is_empty ()) diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 1456cde..05ad1c6 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -132,6 +132,9 @@ struct _slp_tree { unsigned int vec_stmts_size; /* Reference count in the SLP graph. */ unsigned int refcnt; + /* The maximum number of vector elements for the subtree rooted + at this node. */ + poly_uint64 max_nunits; /* Whether the scalar computations use two different operators. */ bool two_operators; /* The DEF type of this node. */ @@ -1375,19 +1378,27 @@ vect_get_num_copies (loop_vec_info loop_vinfo, tree vectype) } /* Update maximum unit count *MAX_NUNITS so that it accounts for - the number of units in vector type VECTYPE. *MAX_NUNITS can be 1 - if we haven't yet recorded any vector types. */ + NUNITS. *MAX_NUNITS can be 1 if we haven't yet recorded anything. */ static inline void -vect_update_max_nunits (poly_uint64 *max_nunits, tree vectype) +vect_update_max_nunits (poly_uint64 *max_nunits, poly_uint64 nunits) { /* All unit counts have the form current_vector_size * X for some rational X, so two unit sizes must have a common multiple. Everything is a multiple of the initial value of 1. */ - poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype); *max_nunits = force_common_multiple (*max_nunits, nunits); } +/* Update maximum unit count *MAX_NUNITS so that it accounts for + the number of units in vector type VECTYPE. *MAX_NUNITS can be 1 + if we haven't yet recorded any vector types. */ + +static inline void +vect_update_max_nunits (poly_uint64 *max_nunits, tree vectype) +{ + vect_update_max_nunits (max_nunits, TYPE_VECTOR_SUBPARTS (vectype)); +} + /* Return the vectorization factor that should be used for costing purposes while vectorizing the loop described by LOOP_VINFO. Pick a reasonable estimate if the vectorization factor isn't -- cgit v1.1 From c3bad34748071038343f8b88a30128faee7c5c0c Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Thu, 29 Aug 2019 09:01:26 +0000 Subject: decl.c (check_var_type): Add location_t parameter and use it. /cp 2019-08-29 Paolo Carlini * decl.c (check_var_type): Add location_t parameter and use it. (grokdeclarator): Adjust call. * pt.c (tsubst_decl): Likewise. * cp-tree.h: Adjust declaration. /testsuite 2019-08-29 Paolo Carlini * g++.dg/spellcheck-typenames.C: Adjust expected locations. * g++.dg/cpp0x/pr84676.C: Check locations. * g++.dg/other/pr88187.C: Likewise. * g++.dg/parse/crash13.C: Likewise. * g++.dg/parse/crash46.C: Likewise. * g++.dg/parse/template28.C: Likewise. * g++.dg/parse/typename4.C: Likewise. From-SVN: r275025 --- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/cp-tree.h | 2 +- gcc/cp/decl.c | 11 ++++++----- gcc/cp/pt.c | 4 ++-- gcc/testsuite/ChangeLog | 10 ++++++++++ gcc/testsuite/g++.dg/cpp0x/pr84676.C | 3 ++- gcc/testsuite/g++.dg/other/pr88187.C | 2 +- gcc/testsuite/g++.dg/parse/crash13.C | 3 ++- gcc/testsuite/g++.dg/parse/crash46.C | 6 +++--- gcc/testsuite/g++.dg/parse/template28.C | 3 ++- gcc/testsuite/g++.dg/parse/typename4.C | 3 ++- gcc/testsuite/g++.dg/spellcheck-typenames.C | 8 ++++---- 12 files changed, 42 insertions(+), 20 deletions(-) (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 818d32b..37de3d9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2019-08-29 Paolo Carlini + + * decl.c (check_var_type): Add location_t parameter and use it. + (grokdeclarator): Adjust call. + * pt.c (tsubst_decl): Likewise. + * cp-tree.h: Adjust declaration. + 2019-08-28 Marek Polacek Implement P1152R4: Deprecating some uses of volatile. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 0e514d5..3c69e54 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6478,7 +6478,7 @@ extern tree cxx_comdat_group (tree); extern bool cp_missing_noreturn_ok_p (tree); extern bool is_direct_enum_init (tree, tree); extern void initialize_artificial_var (tree, vec *); -extern tree check_var_type (tree, tree); +extern tree check_var_type (tree, tree, location_t); extern tree reshape_init (tree, tree, tsubst_flags_t); extern tree next_initializable_field (tree); extern tree fndecl_declared_return_type (tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 2aef330..3497874 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -10298,19 +10298,20 @@ check_special_function_return_type (special_function_kind sfk, error-recovery purposes. */ tree -check_var_type (tree identifier, tree type) +check_var_type (tree identifier, tree type, location_t loc) { if (VOID_TYPE_P (type)) { if (!identifier) - error ("unnamed variable or field declared void"); + error_at (loc, "unnamed variable or field declared void"); else if (identifier_p (identifier)) { gcc_assert (!IDENTIFIER_ANY_OP_P (identifier)); - error ("variable or field %qE declared void", identifier); + error_at (loc, "variable or field %qE declared void", + identifier); } else - error ("variable or field declared void"); + error_at (loc, "variable or field declared void"); type = error_mark_node; } @@ -12470,7 +12471,7 @@ grokdeclarator (const cp_declarator *declarator, error message later. */ if (decl_context != PARM) { - type = check_var_type (unqualified_id, type); + type = check_var_type (unqualified_id, type, id_loc); if (type == error_mark_node) return error_mark_node; } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 54d36f9..13d3db9 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -13894,8 +13894,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) /* Wait until cp_finish_decl to set this again, to handle circular dependency (template/instantiate6.C). */ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r) = 0; - type = check_var_type (DECL_NAME (r), type); - + type = check_var_type (DECL_NAME (r), type, + DECL_SOURCE_LOCATION (r)); if (DECL_HAS_VALUE_EXPR_P (t)) { tree ve = DECL_VALUE_EXPR (t); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3a4f36e..a051dda 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2019-08-29 Paolo Carlini + + * g++.dg/spellcheck-typenames.C: Adjust expected locations. + * g++.dg/cpp0x/pr84676.C: Check locations. + * g++.dg/other/pr88187.C: Likewise. + * g++.dg/parse/crash13.C: Likewise. + * g++.dg/parse/crash46.C: Likewise. + * g++.dg/parse/template28.C: Likewise. + * g++.dg/parse/typename4.C: Likewise. + 2019-08-29 Richard Biener PR tree-optimization/91568 diff --git a/gcc/testsuite/g++.dg/cpp0x/pr84676.C b/gcc/testsuite/g++.dg/cpp0x/pr84676.C index 94d8671..0bd8cc0 100644 --- a/gcc/testsuite/g++.dg/cpp0x/pr84676.C +++ b/gcc/testsuite/g++.dg/cpp0x/pr84676.C @@ -1,4 +1,5 @@ // { dg-do compile { target c++11 } } int a; -void b(__attribute__((c([](int *) {} (a == (0 = auto)))))); // { dg-error "" } +void b(__attribute__((c([](int *) {} (a == (0 = auto)))))); // { dg-error "6:variable or field .b. declared void" } +// { dg-error "expected" "" { target c++11 } .-1 } diff --git a/gcc/testsuite/g++.dg/other/pr88187.C b/gcc/testsuite/g++.dg/other/pr88187.C index 17c14f4..ebdafdd 100644 --- a/gcc/testsuite/g++.dg/other/pr88187.C +++ b/gcc/testsuite/g++.dg/other/pr88187.C @@ -2,6 +2,6 @@ // { dg-do compile } template struct A; -void f (A ()); // { dg-error "variable or field 'f' declared void" "" { target c++14_down } } +void f (A ()); // { dg-error "6:variable or field 'f' declared void" "" { target c++14_down } } // { dg-error "missing template arguments before '\\(' token" "" { target c++14_down } .-1 } // { dg-error "'auto' parameter not permitted in this context" "" { target c++17 } .-2 } diff --git a/gcc/testsuite/g++.dg/parse/crash13.C b/gcc/testsuite/g++.dg/parse/crash13.C index 3c298ec..ab64011 100644 --- a/gcc/testsuite/g++.dg/parse/crash13.C +++ b/gcc/testsuite/g++.dg/parse/crash13.C @@ -12,7 +12,8 @@ struct A }; template -void func(A::B* ) // { dg-error "variable|template|expression" } +void func(A::B* ) // { dg-error "6:variable or field .func. declared void" } +// { dg-error "expected" "" { target *-*-* } .-1 } { } diff --git a/gcc/testsuite/g++.dg/parse/crash46.C b/gcc/testsuite/g++.dg/parse/crash46.C index 0ae2248..cb60ad2 100644 --- a/gcc/testsuite/g++.dg/parse/crash46.C +++ b/gcc/testsuite/g++.dg/parse/crash46.C @@ -2,17 +2,17 @@ // { dg-do compile } void -foo (_Decimal32) // { dg-error "declared void" "declared" } +foo (_Decimal32) // { dg-error "1:variable or field .foo. declared void" "declared" } { } // { dg-error "was not declared" "not" { target *-*-* } 5 } void -bar (_Bool) // { dg-error "declared void" "declared" } +bar (_Bool) // { dg-error "1:variable or field .bar. declared void" "declared" } { } // { dg-error "was not declared" "not" { target *-*-* } 10 } void -baz (_Fract) // { dg-error "declared void" "declared" } +baz (_Fract) // { dg-error "1:variable or field .baz. declared void" "declared" } { } // { dg-error "was not declared" "not" { target *-*-* } 15 } diff --git a/gcc/testsuite/g++.dg/parse/template28.C b/gcc/testsuite/g++.dg/parse/template28.C index 6868bc8..bfd8af1 100644 --- a/gcc/testsuite/g++.dg/parse/template28.C +++ b/gcc/testsuite/g++.dg/parse/template28.C @@ -2,7 +2,8 @@ template struct A {}; -template void foo(A=A()) {} // { dg-error "" } +template void foo(A=A()) {} // { dg-error "24:variable or field .foo. declared void" } +// { dg-error "template" "" { target *-*-* } .-1 } void bar() { diff --git a/gcc/testsuite/g++.dg/parse/typename4.C b/gcc/testsuite/g++.dg/parse/typename4.C index 529889d..94ab98f 100644 --- a/gcc/testsuite/g++.dg/parse/typename4.C +++ b/gcc/testsuite/g++.dg/parse/typename4.C @@ -4,4 +4,5 @@ // PR c++/9364: ICE processing typename with name error. -void find(typename int&); // { dg-error "typename|void|expected" } +void find(typename int&); // { dg-error "6:variable or field .find. declared void" } +// { dg-error "expected" "" { target *-*-* } .-1 } diff --git a/gcc/testsuite/g++.dg/spellcheck-typenames.C b/gcc/testsuite/g++.dg/spellcheck-typenames.C index 25d3f1d..6adf724 100644 --- a/gcc/testsuite/g++.dg/spellcheck-typenames.C +++ b/gcc/testsuite/g++.dg/spellcheck-typenames.C @@ -4,10 +4,10 @@ void test_1 (signed char e); /* PR c/70339. */ -void test_2 (singed char e); // { dg-error "21: variable or field 'test_2' declared void" } +void test_2 (singed char e); // { dg-error "6: variable or field 'test_2' declared void" } /* { dg-begin-multiline-output "" } void test_2 (singed char e); - ^~~~ + ^~~~~~ { dg-end-multiline-output "" } */ // { dg-message "14: 'singed' was not declared in this scope; did you mean 'signed'\\?" "" { target *-*-* } 7 } /* { dg-begin-multiline-output "" } @@ -16,10 +16,10 @@ void test_2 (singed char e); // { dg-error "21: variable or field 'test_2' decla signed { dg-end-multiline-output "" } */ -void test_3 (car e); // { dg-error "14: variable or field 'test_3' declared void" } +void test_3 (car e); // { dg-error "6: variable or field 'test_3' declared void" } /* { dg-begin-multiline-output "" } void test_3 (car e); - ^~~ + ^~~~~~ { dg-end-multiline-output "" } */ // { dg-message "14: 'car' was not declared in this scope; did you mean 'char'\\?" "" { target *-*-* } 19 } /* { dg-begin-multiline-output "" } -- cgit v1.1 From 1d9cd701ec31686dbd037e0fe264c8738d993e41 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 29 Aug 2019 11:20:54 +0200 Subject: re PR tree-optimization/91351 (-fstrict-enums generates incorrect code) PR tree-optimization/91351 * tree-cfg.c (generate_range_test): Use range_check_type instead of unsigned_type_for. * tree-cfgcleanup.c (convert_single_case_switch): Punt if range_check_type returns NULL. * tree-switch-conversion.c (switch_conversion::build_one_array): Use range_check_type instead of unsigned_type_for, don't perform linear opt if it returns NULL. (bit_test_cluster::find_bit_tests): Formatting fix. (bit_test_cluster::emit): Use range_check_type instead of unsigned_type_for. (switch_decision_tree::try_switch_expansion): Punt if range_check_type returns NULL. * g++.dg/opt/pr91351.C: New test. From-SVN: r275026 --- gcc/ChangeLog | 16 ++++++++++++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/opt/pr91351.C | 38 ++++++++++++++++++++++++++++++++++++++ gcc/tree-cfg.c | 2 +- gcc/tree-cfgcleanup.c | 2 ++ gcc/tree-switch-conversion.c | 22 ++++++++++++---------- 6 files changed, 74 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/g++.dg/opt/pr91351.C (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 49ab435..6342c4a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2019-08-29 Jakub Jelinek + + PR tree-optimization/91351 + * tree-cfg.c (generate_range_test): Use range_check_type instead of + unsigned_type_for. + * tree-cfgcleanup.c (convert_single_case_switch): Punt if + range_check_type returns NULL. + * tree-switch-conversion.c (switch_conversion::build_one_array): + Use range_check_type instead of unsigned_type_for, don't perform + linear opt if it returns NULL. + (bit_test_cluster::find_bit_tests): Formatting fix. + (bit_test_cluster::emit): Use range_check_type instead of + unsigned_type_for. + (switch_decision_tree::try_switch_expansion): Punt if range_check_type + returns NULL. + 2019-08-29 Richard Biener PR tree-optimization/91568 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a051dda..652759a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-08-29 Jakub Jelinek + + PR tree-optimization/91351 + * g++.dg/opt/pr91351.C: New test. + 2019-08-29 Paolo Carlini * g++.dg/spellcheck-typenames.C: Adjust expected locations. diff --git a/gcc/testsuite/g++.dg/opt/pr91351.C b/gcc/testsuite/g++.dg/opt/pr91351.C new file mode 100644 index 0000000..f793a2f --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr91351.C @@ -0,0 +1,38 @@ +// PR tree-optimization/91351 +// { dg-do run } +// { dg-options "-O2 -fstrict-enums" } + +enum E { e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, + e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25 }; + +__attribute__((noipa)) void +foo () +{ + __builtin_abort (); +} + +__attribute__((noipa)) void +bar () +{ +} + +__attribute__((noipa)) void +baz (E e) +{ + switch (e) + { + case e11: + case e12: + case e13: foo (); break; + case e24: break; + case e14: + case e15: break; + default: bar (); break; + } +} + +int +main () +{ + baz (e3); +} diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 2648663..b75fdb2 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -9221,7 +9221,7 @@ generate_range_test (basic_block bb, tree index, tree low, tree high, tree *lhs, tree *rhs) { tree type = TREE_TYPE (index); - tree utype = unsigned_type_for (type); + tree utype = range_check_type (type); low = fold_convert (utype, low); high = fold_convert (utype, high); diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c index 183b491..4bac38a 100644 --- a/gcc/tree-cfgcleanup.c +++ b/gcc/tree-cfgcleanup.c @@ -101,6 +101,8 @@ convert_single_case_switch (gswitch *swtch, gimple_stmt_iterator &gsi) if (high) { tree lhs, rhs; + if (range_check_type (TREE_TYPE (index)) == NULL_TREE) + return false; generate_range_test (bb, index, low, high, &lhs, &rhs); cond = gimple_build_cond (LE_EXPR, lhs, rhs, NULL_TREE, NULL_TREE); } diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c index 776db77..e8692a7 100644 --- a/gcc/tree-switch-conversion.c +++ b/gcc/tree-switch-conversion.c @@ -605,7 +605,9 @@ switch_conversion::build_one_array (int num, tree arr_index_type, vec *constructor = m_constructors[num]; wide_int coeff_a, coeff_b; bool linear_p = contains_linear_function_p (constructor, &coeff_a, &coeff_b); - if (linear_p) + tree type; + if (linear_p + && (type = range_check_type (TREE_TYPE ((*constructor)[0].value)))) { if (dump_file && coeff_a.to_uhwi () > 0) fprintf (dump_file, "Linear transformation with A = %" PRId64 @@ -613,13 +615,12 @@ switch_conversion::build_one_array (int num, tree arr_index_type, coeff_b.to_shwi ()); /* We must use type of constructor values. */ - tree t = unsigned_type_for (TREE_TYPE ((*constructor)[0].value)); gimple_seq seq = NULL; - tree tmp = gimple_convert (&seq, t, m_index_expr); - tree tmp2 = gimple_build (&seq, MULT_EXPR, t, - wide_int_to_tree (t, coeff_a), tmp); - tree tmp3 = gimple_build (&seq, PLUS_EXPR, t, tmp2, - wide_int_to_tree (t, coeff_b)); + tree tmp = gimple_convert (&seq, type, m_index_expr); + tree tmp2 = gimple_build (&seq, MULT_EXPR, type, + wide_int_to_tree (type, coeff_a), tmp); + tree tmp3 = gimple_build (&seq, PLUS_EXPR, type, tmp2, + wide_int_to_tree (type, coeff_b)); tree tmp4 = gimple_convert (&seq, TREE_TYPE (name), tmp3); gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT); load = gimple_build_assign (name, tmp4); @@ -1351,7 +1352,7 @@ bit_test_cluster::find_bit_tests (vec &clusters) entire)); } else - for (int i = end - 1; i >= start; i--) + for (int i = end - 1; i >= start; i--) output.safe_push (clusters[i]); end = start; @@ -1484,7 +1485,7 @@ bit_test_cluster::emit (tree index_expr, tree index_type, unsigned int i, j, k; unsigned int count; - tree unsigned_index_type = unsigned_type_for (index_type); + tree unsigned_index_type = range_check_type (index_type); gimple_stmt_iterator gsi; gassign *shift_stmt; @@ -1794,7 +1795,8 @@ switch_decision_tree::try_switch_expansion (vec &clusters) tree index_type = TREE_TYPE (index_expr); basic_block bb = gimple_bb (m_switch); - if (gimple_switch_num_labels (m_switch) == 1) + if (gimple_switch_num_labels (m_switch) == 1 + || range_check_type (index_type) == NULL_TREE) return false; /* Find the default case target label. */ -- cgit v1.1 From 4bf4c103ee457d8fb6872a438de38ec4340cf85f Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 29 Aug 2019 11:22:57 +0200 Subject: re PR target/91560 (Try harder for AVX non-AVX2 cross-lane permutations) PR target/91560 * config/i386/i386-expand.c (expand_vec_perm_movs, expand_vec_perm_blend, expand_vec_perm_vpermil, expand_vec_perm_pshufb, expand_vec_perm_1, expand_vec_perm_pshuflw_pshufhw, expand_vec_perm_palignr, expand_vec_perm_interleave2, expand_vec_perm_vpermq_perm_1, expand_vec_perm_vperm2f128, expand_vec_perm_interleave3, expand_vec_perm_vperm2f128_vblend, expand_vec_perm_2vperm2f128_vshuf, expand_vec_perm_even_odd, expand_vec_perm_broadcast): Adjust function comments - replace ix86_expand_vec_perm_builtin_1 with ix86_expand_vec_perm_const_1. (expand_vec_perm2_vperm2f128_vblend): New function. (ix86_expand_vec_perm_const_1): New forward declaration. Call expand_vec_perm2_vperm2f128_vblend as last resort. (canonicalize_perm): Formatting fix. * gcc.dg/torture/vshuf-8.inc: Add two further permutations. From-SVN: r275027 --- gcc/ChangeLog | 16 ++++ gcc/config/i386/i386-expand.c | 140 +++++++++++++++++++++++++++---- gcc/testsuite/ChangeLog | 3 + gcc/testsuite/gcc.dg/torture/vshuf-8.inc | 4 +- 4 files changed, 144 insertions(+), 19 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6342c4a..9deb5b0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,21 @@ 2019-08-29 Jakub Jelinek + PR target/91560 + * config/i386/i386-expand.c (expand_vec_perm_movs, + expand_vec_perm_blend, expand_vec_perm_vpermil, + expand_vec_perm_pshufb, expand_vec_perm_1, + expand_vec_perm_pshuflw_pshufhw, expand_vec_perm_palignr, + expand_vec_perm_interleave2, expand_vec_perm_vpermq_perm_1, + expand_vec_perm_vperm2f128, expand_vec_perm_interleave3, + expand_vec_perm_vperm2f128_vblend, expand_vec_perm_2vperm2f128_vshuf, + expand_vec_perm_even_odd, expand_vec_perm_broadcast): Adjust function + comments - replace ix86_expand_vec_perm_builtin_1 with + ix86_expand_vec_perm_const_1. + (expand_vec_perm2_vperm2f128_vblend): New function. + (ix86_expand_vec_perm_const_1): New forward declaration. Call + expand_vec_perm2_vperm2f128_vblend as last resort. + (canonicalize_perm): Formatting fix. + PR tree-optimization/91351 * tree-cfg.c (generate_range_test): Use range_check_type instead of unsigned_type_for. diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c index b6a2dbf..ec50de2 100644 --- a/gcc/config/i386/i386-expand.c +++ b/gcc/config/i386/i386-expand.c @@ -16372,7 +16372,7 @@ expand_vselect_vconcat (rtx target, rtx op0, rtx op1, return ok; } -/* A subroutine of ix86_expand_vec_perm_builtin_1. Try to implement D +/* A subroutine of ix86_expand_vec_perm_const_1. Try to implement D using movss or movsd. */ static bool expand_vec_perm_movs (struct expand_vec_perm_d *d) @@ -16408,7 +16408,7 @@ expand_vec_perm_movs (struct expand_vec_perm_d *d) return true; } -/* A subroutine of ix86_expand_vec_perm_builtin_1. Try to implement D +/* A subroutine of ix86_expand_vec_perm_const_1. Try to implement D in terms of blendp[sd] / pblendw / pblendvb / vpblendd. */ static bool @@ -16633,7 +16633,7 @@ expand_vec_perm_blend (struct expand_vec_perm_d *d) return true; } -/* A subroutine of ix86_expand_vec_perm_builtin_1. Try to implement D +/* A subroutine of ix86_expand_vec_perm_const_1. Try to implement D in terms of the variable form of vpermilps. Note that we will have already failed the immediate input vpermilps, @@ -16709,7 +16709,7 @@ valid_perm_using_mode_p (machine_mode vmode, struct expand_vec_perm_d *d) return true; } -/* A subroutine of ix86_expand_vec_perm_builtin_1. Try to implement D +/* A subroutine of ix86_expand_vec_perm_const_1. Try to implement D in terms of pshufb, vpperm, vpermq, vpermd, vpermps or vperm2i128. */ static bool @@ -17026,7 +17026,7 @@ ix86_expand_vec_one_operand_perm_avx512 (struct expand_vec_perm_d *d) static bool expand_vec_perm_palignr (struct expand_vec_perm_d *d, bool); -/* A subroutine of ix86_expand_vec_perm_builtin_1. Try to instantiate D +/* A subroutine of ix86_expand_vec_perm_const_1. Try to instantiate D in a single instruction. */ static bool @@ -17216,7 +17216,7 @@ expand_vec_perm_1 (struct expand_vec_perm_d *d) return false; } -/* A subroutine of ix86_expand_vec_perm_builtin_1. Try to implement D +/* A subroutine of ix86_expand_vec_perm_const_1. Try to implement D in terms of a pair of pshuflw + pshufhw instructions. */ static bool @@ -17257,7 +17257,7 @@ expand_vec_perm_pshuflw_pshufhw (struct expand_vec_perm_d *d) return true; } -/* A subroutine of ix86_expand_vec_perm_builtin_1. Try to simplify +/* A subroutine of ix86_expand_vec_perm_const_1. Try to simplify the permutation using the SSSE3 palignr instruction. This succeeds when all of the elements in PERM fit within one vector and we merely need to shift them down so that a single vector permutation has a @@ -17474,7 +17474,7 @@ expand_vec_perm_pblendv (struct expand_vec_perm_d *d) static bool expand_vec_perm_interleave3 (struct expand_vec_perm_d *d); -/* A subroutine of ix86_expand_vec_perm_builtin_1. Try to simplify +/* A subroutine of ix86_expand_vec_perm_const_1. Try to simplify a two vector permutation into a single vector permutation by using an interleave operation to merge the vectors. */ @@ -17752,7 +17752,7 @@ expand_vec_perm_interleave2 (struct expand_vec_perm_d *d) return true; } -/* A subroutine of ix86_expand_vec_perm_builtin_1. Try to simplify +/* A subroutine of ix86_expand_vec_perm_const_1. Try to simplify a single vector cross-lane permutation into vpermq followed by any of the single insn permutations. */ @@ -17833,7 +17833,7 @@ expand_vec_perm_vpermq_perm_1 (struct expand_vec_perm_d *d) static bool canonicalize_perm (struct expand_vec_perm_d *d); -/* A subroutine of ix86_expand_vec_perm_builtin_1. Try to expand +/* A subroutine of ix86_expand_vec_perm_const_1. Try to expand a vector permutation using two instructions, vperm2f128 resp. vperm2i128 followed by any single in-lane permutation. */ @@ -17950,7 +17950,7 @@ expand_vec_perm_vperm2f128 (struct expand_vec_perm_d *d) return false; } -/* A subroutine of ix86_expand_vec_perm_builtin_1. Try to simplify +/* A subroutine of ix86_expand_vec_perm_const_1. Try to simplify a two vector permutation using 2 intra-lane interleave insns and cross-lane shuffle for 32-byte vectors. */ @@ -18026,7 +18026,7 @@ expand_vec_perm_interleave3 (struct expand_vec_perm_d *d) return true; } -/* A subroutine of ix86_expand_vec_perm_builtin_1. Try to implement +/* A subroutine of ix86_expand_vec_perm_const_1. Try to implement a single vector permutation using a single intra-lane vector permutation, vperm2f128 swapping the lanes and vblend* insn blending the non-swapped and swapped vectors together. */ @@ -18094,7 +18094,7 @@ expand_vec_perm_vperm2f128_vblend (struct expand_vec_perm_d *d) return true; } -/* A subroutine of ix86_expand_vec_perm_builtin_1. Implement a V4DF +/* A subroutine of ix86_expand_vec_perm_const_1. Implement a V4DF permutation using two vperm2f128, followed by a vshufpd insn blending the two vectors together. */ @@ -18145,6 +18145,106 @@ expand_vec_perm_2vperm2f128_vshuf (struct expand_vec_perm_d *d) return true; } +static bool ix86_expand_vec_perm_const_1 (struct expand_vec_perm_d *); + +/* A subroutine of ix86_expand_vec_perm_const_1. Try to implement + a two vector permutation using two intra-lane vector + permutations, vperm2f128 swapping the lanes and vblend* insn blending + the non-swapped and swapped vectors together. */ + +static bool +expand_vec_perm2_vperm2f128_vblend (struct expand_vec_perm_d *d) +{ + struct expand_vec_perm_d dfirst, dsecond, dthird; + unsigned i, j, msk, nelt = d->nelt, nelt2 = nelt / 2, which1 = 0, which2 = 0; + rtx_insn *seq1, *seq2; + bool ok; + rtx (*blend) (rtx, rtx, rtx, rtx) = NULL; + + if (!TARGET_AVX + || TARGET_AVX2 + || (d->vmode != V8SFmode && d->vmode != V4DFmode) + || d->one_operand_p) + return false; + + dfirst = *d; + dsecond = *d; + for (i = 0; i < nelt; i++) + { + dfirst.perm[i] = 0xff; + dsecond.perm[i] = 0xff; + } + for (i = 0, msk = 0; i < nelt; i++) + { + j = (d->perm[i] & nelt2) ? i | nelt2 : i & ~nelt2; + if (j == i) + { + dfirst.perm[j] = d->perm[i]; + which1 |= (d->perm[i] < nelt ? 1 : 2); + } + else + { + dsecond.perm[j] = d->perm[i]; + which2 |= (d->perm[i] < nelt ? 1 : 2); + msk |= (1U << i); + } + } + if (msk == 0 || msk == (1U << nelt) - 1) + return false; + + if (!d->testing_p) + { + dfirst.target = gen_reg_rtx (dfirst.vmode); + dsecond.target = gen_reg_rtx (dsecond.vmode); + } + + for (i = 0; i < nelt; i++) + { + if (dfirst.perm[i] == 0xff) + dfirst.perm[i] = (which1 == 2 ? i + nelt : i); + if (dsecond.perm[i] == 0xff) + dsecond.perm[i] = (which2 == 2 ? i + nelt : i); + } + canonicalize_perm (&dfirst); + start_sequence (); + ok = ix86_expand_vec_perm_const_1 (&dfirst); + seq1 = get_insns (); + end_sequence (); + + if (!ok) + return false; + + canonicalize_perm (&dsecond); + start_sequence (); + ok = ix86_expand_vec_perm_const_1 (&dsecond); + seq2 = get_insns (); + end_sequence (); + + if (!ok) + return false; + + if (d->testing_p) + return true; + + emit_insn (seq1); + emit_insn (seq2); + + dthird = *d; + dthird.op0 = dsecond.target; + dthird.op1 = dsecond.target; + dthird.one_operand_p = true; + dthird.target = gen_reg_rtx (dthird.vmode); + for (i = 0; i < nelt; i++) + dthird.perm[i] = i ^ nelt2; + + ok = expand_vec_perm_1 (&dthird); + gcc_assert (ok); + + blend = d->vmode == V8SFmode ? gen_avx_blendps256 : gen_avx_blendpd256; + emit_insn (blend (d->target, dfirst.target, dthird.target, GEN_INT (msk))); + return true; +} + /* A subroutine of expand_vec_perm_even_odd_1. Implement the double-word permutation with two pshufb insns and an ior. We should have already failed all two instruction sequences. */ @@ -18534,7 +18634,7 @@ expand_vec_perm_even_odd_trunc (struct expand_vec_perm_d *d) return true; } -/* A subroutine of ix86_expand_vec_perm_builtin_1. Implement extract-even +/* A subroutine of ix86_expand_vec_perm_const_1. Implement extract-even and extract-odd permutations. */ static bool @@ -18743,7 +18843,7 @@ expand_vec_perm_even_odd_1 (struct expand_vec_perm_d *d, unsigned odd) return true; } -/* A subroutine of ix86_expand_vec_perm_builtin_1. Pattern match +/* A subroutine of ix86_expand_vec_perm_const_1. Pattern match extract-even and extract-odd permutations. */ static bool @@ -18762,7 +18862,7 @@ expand_vec_perm_even_odd (struct expand_vec_perm_d *d) return expand_vec_perm_even_odd_1 (d, odd); } -/* A subroutine of ix86_expand_vec_perm_builtin_1. Implement broadcast +/* A subroutine of ix86_expand_vec_perm_const_1. Implement broadcast permutations. We assume that expand_vec_perm_1 has already failed. */ static bool @@ -18841,7 +18941,7 @@ expand_vec_perm_broadcast_1 (struct expand_vec_perm_d *d) } } -/* A subroutine of ix86_expand_vec_perm_builtin_1. Pattern match +/* A subroutine of ix86_expand_vec_perm_const_1. Pattern match broadcast permutations. */ static bool @@ -19137,6 +19237,10 @@ ix86_expand_vec_perm_const_1 (struct expand_vec_perm_d *d) return true; } + /* Even longer, including recursion to ix86_expand_vec_perm_const_1. */ + if (expand_vec_perm2_vperm2f128_vblend (d)) + return true; + return false; } @@ -19149,7 +19253,7 @@ canonicalize_perm (struct expand_vec_perm_d *d) int i, which, nelt = d->nelt; for (i = which = 0; i < nelt; ++i) - which |= (d->perm[i] < nelt ? 1 : 2); + which |= (d->perm[i] < nelt ? 1 : 2); d->one_operand_p = true; switch (which) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 652759a..02734ee 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2019-08-29 Jakub Jelinek + PR target/91560 + * gcc.dg/torture/vshuf-8.inc: Add two further permutations. + PR tree-optimization/91351 * g++.dg/opt/pr91351.C: New test. diff --git a/gcc/testsuite/gcc.dg/torture/vshuf-8.inc b/gcc/testsuite/gcc.dg/torture/vshuf-8.inc index d7a7610..de358f3 100644 --- a/gcc/testsuite/gcc.dg/torture/vshuf-8.inc +++ b/gcc/testsuite/gcc.dg/torture/vshuf-8.inc @@ -25,7 +25,9 @@ T (21, 4, 12, 5, 13, 6, 14, 7, 15) \ T (22, 1, 2, 3, 4, 5, 6, 7, 0) \ T (23, 6, 5, 4, 3, 2, 1, 0, 7) \ T (24, 0, 1, 2, 3, 8, 9, 10, 11) \ -T (25, 0, 1, 2, 3, 12, 13, 14, 15) +T (25, 0, 1, 2, 3, 12, 13, 14, 15) \ +T (26, 0, 1, 8, 9, 10, 11, 12, 13) \ +T (27, 0, 8, 9, 10, 11, 12, 13, 14) #define EXPTESTS \ T (116, 9, 3, 9, 4, 7, 0, 0, 6) \ T (117, 4, 14, 12, 8, 9, 6, 0, 10) \ -- cgit v1.1 From c49609be4fd8751e7295610220889aa20a227dbf Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 29 Aug 2019 10:30:48 +0000 Subject: re PR bootstrap/91580 (i686-{darwin, linux} bootstrap fails after r274926) 2019-08-29 Richard Biener PR bootstrap/91580 * config/i386/i386-features.c (general_scalar_chain::convert_insn): Do not emit scalar copies for debug-insns, instead replace their uses with the reg copy used in the chain or reset them if there is a reaching definition outside of the chain as well. From-SVN: r275030 --- gcc/ChangeLog | 8 ++++++++ gcc/config/i386/i386-features.c | 40 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 3 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9deb5b0..f94dae2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2019-08-29 Richard Biener + + PR bootstrap/91580 + * config/i386/i386-features.c (general_scalar_chain::convert_insn): + Do not emit scalar copies for debug-insns, instead replace + their uses with the reg copy used in the chain or reset them + if there is a reaching definition outside of the chain as well. + 2019-08-29 Jakub Jelinek PR target/91560 diff --git a/gcc/config/i386/i386-features.c b/gcc/config/i386/i386-features.c index d6a1074..f3c0eb6 100644 --- a/gcc/config/i386/i386-features.c +++ b/gcc/config/i386/i386-features.c @@ -880,18 +880,52 @@ general_scalar_chain::convert_op (rtx *op, rtx_insn *insn) void general_scalar_chain::convert_insn (rtx_insn *insn) { - /* Generate copies for out-of-chain uses of defs. */ + /* Generate copies for out-of-chain uses of defs and adjust debug uses. */ for (df_ref ref = DF_INSN_DEFS (insn); ref; ref = DF_REF_NEXT_LOC (ref)) if (bitmap_bit_p (defs_conv, DF_REF_REGNO (ref))) { df_link *use; for (use = DF_REF_CHAIN (ref); use; use = use->next) - if (DF_REF_REG_MEM_P (use->ref) - || !bitmap_bit_p (insns, DF_REF_INSN_UID (use->ref))) + if (NONDEBUG_INSN_P (DF_REF_INSN (use->ref)) + && (DF_REF_REG_MEM_P (use->ref) + || !bitmap_bit_p (insns, DF_REF_INSN_UID (use->ref)))) break; if (use) convert_reg (insn, DF_REF_REG (ref), *defs_map.get (regno_reg_rtx [DF_REF_REGNO (ref)])); + else + { + /* If we generated a scalar copy we can leave debug-insns + as-is, if not, we have to adjust them. */ + auto_vec to_reset_debug_insns; + for (use = DF_REF_CHAIN (ref); use; use = use->next) + if (DEBUG_INSN_P (DF_REF_INSN (use->ref))) + { + rtx_insn *debug_insn = DF_REF_INSN (use->ref); + /* If there's a reaching definition outside of the + chain we have to reset. */ + df_link *def; + for (def = DF_REF_CHAIN (use->ref); def; def = def->next) + if (!bitmap_bit_p (insns, DF_REF_INSN_UID (def->ref))) + break; + if (def) + to_reset_debug_insns.safe_push (debug_insn); + else + { + *DF_REF_REAL_LOC (use->ref) + = *defs_map.get (regno_reg_rtx [DF_REF_REGNO (ref)]); + df_insn_rescan (debug_insn); + } + } + /* Have to do the reset outside of the DF_CHAIN walk to not + disrupt it. */ + while (!to_reset_debug_insns.is_empty ()) + { + rtx_insn *debug_insn = to_reset_debug_insns.pop (); + INSN_VAR_LOCATION_LOC (debug_insn) = gen_rtx_UNKNOWN_VAR_LOC (); + df_insn_rescan_debug_internal (debug_insn); + } + } } /* Replace uses in this insn with the defs we use in the chain. */ -- cgit v1.1 From 132e2b41ef9b7d77ba05a42b89d6ce4cda706e36 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 29 Aug 2019 11:59:41 +0000 Subject: i386-features.c (general_scalar_chain::convert_insn): Guard debug work with MAY_HAVE_DEBUG_BIND_INSNS. 2019-08-29 Richard Biener * config/i386/i386-features.c (general_scalar_chain::convert_insn): Guard debug work with MAY_HAVE_DEBUG_BIND_INSNS. From-SVN: r275031 --- gcc/ChangeLog | 5 +++++ gcc/config/i386/i386-features.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f94dae2..7a97562 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2019-08-29 Richard Biener + * config/i386/i386-features.c (general_scalar_chain::convert_insn): + Guard debug work with MAY_HAVE_DEBUG_BIND_INSNS. + +2019-08-29 Richard Biener + PR bootstrap/91580 * config/i386/i386-features.c (general_scalar_chain::convert_insn): Do not emit scalar copies for debug-insns, instead replace diff --git a/gcc/config/i386/i386-features.c b/gcc/config/i386/i386-features.c index f3c0eb6..03f33f8 100644 --- a/gcc/config/i386/i386-features.c +++ b/gcc/config/i386/i386-features.c @@ -893,7 +893,7 @@ general_scalar_chain::convert_insn (rtx_insn *insn) if (use) convert_reg (insn, DF_REF_REG (ref), *defs_map.get (regno_reg_rtx [DF_REF_REGNO (ref)])); - else + else if (MAY_HAVE_DEBUG_BIND_INSNS) { /* If we generated a scalar copy we can leave debug-insns as-is, if not, we have to adjust them. */ -- cgit v1.1 From ce189a6254e0fdcdf81d6131010b177104cb654e Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Thu, 29 Aug 2019 20:09:50 +0200 Subject: * ChangeLog: Fix wrong ChangeLog of my last entry. From-SVN: r275049 --- gcc/ChangeLog | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7a97562..e3f5d43 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -84,11 +84,8 @@ 2019-08-28 Uroš Bizjak - * config/i386/i386-features.c - (general_scalar_chain::compute_convert_gain): - Correct cost for double-word shifts. - (general_scalar_to_vector_candidate_p): Reject count operands - greater or equal to mode bitsize. + * config/i386/i386.c (ix86_register_move_cost): Do not + limit the cost of moves to/from XMM register to minimum 8. 2019-08-28 Martin Jambor -- cgit v1.1 From d1041899c2d24d0e001f8a48035881c7d4553aa2 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Thu, 29 Aug 2019 20:15:13 +0200 Subject: i386.c (inline_secondary_memory_needed): Return true for moves between SSE and non-general registers and between mask... * config/i386/i386.c (inline_secondary_memory_needed): Return true for moves between SSE and non-general registers and between mask and non-general registers. (ix86_register_move_cost): Remove stalled comment. From-SVN: r275050 --- gcc/ChangeLog | 7 +++++++ gcc/config/i386/i386.c | 30 +++++++++++++----------------- 2 files changed, 20 insertions(+), 17 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e3f5d43..f73e8be 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2019-08-29 Uroš Bizjak + + * config/i386/i386.c (inline_secondary_memory_needed): Return true + for moves between SSE and non-general registers and between + mask and non-general registers. + (ix86_register_move_cost): Remove stalled comment. + 2019-08-29 Richard Biener * config/i386/i386-features.c (general_scalar_chain::convert_insn): diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index d2d84eb..1c9c719 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -18306,32 +18306,36 @@ inline_secondary_memory_needed (machine_mode mode, reg_class_t class1, if (FLOAT_CLASS_P (class1) != FLOAT_CLASS_P (class2)) return true; - /* Between mask and general, we have moves no larger than word size. */ - if ((MASK_CLASS_P (class1) != MASK_CLASS_P (class2)) - && (GET_MODE_SIZE (mode) > UNITS_PER_WORD)) - return true; - /* ??? This is a lie. We do have moves between mmx/general, and for mmx/sse2. But by saying we need secondary memory we discourage the register allocator from using the mmx registers unless needed. */ if (MMX_CLASS_P (class1) != MMX_CLASS_P (class2)) return true; + /* Between mask and general, we have moves no larger than word size. */ + if (MASK_CLASS_P (class1) != MASK_CLASS_P (class2)) + { + if (!(INTEGER_CLASS_P (class1) || INTEGER_CLASS_P (class2)) + || GET_MODE_SIZE (mode) > UNITS_PER_WORD) + return true; + } + if (SSE_CLASS_P (class1) != SSE_CLASS_P (class2)) { /* SSE1 doesn't have any direct moves from other classes. */ if (!TARGET_SSE2) return true; + /* Between SSE and general, we have moves no larger than word size. */ + if (!(INTEGER_CLASS_P (class1) || INTEGER_CLASS_P (class2)) + || GET_MODE_SIZE (mode) > UNITS_PER_WORD) + return true; + /* If the target says that inter-unit moves are more expensive than moving through memory, then don't generate them. */ if ((SSE_CLASS_P (class1) && !TARGET_INTER_UNIT_MOVES_FROM_VEC) || (SSE_CLASS_P (class2) && !TARGET_INTER_UNIT_MOVES_TO_VEC)) return true; - - /* Between SSE and general, we have moves no larger than word size. */ - if (GET_MODE_SIZE (mode) > UNITS_PER_WORD) - return true; } return false; @@ -18608,15 +18612,7 @@ ix86_register_move_cost (machine_mode mode, reg_class_t class1_i, if (MMX_CLASS_P (class1) != MMX_CLASS_P (class2)) gcc_unreachable (); - /* Moves between SSE and integer units are expensive. */ if (SSE_CLASS_P (class1) != SSE_CLASS_P (class2)) - - /* ??? By keeping returned value relatively high, we limit the number - of moves between integer and SSE registers for all targets. - Additionally, high value prevents problem with x86_modes_tieable_p(), - where integer modes in SSE registers are not tieable - because of missing QImode and HImode moves to, from or between - MMX/SSE registers. */ return (SSE_CLASS_P (class1) ? ix86_cost->hard_register.sse_to_integer : ix86_cost->hard_register.integer_to_sse); -- cgit v1.1 From 2a3daf5b6101ff30f4bae3a83cf49e8f1e3d082b Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Thu, 29 Aug 2019 21:47:19 +0200 Subject: * config/i386/i386-features.c (general_scalar_chain::compute_convert_gain): Correct cost for double-word shifts. (general_scalar_to_vector_candidate_p): Reject count operands greater or equal to mode bitsize. From-SVN: r275055 --- gcc/ChangeLog | 8 ++++++++ gcc/config/i386/i386-features.c | 15 +++++++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f73e8be..e096497 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 2019-08-29 Uroš Bizjak + * config/i386/i386-features.c + (general_scalar_chain::compute_convert_gain): + Correct cost for double-word shifts. + (general_scalar_to_vector_candidate_p): Reject count operands + greater or equal to mode bitsize. + +2019-08-29 Uroš Bizjak + * config/i386/i386.c (inline_secondary_memory_needed): Return true for moves between SSE and non-general registers and between mask and non-general registers. diff --git a/gcc/config/i386/i386-features.c b/gcc/config/i386/i386-features.c index 03f33f8..454eeae 100644 --- a/gcc/config/i386/i386-features.c +++ b/gcc/config/i386/i386-features.c @@ -549,11 +549,18 @@ general_scalar_chain::compute_convert_gain () || GET_CODE (src) == ASHIFTRT || GET_CODE (src) == LSHIFTRT) { + if (m == 2) + { + if (INTVAL (XEXP (src, 1)) >= 32) + igain += ix86_cost->add; + else + igain += ix86_cost->shift_const; + } + + igain += ix86_cost->shift_const - ix86_cost->sse_op; + if (CONST_INT_P (XEXP (src, 0))) igain -= vector_const_cost (XEXP (src, 0)); - igain += m * ix86_cost->shift_const - ix86_cost->sse_op; - if (INTVAL (XEXP (src, 1)) >= 32) - igain -= COSTS_N_INSNS (1); } else if (GET_CODE (src) == PLUS || GET_CODE (src) == MINUS @@ -1359,7 +1366,7 @@ general_scalar_to_vector_candidate_p (rtx_insn *insn, enum machine_mode mode) case ASHIFT: case LSHIFTRT: if (!CONST_INT_P (XEXP (src, 1)) - || !IN_RANGE (INTVAL (XEXP (src, 1)), 0, 63)) + || !IN_RANGE (INTVAL (XEXP (src, 1)), 0, GET_MODE_BITSIZE (mode)-1)) return false; break; -- cgit v1.1 From ffb738a286543a47682c72a9410eae3f85872580 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Fri, 30 Aug 2019 00:16:23 +0000 Subject: Daily bump. From-SVN: r275059 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index b37e648..53042e9 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20190829 +20190830 -- cgit v1.1 From bb4d170d7b43be4b28ef20978ab2b453f6f2c55d Mon Sep 17 00:00:00 2001 From: Martin Jambor Date: Fri, 30 Aug 2019 10:08:42 +0200 Subject: [PR 91579] Avoid creating redundant PHI nodes in tail-call pass 2019-08-30 Martin Jambor tree-optimization/91579 * tree-tailcall.c (tailr_arg_needs_copy): New variable. (find_tail_calls): Allocate tailr_arg_needs_copy and set its bits as appropriate. (arg_needs_copy_p): Removed. (eliminate_tail_call): Test tailr_arg_needs_copy instead of calling arg_needs_copy_p. (tree_optimize_tail_calls_1): Likewise. Free tailr_arg_needs_copy. testsuite/ * gcc.dg/tree-ssa/pr91579.c: New test. From-SVN: r275062 --- gcc/ChangeLog | 11 ++++++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.dg/tree-ssa/pr91579.c | 22 +++++++++++++++ gcc/tree-tailcall.c | 48 +++++++++++++++++---------------- 4 files changed, 63 insertions(+), 23 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr91579.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e096497..57811a5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2019-08-30 Martin Jambor + + tree-optimization/91579 + * tree-tailcall.c (tailr_arg_needs_copy): New variable. + (find_tail_calls): Allocate tailr_arg_needs_copy and set its bits as + appropriate. + (arg_needs_copy_p): Removed. + (eliminate_tail_call): Test tailr_arg_needs_copy instead of calling + arg_needs_copy_p. + (tree_optimize_tail_calls_1): Likewise. Free tailr_arg_needs_copy. + 2019-08-29 Uroš Bizjak * config/i386/i386-features.c diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 02734ee..0c5ec53 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-08-30 Martin Jambor + + tree-optimization/91579 + * gcc.dg/tree-ssa/pr91579.c: New test. + 2019-08-29 Jakub Jelinek PR target/91560 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr91579.c b/gcc/testsuite/gcc.dg/tree-ssa/pr91579.c new file mode 100644 index 0000000..ee752be --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr91579.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-tailr1" } */ + +typedef long unsigned int size_t; +typedef int (*compare_t)(const void *, const void *); + +int partition (void *base, size_t nmemb, size_t size, compare_t cmp); + +void +my_qsort (void *base, size_t nmemb, size_t size, compare_t cmp) +{ + int pt; + if (nmemb > 1) + { + pt = partition (base, nmemb, size, cmp); + my_qsort (base, pt + 1, size, cmp); + my_qsort ((void*)((char*) base + (pt + 1) * size), + nmemb - pt - 1, size, cmp); + } +} + +/* { dg-final { scan-tree-dump-not "cmp\[^\r\n\]*PHI" "tailr1" } } */ diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c index a4b563e..4824a5e 100644 --- a/gcc/tree-tailcall.c +++ b/gcc/tree-tailcall.c @@ -126,6 +126,11 @@ struct tailcall accumulator. */ static tree m_acc, a_acc; +/* Bitmap with a bit for each function parameter which is set to true if we + have to copy the parameter for conversion of tail-recursive calls. */ + +static bitmap tailr_arg_needs_copy; + static bool optimize_tail_call (struct tailcall *, bool); static void eliminate_tail_call (struct tailcall *); @@ -727,6 +732,18 @@ find_tail_calls (basic_block bb, struct tailcall **ret) gimple_stmt_iterator mgsi = gsi_for_stmt (stmt); gsi_move_before (&mgsi, &gsi); } + if (!tailr_arg_needs_copy) + tailr_arg_needs_copy = BITMAP_ALLOC (NULL); + for (param = DECL_ARGUMENTS (current_function_decl), idx = 0; + param; + param = DECL_CHAIN (param), idx++) + { + tree ddef, arg = gimple_call_arg (call, idx); + if (is_gimple_reg (param) + && (ddef = ssa_default_def (cfun, param)) + && (arg != ddef)) + bitmap_set_bit (tailr_arg_needs_copy, idx); + } } nw = XNEW (struct tailcall); @@ -905,25 +922,6 @@ decrease_profile (basic_block bb, profile_count count) } } -/* Returns true if argument PARAM of the tail recursive call needs to be copied - when the call is eliminated. */ - -static bool -arg_needs_copy_p (tree param) -{ - tree def; - - if (!is_gimple_reg (param)) - return false; - - /* Parameters that are only defined but never used need not be copied. */ - def = ssa_default_def (cfun, param); - if (!def) - return false; - - return true; -} - /* Eliminates tail call described by T. TMP_VARS is a list of temporary variables used to copy the function arguments. */ @@ -1005,7 +1003,7 @@ eliminate_tail_call (struct tailcall *t) param; param = DECL_CHAIN (param), idx++) { - if (!arg_needs_copy_p (param)) + if (!bitmap_bit_p (tailr_arg_needs_copy, idx)) continue; arg = gimple_call_arg (stmt, idx); @@ -1139,10 +1137,11 @@ tree_optimize_tail_calls_1 (bool opt_tailcalls) split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun))); /* Copy the args if needed. */ - for (param = DECL_ARGUMENTS (current_function_decl); + unsigned idx; + for (param = DECL_ARGUMENTS (current_function_decl), idx = 0; param; - param = DECL_CHAIN (param)) - if (arg_needs_copy_p (param)) + param = DECL_CHAIN (param), idx++) + if (bitmap_bit_p (tailr_arg_needs_copy, idx)) { tree name = ssa_default_def (cfun, param); tree new_name = make_ssa_name (param, SSA_NAME_DEF_STMT (name)); @@ -1206,6 +1205,9 @@ tree_optimize_tail_calls_1 (bool opt_tailcalls) if (phis_constructed) mark_virtual_operands_for_renaming (cfun); + if (tailr_arg_needs_copy) + BITMAP_FREE (tailr_arg_needs_copy); + if (changed) return TODO_cleanup_cfg | TODO_update_ssa_only_virtuals; return 0; -- cgit v1.1 From 3eefaaa9fe42837b1debc49575b4a5405bf0af3b Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Fri, 30 Aug 2019 10:38:37 +0000 Subject: arm.md (unaligned_loaddi, [...]): New unspec insn patterns. 2019-08-30 Bernd Edlinger * config/arm/arm.md (unaligned_loaddi, unaligned_storedi): New unspec insn patterns. * config/arm/neon.md (unaligned_storev8qi): Likewise. * config/arm/arm.c (gen_cpymem_ldrd_strd): Use unaligned_loaddi and unaligned_storedi for 4-byte aligned memory. (arm_block_set_aligned_vect): Use unaligned_storev8qi for 4-byte aligned memory. From-SVN: r275063 --- gcc/ChangeLog | 10 ++++++++++ gcc/config/arm/arm.c | 19 +++++++++++++------ gcc/config/arm/arm.md | 22 ++++++++++++++++++++++ gcc/config/arm/neon.md | 10 ++++++++++ 4 files changed, 55 insertions(+), 6 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 57811a5..f902b55 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2019-08-30 Bernd Edlinger + + * config/arm/arm.md (unaligned_loaddi, + unaligned_storedi): New unspec insn patterns. + * config/arm/neon.md (unaligned_storev8qi): Likewise. + * config/arm/arm.c (gen_cpymem_ldrd_strd): Use unaligned_loaddi + and unaligned_storedi for 4-byte aligned memory. + (arm_block_set_aligned_vect): Use unaligned_storev8qi for + 4-byte aligned memory. + 2019-08-30 Martin Jambor tree-optimization/91579 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index a34cb74..eb8bf13 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -14578,8 +14578,10 @@ gen_cpymem_ldrd_strd (rtx *operands) low_reg = gen_lowpart (SImode, reg0); hi_reg = gen_highpart_mode (SImode, DImode, reg0); } - if (src_aligned) - emit_move_insn (reg0, src); + if (MEM_ALIGN (src) >= 2 * BITS_PER_WORD) + emit_move_insn (reg0, src); + else if (src_aligned) + emit_insn (gen_unaligned_loaddi (reg0, src)); else { emit_insn (gen_unaligned_loadsi (low_reg, src)); @@ -14587,8 +14589,10 @@ gen_cpymem_ldrd_strd (rtx *operands) emit_insn (gen_unaligned_loadsi (hi_reg, src)); } - if (dst_aligned) - emit_move_insn (dst, reg0); + if (MEM_ALIGN (dst) >= 2 * BITS_PER_WORD) + emit_move_insn (dst, reg0); + else if (dst_aligned) + emit_insn (gen_unaligned_storedi (dst, reg0)); else { emit_insn (gen_unaligned_storesi (dst, low_reg)); @@ -30197,7 +30201,10 @@ arm_block_set_aligned_vect (rtx dstbase, { addr = plus_constant (Pmode, dst, i); mem = adjust_automodify_address (dstbase, mode, addr, offset + i); - emit_move_insn (mem, reg); + if (MEM_ALIGN (mem) >= 2 * BITS_PER_WORD) + emit_move_insn (mem, reg); + else + emit_insn (gen_unaligned_storev8qi (mem, reg)); } /* Handle single word leftover by shifting 4 bytes back. We can @@ -30211,7 +30218,7 @@ arm_block_set_aligned_vect (rtx dstbase, if (align > UNITS_PER_WORD) set_mem_align (mem, BITS_PER_UNIT * UNITS_PER_WORD); - emit_move_insn (mem, reg); + emit_insn (gen_unaligned_storev8qi (mem, reg)); } /* Handle (0, 4), (4, 8) bytes leftover by shifting bytes back. We have to use unaligned access for this case. */ diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 0be7a01..e49e0d5 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -3963,6 +3963,17 @@ ; ARMv6+ unaligned load/store instructions (used for packed structure accesses). +(define_insn "unaligned_loaddi" + [(set (match_operand:DI 0 "s_register_operand" "=r") + (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] + UNSPEC_UNALIGNED_LOAD))] + "TARGET_32BIT && TARGET_LDRD" + "* + return output_move_double (operands, true, NULL); + " + [(set_attr "length" "8") + (set_attr "type" "load_8")]) + (define_insn "unaligned_loadsi" [(set (match_operand:SI 0 "s_register_operand" "=l,l,r") (unspec:SI [(match_operand:SI 1 "memory_operand" "m,Uw,m")] @@ -4008,6 +4019,17 @@ (set_attr "predicable_short_it" "no,yes,no") (set_attr "type" "load_byte")]) +(define_insn "unaligned_storedi" + [(set (match_operand:DI 0 "memory_operand" "=m") + (unspec:DI [(match_operand:DI 1 "s_register_operand" "r")] + UNSPEC_UNALIGNED_STORE))] + "TARGET_32BIT && TARGET_LDRD" + "* + return output_move_double (operands, true, NULL); + " + [(set_attr "length" "8") + (set_attr "type" "store_8")]) + (define_insn "unaligned_storesi" [(set (match_operand:SI 0 "memory_operand" "=m,Uw,m") (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,l,r")] diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md index a5aa8d6..6a0ee28 100644 --- a/gcc/config/arm/neon.md +++ b/gcc/config/arm/neon.md @@ -23,6 +23,16 @@ ;; type attribute definitions. (define_attr "vqh_mnem" "vadd,vmin,vmax" (const_string "vadd")) +(define_insn "unaligned_storev8qi" + [(set (match_operand:V8QI 0 "memory_operand" "=Un") + (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "w")] + UNSPEC_UNALIGNED_STORE))] + "TARGET_NEON" + "* + return output_move_neon (operands); + " + [(set_attr "type" "neon_store1_1reg")]) + (define_insn "*neon_mov" [(set (match_operand:VDX 0 "nonimmediate_operand" "=w,Un,w, w, w, ?r,?w,?r, ?Us,*r") -- cgit v1.1 From 815b53683243f09194a9a0af270cde060c2d58e7 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Fri, 30 Aug 2019 13:50:34 +0000 Subject: gigi.h (gigi_checking_assert): New macro. * gcc-interface/gigi.h (gigi_checking_assert): New macro. * gcc-interface/decl.c (gnat_to_gnu_entity) : Remove redundant test and adjust comments. Minor tweaks. * gcc-interface/trans.c (Call_to_gnu): Do not generate range checks, instead assert that the Do_Range_Check flag is not set. Adjust call to convert_with_check. (gnat_to_gnu): Likewise. (assoc_to_constructor): Likewise. (pos_to_constructor): Likewise. Remove GNAT_COMPONENT_TYPE parameter. (emit_range_check): Delete. (convert_with_check): Remove RANGE_P parameter and adjust. Do a single overflow check for modular types. From-SVN: r275174 --- gcc/ada/ChangeLog | 15 ++++ gcc/ada/gcc-interface/decl.c | 39 +++++----- gcc/ada/gcc-interface/gigi.h | 8 +- gcc/ada/gcc-interface/trans.c | 167 +++++++++++------------------------------- 4 files changed, 83 insertions(+), 146 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index b5c0b1f..923f474 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,18 @@ +2019-08-30 Eric Botcazou + + * gcc-interface/gigi.h (gigi_checking_assert): New macro. + * gcc-interface/decl.c (gnat_to_gnu_entity) : + Remove redundant test and adjust comments. Minor tweaks. + * gcc-interface/trans.c (Call_to_gnu): Do not generate range checks, + instead assert that the Do_Range_Check flag is not set. Adjust call + to convert_with_check. + (gnat_to_gnu): Likewise. + (assoc_to_constructor): Likewise. + (pos_to_constructor): Likewise. Remove GNAT_COMPONENT_TYPE parameter. + (emit_range_check): Delete. + (convert_with_check): Remove RANGE_P parameter and adjust. Do a single + overflow check for modular types. + 2019-08-23 Jakub Jelinek PR middle-end/91283 diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 81f621b..54ceb8d 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -447,13 +447,13 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) If we are not defining it, it must be a type or an entity that is defined elsewhere or externally, otherwise we should have defined it already. */ gcc_assert (definition - || type_annotate_only || is_type || kind == E_Discriminant || kind == E_Component || kind == E_Label || (kind == E_Constant && Present (Full_View (gnat_entity))) - || Is_Public (gnat_entity)); + || Is_Public (gnat_entity) + || type_annotate_only); /* Get the name of the entity and set up the line number and filename of the original definition for use in any decl we make. Make sure we do @@ -1758,34 +1758,29 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) case E_Modular_Integer_Type: { - /* For modular types, make the unsigned type of the proper number - of bits and then set up the modulus, if required. */ - tree gnu_modulus, gnu_high = NULL_TREE; - /* Packed Array Impl. Types are supposed to be subtypes only. */ gcc_assert (!Is_Packed_Array_Impl_Type (gnat_entity)); + /* For modular types, make the unsigned type of the proper number + of bits and then set up the modulus, if required. */ gnu_type = make_unsigned_type (esize); - /* Get the modulus in this type. If it overflows, assume it is because - it is equal to 2**Esize. Note that there is no overflow checking - done on unsigned type, so we detect the overflow by looking for - a modulus of zero, which is otherwise invalid. */ - gnu_modulus = UI_To_gnu (Modulus (gnat_entity), gnu_type); + /* Get the modulus in this type. If the modulus overflows, assume + that this is because it was equal to 2**Esize. Note that there + is no overflow checking done on unsigned types, so we detect the + overflow by looking for a modulus of zero, which is invalid. */ + tree gnu_modulus = UI_To_gnu (Modulus (gnat_entity), gnu_type); + /* If the modulus is not 2**Esize, then this also means that the upper + bound of the type, i.e. modulus - 1, is not maximal, so we create an + extra subtype to carry it and set the modulus on the base type. */ if (!integer_zerop (gnu_modulus)) { + TYPE_NAME (gnu_type) = create_concat_name (gnat_entity, "UMT"); TYPE_MODULAR_P (gnu_type) = 1; SET_TYPE_MODULUS (gnu_type, gnu_modulus); - gnu_high = fold_build2 (MINUS_EXPR, gnu_type, gnu_modulus, - build_int_cst (gnu_type, 1)); - } - - /* If the upper bound is not maximal, make an extra subtype. */ - if (gnu_high - && !tree_int_cst_equal (gnu_high, TYPE_MAX_VALUE (gnu_type))) - { - TYPE_NAME (gnu_type) = create_concat_name (gnat_entity, "UMT"); + tree gnu_high = fold_build2 (MINUS_EXPR, gnu_type, gnu_modulus, + build_int_cst (gnu_type, 1)); gnu_type = create_extra_subtype (gnu_type, TYPE_MIN_VALUE (gnu_type), gnu_high); @@ -2987,8 +2982,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) || Present (Record_Extension_Part (record_definition))) record_definition = Record_Extension_Part (record_definition); - gcc_assert (type_annotate_only - || Present (Parent_Subtype (gnat_entity))); + gcc_assert (Present (Parent_Subtype (gnat_entity)) + || type_annotate_only); } /* Make a node for the record. If we are not defining the record, diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h index f7415c7..21af83e 100644 --- a/gcc/ada/gcc-interface/gigi.h +++ b/gcc/ada/gcc-interface/gigi.h @@ -6,7 +6,7 @@ * * * C Header File * * * - * Copyright (C) 1992-2018, Free Software Foundation, Inc. * + * Copyright (C) 1992-2019, Free Software Foundation, Inc. * * * * GNAT is free software; you can redistribute it and/or modify it under * * terms of the GNU General Public License as published by the Free Soft- * @@ -1054,6 +1054,12 @@ extern void enumerate_modes (void (*f) (const char *, int, int, int, int, int, } #endif +/* Use gigi_checking_assert to test invariants in code generation mode. + It's effective only if the compiler is configured with more checking + than the release mode and can be disabled by means of -fchecking. */ +#define gigi_checking_assert(EXPR) \ + gcc_checking_assert ((EXPR) || type_annotate_only) + /* If EXP's type is a VECTOR_TYPE, return EXP converted to the associated TYPE_REPRESENTATIVE_ARRAY. */ diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 6c696b9..f21b9a8 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -231,14 +231,13 @@ static enum gimplify_status gnat_gimplify_stmt (tree *); static void elaborate_all_entities (Node_Id); static void process_freeze_entity (Node_Id); static void process_decls (List_Id, List_Id, Node_Id, bool, bool); -static tree emit_range_check (tree, Node_Id, Node_Id); static tree emit_check (tree, tree, int, Node_Id); static tree build_unary_op_trapv (enum tree_code, tree, tree, Node_Id); static tree build_binary_op_trapv (enum tree_code, tree, tree, tree, Node_Id); -static tree convert_with_check (Entity_Id, tree, bool, bool, bool, Node_Id); +static tree convert_with_check (Entity_Id, tree, bool, bool, Node_Id); static bool addressable_p (tree, tree); static tree assoc_to_constructor (Entity_Id, Node_Id, tree); -static tree pos_to_constructor (Node_Id, tree, Entity_Id); +static tree pos_to_constructor (Node_Id, tree); static void validate_unchecked_conversion (Node_Id); static Node_Id adjust_for_implicit_deref (Node_Id); static tree maybe_implicit_deref (tree); @@ -5407,11 +5406,7 @@ Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target, else gnu_actual = convert (gnu_actual_type, gnu_actual); - /* Make sure that the actual is in range of the formal's type. */ - if (Ekind (gnat_formal) != E_Out_Parameter - && Do_Range_Check (gnat_actual)) - gnu_actual - = emit_range_check (gnu_actual, gnat_formal_type, gnat_actual); + gigi_checking_assert (!Do_Range_Check (gnat_actual)); /* First see if the parameter is passed by reference. */ if (is_true_formal_parm && DECL_BY_REF_P (gnu_formal)) @@ -5655,12 +5650,15 @@ Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target, conversion node and not from the inner Expression. */ if (Nkind (gnat_actual) == N_Type_Conversion) { + const Node_Id gnat_expr = Expression (gnat_actual); + + gigi_checking_assert (!Do_Range_Check (gnat_expr)); + gnu_result - = convert_with_check - (Etype (Expression (gnat_actual)), gnu_result, - Do_Overflow_Check (gnat_actual), - Do_Range_Check (Expression (gnat_actual)), - Float_Truncate (gnat_actual), gnat_actual); + = convert_with_check (Etype (gnat_expr), gnu_result, + Do_Overflow_Check (gnat_actual), + Float_Truncate (gnat_actual), + gnat_actual); if (!Is_Composite_Type (Underlying_Type (Etype (gnat_formal)))) gnu_actual = convert (TREE_TYPE (gnu_result), gnu_actual); @@ -5676,10 +5674,7 @@ Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target, No_Truncation (gnat_actual)); else { - if (Do_Range_Check (gnat_actual)) - gnu_result - = emit_range_check (gnu_result, Etype (gnat_actual), - gnat_actual); + gigi_checking_assert (!Do_Range_Check (gnat_actual)); if (!(!TREE_CONSTANT (TYPE_SIZE (TREE_TYPE (gnu_actual))) && TREE_CONSTANT (TYPE_SIZE (TREE_TYPE (gnu_result))))) @@ -5736,11 +5731,7 @@ Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target, Node_Id gnat_parent = Parent (gnat_node); enum tree_code op_code; - /* If range check is needed, emit code to generate it. */ - if (Do_Range_Check (gnat_node)) - gnu_call - = emit_range_check (gnu_call, Etype (Name (gnat_parent)), - gnat_parent); + gigi_checking_assert (!Do_Range_Check (gnat_node)); /* ??? If the return type has variable size, then force the return slot optimization as we would not be able to create a temporary. @@ -7043,10 +7034,9 @@ gnat_to_gnu (Node_Id gnat_node) && (!type_annotate_only || Compile_Time_Known_Value (Expression (gnat_node)))) { + gigi_checking_assert (!Do_Range_Check (Expression (gnat_node))); + gnu_expr = gnat_to_gnu (Expression (gnat_node)); - if (Do_Range_Check (Expression (gnat_node))) - gnu_expr - = emit_range_check (gnu_expr, Etype (gnat_temp), gnat_node); if (type_annotate_only && TREE_CODE (gnu_expr) == ERROR_MARK) gnu_expr = NULL_TREE; @@ -7396,8 +7386,7 @@ gnat_to_gnu (Node_Id gnat_node) gnu_aggr_type); else if (TREE_CODE (gnu_aggr_type) == ARRAY_TYPE) gnu_result = pos_to_constructor (First (Expressions (gnat_node)), - gnu_aggr_type, - Component_Type (Etype (gnat_node))); + gnu_aggr_type); else if (TREE_CODE (gnu_aggr_type) == COMPLEX_TYPE) gnu_result = build_binary_op @@ -7436,10 +7425,11 @@ gnat_to_gnu (Node_Id gnat_node) if (kind == N_Qualified_Expression && Is_Tagged_Type (Etype (gnat_node))) used_types_insert (gnu_result_type); + gigi_checking_assert (!Do_Range_Check (Expression (gnat_node))); + gnu_result = convert_with_check (Etype (gnat_node), gnu_expr, Do_Overflow_Check (gnat_node), - Do_Range_Check (Expression (gnat_node)), kind == N_Type_Conversion && Float_Truncate (gnat_node), gnat_node); break; @@ -7749,10 +7739,9 @@ gnat_to_gnu (Node_Id gnat_node) gnat_temp = Expression (gnat_node); - /* The Expression operand can either be an N_Identifier or - Expanded_Name, which must represent a type, or a - N_Qualified_Expression, which contains both the object type and an - initial value for the object. */ + /* The expression can be either an N_Identifier or an Expanded_Name, + which must represent a type, or a N_Qualified_Expression, which + contains both the type and an initial value for the object. */ if (Nkind (gnat_temp) == N_Identifier || Nkind (gnat_temp) == N_Expanded_Name) gnu_type = gnat_to_gnu_type (Entity (gnat_temp)); @@ -7765,9 +7754,8 @@ gnat_to_gnu (Node_Id gnat_node) gnu_init = gnat_to_gnu (Expression (gnat_temp)); gnu_init = maybe_unconstrained_array (gnu_init); - if (Do_Range_Check (Expression (gnat_temp))) - gnu_init - = emit_range_check (gnu_init, gnat_desig_type, gnat_temp); + + gigi_checking_assert (!Do_Range_Check (Expression (gnat_temp))); if (Is_Elementary_Type (gnat_desig_type) || Is_Constrained (gnat_desig_type)) @@ -7873,10 +7861,7 @@ gnat_to_gnu (Node_Id gnat_node) else gnu_rhs = maybe_unconstrained_array (gnat_to_gnu (gnat_expr)); - /* If range check is needed, emit code to generate it. */ - if (Do_Range_Check (gnat_expr)) - gnu_rhs = emit_range_check (gnu_rhs, Etype (Name (gnat_node)), - gnat_node); + gigi_checking_assert (!Do_Range_Check (gnat_expr)); /* If an outer atomic access is required on the LHS, build the load- modify-store sequence. */ @@ -10086,58 +10071,6 @@ build_binary_op_trapv (enum tree_code code, tree gnu_type, tree left, return emit_check (check, gnu_expr, CE_Overflow_Check_Failed, gnat_node); } -/* Emit code for a range check. GNU_EXPR is the expression to be checked, - GNAT_RANGE_TYPE the gnat type or subtype containing the bounds against - which we have to check. GNAT_NODE is the GNAT node conveying the source - location for which the error should be signaled. */ - -static tree -emit_range_check (tree gnu_expr, Entity_Id gnat_range_type, Node_Id gnat_node) -{ - tree gnu_range_type = get_unpadded_type (gnat_range_type); - tree gnu_compare_type = get_base_type (TREE_TYPE (gnu_expr)); - - /* If GNU_EXPR has GNAT_RANGE_TYPE as its base type, no check is needed. - This can for example happen when translating 'Val or 'Value. */ - if (gnu_compare_type == gnu_range_type) - return gnu_expr; - - /* Range checks can only be applied to types with ranges. */ - gcc_assert (INTEGRAL_TYPE_P (gnu_range_type) - || SCALAR_FLOAT_TYPE_P (gnu_range_type)); - - /* If GNU_EXPR has an integral type that is narrower than GNU_RANGE_TYPE, - we can't do anything since we might be truncating the bounds. No - check is needed in this case. */ - if (INTEGRAL_TYPE_P (TREE_TYPE (gnu_expr)) - && (TYPE_PRECISION (gnu_compare_type) - < TYPE_PRECISION (get_base_type (gnu_range_type)))) - return gnu_expr; - - /* Checked expressions must be evaluated only once. */ - gnu_expr = gnat_protect_expr (gnu_expr); - - /* Note that the form of the check is - (not (expr >= lo)) or (not (expr <= hi)) - the reason for this slightly convoluted form is that NaNs - are not considered to be in range in the float case. */ - return emit_check - (build_binary_op (TRUTH_ORIF_EXPR, boolean_type_node, - invert_truthvalue - (build_binary_op (GE_EXPR, boolean_type_node, - convert (gnu_compare_type, gnu_expr), - convert (gnu_compare_type, - TYPE_MIN_VALUE - (gnu_range_type)))), - invert_truthvalue - (build_binary_op (LE_EXPR, boolean_type_node, - convert (gnu_compare_type, gnu_expr), - convert (gnu_compare_type, - TYPE_MAX_VALUE - (gnu_range_type))))), - gnu_expr, CE_Range_Check_Failed, gnat_node); -} - /* GNU_COND contains the condition corresponding to an index, overflow or range check of value GNU_EXPR. Build a COND_EXPR that returns GNU_EXPR if GNU_COND is false and raises a CONSTRAINT_ERROR if GNU_COND is true. @@ -10169,14 +10102,13 @@ emit_check (tree gnu_cond, tree gnu_expr, int reason, Node_Id gnat_node) } /* Return an expression that converts GNU_EXPR to GNAT_TYPE, doing overflow - checks if OVERFLOW_P is true and range checks if RANGE_P is true. - If TRUNCATE_P true, do a float-to-integer conversion with truncation, - otherwise round. GNAT_NODE is the GNAT node conveying the source location - for which the error should be signaled. */ + checks if OVERFLOW_P is true. If TRUNCATE_P is true, do a fp-to-integer + conversion with truncation, otherwise round. GNAT_NODE is the GNAT node + conveying the source location for which the error should be signaled. */ static tree convert_with_check (Entity_Id gnat_type, tree gnu_expr, bool overflow_p, - bool range_p, bool truncate_p, Node_Id gnat_node) + bool truncate_p, Node_Id gnat_node) { tree gnu_type = get_unpadded_type (gnat_type); tree gnu_base_type = get_base_type (gnu_type); @@ -10187,8 +10119,7 @@ convert_with_check (Entity_Id gnat_type, tree gnu_expr, bool overflow_p, /* If we are not doing any checks, the output is an integral type and the input is not a floating-point type, just do the conversion. This is required for packed array types and is simpler in all cases anyway. */ - if (!range_p - && !overflow_p + if (!overflow_p && INTEGRAL_TYPE_P (gnu_base_type) && !FLOAT_TYPE_P (gnu_in_base_type)) return convert (gnu_type, gnu_expr); @@ -10221,7 +10152,13 @@ convert_with_check (Entity_Id gnat_type, tree gnu_expr, bool overflow_p, tree gnu_in_lb = TYPE_MIN_VALUE (gnu_in_base_type); tree gnu_in_ub = TYPE_MAX_VALUE (gnu_in_base_type); tree gnu_out_lb = TYPE_MIN_VALUE (gnu_base_type); - tree gnu_out_ub = TYPE_MAX_VALUE (gnu_base_type); + tree gnu_out_ub + = (TREE_CODE (gnu_base_type) == INTEGER_TYPE + && TYPE_MODULAR_P (gnu_base_type)) + ? fold_build2 (MINUS_EXPR, gnu_base_type, + TYPE_MODULUS (gnu_base_type), + build_int_cst (gnu_base_type, 1)) + : TYPE_MAX_VALUE (gnu_base_type); /* Convert the lower bounds to signed types, so we're sure we're comparing them properly. Likewise, convert the upper bounds @@ -10346,14 +10283,6 @@ convert_with_check (Entity_Id gnat_type, tree gnu_expr, bool overflow_p, else gnu_result = convert (gnu_base_type, gnu_result); - /* Finally, do the range check if requested. Note that if the result type - is a modular type, the range check is actually an overflow check. */ - if (range_p - || (overflow_p - && TREE_CODE (gnu_base_type) == INTEGER_TYPE - && TYPE_MODULAR_P (gnu_base_type))) - gnu_result = emit_range_check (gnu_result, gnat_type, gnat_node); - return convert (gnu_type, gnu_result); } @@ -10682,7 +10611,8 @@ assoc_to_constructor (Entity_Id gnat_entity, Node_Id gnat_assoc, tree gnu_type) for (; Present (gnat_assoc); gnat_assoc = Next (gnat_assoc)) { - Node_Id gnat_field = First (Choices (gnat_assoc)); + const Node_Id gnat_field = First (Choices (gnat_assoc)); + const Node_Id gnat_expr = Expression (gnat_assoc); tree gnu_field = gnat_to_gnu_field_decl (Entity (gnat_field)); tree gnu_expr = gnat_to_gnu (Expression (gnat_assoc)); @@ -10702,11 +10632,9 @@ assoc_to_constructor (Entity_Id gnat_entity, Node_Id gnat_assoc, tree gnu_type) && Is_Unchecked_Union (gnat_entity)) continue; - /* Before assigning a value in an aggregate make sure range checks - are done if required. Then convert to the type of the field. */ - if (Do_Range_Check (Expression (gnat_assoc))) - gnu_expr = emit_range_check (gnu_expr, Etype (gnat_field), Empty); + gigi_checking_assert (!Do_Range_Check (gnat_expr)); + /* Convert to the type of the field. */ gnu_expr = convert (TREE_TYPE (gnu_field), gnu_expr); /* Add the field and expression to the list. */ @@ -10727,13 +10655,10 @@ assoc_to_constructor (Entity_Id gnat_entity, Node_Id gnat_assoc, tree gnu_type) /* Build a possibly nested constructor for array aggregates. GNAT_EXPR is the first element of an array aggregate. It may itself be an aggregate. - GNU_ARRAY_TYPE is the GCC type corresponding to the array aggregate. - GNAT_COMPONENT_TYPE is the type of the array component; it is needed - for range checking. */ + GNU_ARRAY_TYPE is the GCC type corresponding to the array aggregate. */ static tree -pos_to_constructor (Node_Id gnat_expr, tree gnu_array_type, - Entity_Id gnat_component_type) +pos_to_constructor (Node_Id gnat_expr, tree gnu_array_type) { tree gnu_index = TYPE_MIN_VALUE (TYPE_DOMAIN (gnu_array_type)); vec *gnu_expr_vec = NULL; @@ -10749,8 +10674,7 @@ pos_to_constructor (Node_Id gnat_expr, tree gnu_array_type, && TREE_CODE (TREE_TYPE (gnu_array_type)) == ARRAY_TYPE && TYPE_MULTI_ARRAY_P (TREE_TYPE (gnu_array_type))) gnu_expr = pos_to_constructor (First (Expressions (gnat_expr)), - TREE_TYPE (gnu_array_type), - gnat_component_type); + TREE_TYPE (gnu_array_type)); else { /* If the expression is a conversion to an unconstrained array type, @@ -10762,10 +10686,7 @@ pos_to_constructor (Node_Id gnat_expr, tree gnu_array_type, else gnu_expr = gnat_to_gnu (gnat_expr); - /* Before assigning the element to the array, make sure it is - in range. */ - if (Do_Range_Check (gnat_expr)) - gnu_expr = emit_range_check (gnu_expr, gnat_component_type, Empty); + gigi_checking_assert (!Do_Range_Check (gnat_expr)); } CONSTRUCTOR_APPEND_ELT (gnu_expr_vec, gnu_index, -- cgit v1.1 From 81e753d9c8a5930b5465676304df5d0d0c90294e Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Fri, 30 Aug 2019 13:55:59 +0000 Subject: * doc/invoke.texi (-Wvolatile): Use @code for volatile. From-SVN: r275178 --- gcc/ChangeLog | 4 ++++ gcc/doc/invoke.texi | 15 ++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f902b55..e9226d8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2019-08-30 Marek Polacek + + * doc/invoke.texi (-Wvolatile): Use @code for volatile. + 2019-08-30 Bernd Edlinger * config/arm/arm.md (unaligned_loaddi, diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index aa9886e..44a8801 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -3520,13 +3520,14 @@ a conversion function will never be called. @item -Wvolatile @r{(C++ and Objective-C++ only)} @opindex Wvolatile @opindex Wno-volatile -Warn about deprecated uses of the volatile qualifier. This includes postfix -and prefix @code{++} and @code{--} expressions of volatile-qualified types, -using simple assignments where the left operand is a volatile-qualified -non-class type for their value, compound assignments where the left operand -is a volatile-qualified non-class type, volatile-qualified function return -type, volatile-qualified parameter type, and structured bindings of a -volatile-qualified type. This usage was deprecated in C++20. +Warn about deprecated uses of the @code{volatile} qualifier. This includes +postfix and prefix @code{++} and @code{--} expressions of +@code{volatile}-qualified types, using simple assignments where the left +operand is a @code{volatile}-qualified non-class type for their value, +compound assignments where the left operand is a @code{volatile}-qualified +non-class type, @code{volatile}-qualified function return type, +@code{volatile}-qualified parameter type, and structured bindings of a +@code{volatile}-qualified type. This usage was deprecated in C++20. Enabled by default with @option{-std=c++2a}. @end table -- cgit v1.1 From da81cc570f27e78f71fed25d3c21a1d7d7f3ed66 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Fri, 30 Aug 2019 14:26:20 +0000 Subject: * gcc-interface/trans.c (Attribute_to_gnu) : Add assertion. From-SVN: r275187 --- gcc/ada/ChangeLog | 4 ++++ gcc/ada/gcc-interface/trans.c | 3 +++ 2 files changed, 7 insertions(+) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 923f474..af3db1d 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,5 +1,9 @@ 2019-08-30 Eric Botcazou + * gcc-interface/trans.c (Attribute_to_gnu) : Add assertion. + +2019-08-30 Eric Botcazou + * gcc-interface/gigi.h (gigi_checking_assert): New macro. * gcc-interface/decl.c (gnat_to_gnu_entity) : Remove redundant test and adjust comments. Minor tweaks. diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index f21b9a8..bd861f3 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -2351,6 +2351,9 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) gnu_type = TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (gnu_type))); } + /* The type must be frozen at this point. */ + gcc_assert (COMPLETE_TYPE_P (gnu_type)); + /* If we're looking for the size of a field, return the field size. */ if (TREE_CODE (gnu_prefix) == COMPONENT_REF) gnu_result = DECL_SIZE (TREE_OPERAND (gnu_prefix, 1)); -- cgit v1.1 From 37cf9302639271ff141d2ff7b4e29e60a401785c Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Fri, 30 Aug 2019 14:39:09 +0000 Subject: decl.c (annotate_value): Inline the call also if List_Representation_Info is greater than 3. * gcc-interface/decl.c (annotate_value) : Inline the call also if List_Representation_Info is greater than 3. From-SVN: r275188 --- gcc/ada/ChangeLog | 5 +++++ gcc/ada/gcc-interface/decl.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index af3db1d..5f004a9 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,5 +1,10 @@ 2019-08-30 Eric Botcazou + * gcc-interface/decl.c (annotate_value) : Inline the call + also if List_Representation_Info is greater than 3. + +2019-08-30 Eric Botcazou + * gcc-interface/trans.c (Attribute_to_gnu) : Add assertion. 2019-08-30 Eric Botcazou diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 54ceb8d..0695c2f 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -8398,7 +8398,7 @@ annotate_value (tree gnu_size) /* In regular mode, inline back only if symbolic annotation is requested in order to avoid memory explosion on big discriminated record types. But not in ASIS mode, as symbolic annotation is required for DDA. */ - if (List_Representation_Info == 3 || type_annotate_only) + if (List_Representation_Info >= 3 || type_annotate_only) { tree t = maybe_inline_call_in_expr (gnu_size); return t ? annotate_value (t) : No_Uint; -- cgit v1.1 From e5969b734db1e79e295372588ee2d5e6731d9713 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Fri, 30 Aug 2019 14:44:50 +0000 Subject: utils.c (build_template): Deal with parameters passed by pointer to component of multi-dimensional arrays. * gcc-interface/utils.c (build_template): Deal with parameters passed by pointer to component of multi-dimensional arrays. From-SVN: r275190 --- gcc/ada/ChangeLog | 5 +++++ gcc/ada/gcc-interface/utils.c | 29 ++++++++++++++++------------- 2 files changed, 21 insertions(+), 13 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 5f004a9..463a47a 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,5 +1,10 @@ 2019-08-30 Eric Botcazou + * gcc-interface/utils.c (build_template): Deal with parameters + passed by pointer to component of multi-dimensional arrays. + +2019-08-30 Eric Botcazou + * gcc-interface/decl.c (annotate_value) : Inline the call also if List_Representation_Info is greater than 3. diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index c6942fe..0202576 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -3953,27 +3953,30 @@ build_template (tree template_type, tree array_type, tree expr) && TYPE_HAS_ACTUAL_BOUNDS_P (array_type))) bound_list = TYPE_ACTUAL_BOUNDS (array_type); - /* First make the list for a CONSTRUCTOR for the template. Go down the - field list of the template instead of the type chain because this - array might be an Ada array of arrays and we can't tell where the - nested arrays stop being the underlying object. */ - - for (field = TYPE_FIELDS (template_type); field; - (bound_list - ? (bound_list = TREE_CHAIN (bound_list)) - : (array_type = TREE_TYPE (array_type))), + /* First make the list for a CONSTRUCTOR for the template. Go down + the field list of the template instead of the type chain because + this array might be an Ada array of array and we can't tell where + the nested array stop being the underlying object. */ + for (field = TYPE_FIELDS (template_type); + field; field = DECL_CHAIN (DECL_CHAIN (field))) { tree bounds, min, max; /* If we have a bound list, get the bounds from there. Likewise for an ARRAY_TYPE. Otherwise, if expr is a PARM_DECL with - DECL_BY_COMPONENT_PTR_P, use the bounds of the field in the template. - This will give us a maximum range. */ + DECL_BY_COMPONENT_PTR_P, use the bounds of the field in the + template, but this will only give us a maximum range. */ if (bound_list) - bounds = TREE_VALUE (bound_list); + { + bounds = TREE_VALUE (bound_list); + bound_list = TREE_CHAIN (bound_list); + } else if (TREE_CODE (array_type) == ARRAY_TYPE) - bounds = TYPE_INDEX_TYPE (TYPE_DOMAIN (array_type)); + { + bounds = TYPE_INDEX_TYPE (TYPE_DOMAIN (array_type)); + array_type = TREE_TYPE (array_type); + } else if (expr && TREE_CODE (expr) == PARM_DECL && DECL_BY_COMPONENT_PTR_P (expr)) bounds = TREE_TYPE (field); -- cgit v1.1 From 7f6dd1021e66c83a6f5e660d64fb055540bd6530 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Fri, 30 Aug 2019 14:48:16 +0000 Subject: trans.c (lvalue_required_p): Adjust GNU_TYPE in the recursive call. * gcc-interface/trans.c (lvalue_required_p) : Adjust GNU_TYPE in the recursive call. : Likewise. From-SVN: r275191 --- gcc/ada/ChangeLog | 6 ++++++ gcc/ada/gcc-interface/trans.c | 10 ++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 463a47a..71681b6 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,5 +1,11 @@ 2019-08-30 Eric Botcazou + * gcc-interface/trans.c (lvalue_required_p) : Adjust GNU_TYPE + in the recursive call. + : Likewise. + +2019-08-30 Eric Botcazou + * gcc-interface/utils.c (build_template): Deal with parameters passed by pointer to component of multi-dimensional arrays. diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index bd861f3..5579986 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -873,12 +873,14 @@ lvalue_required_p (Node_Id gnat_node, tree gnu_type, bool constant, if (Prefix (gnat_parent) != gnat_node) return 0; - return lvalue_required_p (gnat_parent, gnu_type, constant, - address_of_constant); + return lvalue_required_p (gnat_parent, + get_unpadded_type (Etype (gnat_parent)), + constant, address_of_constant); case N_Selected_Component: - return lvalue_required_p (gnat_parent, gnu_type, constant, - address_of_constant); + return lvalue_required_p (gnat_parent, + get_unpadded_type (Etype (gnat_parent)), + constant, address_of_constant); case N_Object_Renaming_Declaration: /* We need to preserve addresses through a renaming. */ -- cgit v1.1 From c85dbadc061f7c7f3575e335976150370d8652be Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Fri, 30 Aug 2019 09:10:14 -0600 Subject: * gcc.target/mips/r10k-cache-barrier-9.c: Suppress warnings. From-SVN: r275195 --- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.target/mips/r10k-cache-barrier-9.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0c5ec53..5044002 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-08-30 Jeff Law + + * gcc.target/mips/r10k-cache-barrier-9.c: Suppress warnings. + 2019-08-30 Martin Jambor tree-optimization/91579 diff --git a/gcc/testsuite/gcc.target/mips/r10k-cache-barrier-9.c b/gcc/testsuite/gcc.target/mips/r10k-cache-barrier-9.c index 2f83968..2516b66 100644 --- a/gcc/testsuite/gcc.target/mips/r10k-cache-barrier-9.c +++ b/gcc/testsuite/gcc.target/mips/r10k-cache-barrier-9.c @@ -1,4 +1,4 @@ -/* { dg-options "-mr10k-cache-barrier=store -G8" } */ +/* { dg-options "-mr10k-cache-barrier=store -G8 -w" } */ /* Test that out-of-range stores to components of static objects are protected by a cache barrier. */ -- cgit v1.1 From 0c2837b5c408f8fd2b023a7bf00be9abd1e28a28 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Fri, 30 Aug 2019 15:12:20 +0000 Subject: gigi.h (aggregate_type_contains_array_p): Declare. * gcc-interface/gigi.h (aggregate_type_contains_array_p): Declare. * gcc-interface/decl.c (gnat_to_gnu_entity) : For an extension, test Has_Record_Rep_Clause instead of Has_Specified_Layout. (adjust_packed): Return 0 if the type of the field is an aggregate type that contains (or is) a self-referential array. (type_has_variable_size): Delete. * gcc-interface/utils.c (inish_record_type): Constify a variable. (aggregate_type_contains_array_p): Add parameter SELF_REFERENTIAL. : Pass it in the recursive call. : If it is true, return true only if the array type is self-referential. (create_field_decl): Streamline the setting of the alignment on the field. Pass false to aggregate_type_contains_array_p. From-SVN: r275196 --- gcc/ada/ChangeLog | 16 ++++++++++ gcc/ada/gcc-interface/decl.c | 43 +++++++------------------ gcc/ada/gcc-interface/gigi.h | 5 +++ gcc/ada/gcc-interface/utils.c | 69 ++++++++++++++++++++++------------------ gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gnat.dg/pack24.adb | 38 ++++++++++++++++++++++ 6 files changed, 112 insertions(+), 63 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/pack24.adb (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 71681b6..636eb7c 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,5 +1,21 @@ 2019-08-30 Eric Botcazou + * gcc-interface/gigi.h (aggregate_type_contains_array_p): Declare. + * gcc-interface/decl.c (gnat_to_gnu_entity) : For an + extension, test Has_Record_Rep_Clause instead of Has_Specified_Layout. + (adjust_packed): Return 0 if the type of the field is an aggregate + type that contains (or is) a self-referential array. + (type_has_variable_size): Delete. + * gcc-interface/utils.c (inish_record_type): Constify a variable. + (aggregate_type_contains_array_p): Add parameter SELF_REFERENTIAL. + : Pass it in the recursive call. + : If it is true, return true only if the array type is + self-referential. + (create_field_decl): Streamline the setting of the alignment on the + field. Pass false to aggregate_type_contains_array_p. + +2019-08-30 Eric Botcazou + * gcc-interface/trans.c (lvalue_required_p) : Adjust GNU_TYPE in the recursive call. : Likewise. diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 0695c2f..5fce2ad 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -202,7 +202,6 @@ static void prepend_one_attribute_pragma (struct attrib **, Node_Id); static void prepend_attributes (struct attrib **, Entity_Id); static tree elaborate_expression (Node_Id, Entity_Id, const char *, bool, bool, bool); -static bool type_has_variable_size (tree); static tree elaborate_expression_1 (tree, Entity_Id, const char *, bool, bool); static tree elaborate_expression_2 (tree, Entity_Id, const char *, bool, bool, unsigned int); @@ -2953,10 +2952,13 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) : 0; const bool has_align = Known_Alignment (gnat_entity); const bool has_discr = Has_Discriminants (gnat_entity); - const bool has_rep = Has_Specified_Layout (gnat_entity); const bool is_extension = (Is_Tagged_Type (gnat_entity) && Nkind (record_definition) == N_Derived_Type_Definition); + const bool has_rep + = is_extension + ? Has_Record_Rep_Clause (gnat_entity) + : Has_Specified_Layout (gnat_entity); const bool is_unchecked_union = Is_Unchecked_Union (gnat_entity); bool all_rep = has_rep; @@ -6865,11 +6867,13 @@ choices_to_gnu (tree gnu_operand, Node_Id gnat_choices) static int adjust_packed (tree field_type, tree record_type, int packed) { - /* If the field contains an item of variable size, we cannot pack it - because we cannot create temporaries of non-fixed size in case - we need to take the address of the field. See addressable_p and - the notes on the addressability issues for further details. */ - if (type_has_variable_size (field_type)) + /* If the field contains an array with self-referential size, we'd better + not pack it because this would misalign it and, therefore, cause large + temporaries to be created in case we need to take the address of the + field. See addressable_p and the notes on the addressability issues + for further details. */ + if (AGGREGATE_TYPE_P (field_type) + && aggregate_type_contains_array_p (field_type, true)) return 0; /* In the other cases, we can honor the packing. */ @@ -7274,31 +7278,6 @@ components_need_strict_alignment (Node_Id component_list) return false; } -/* Return true if TYPE is a type with variable size or a padding type with a - field of variable size or a record that has a field with such a type. */ - -static bool -type_has_variable_size (tree type) -{ - tree field; - - if (!TREE_CONSTANT (TYPE_SIZE (type))) - return true; - - if (TYPE_IS_PADDING_P (type) - && !TREE_CONSTANT (DECL_SIZE (TYPE_FIELDS (type)))) - return true; - - if (!RECORD_OR_UNION_TYPE_P (type)) - return false; - - for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) - if (type_has_variable_size (TREE_TYPE (field))) - return true; - - return false; -} - /* Return true if FIELD is an artificial field. */ static bool diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h index 21af83e..edfcbd5 100644 --- a/gcc/ada/gcc-interface/gigi.h +++ b/gcc/ada/gcc-interface/gigi.h @@ -835,6 +835,11 @@ extern tree get_base_type (tree type); in bits. If we don't know anything about the alignment, return 0. */ extern unsigned int known_alignment (tree exp); +/* Return true if TYPE, an aggregate type, contains (or is) an array. + If SELF_REFERENTIAL is true, then an additional requirement on the + array is that it be self-referential. */ +extern bool aggregate_type_contains_array_p (tree type, bool self_referential); + /* Return true if VALUE is a multiple of FACTOR. FACTOR must be a power of 2. */ extern bool value_factor_p (tree value, unsigned HOST_WIDE_INT factor); diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index 0202576..8a38b34 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -1948,7 +1948,7 @@ finish_record_type (tree record_type, tree field_list, int rep_level, if (DECL_BIT_FIELD (field) && operand_equal_p (this_size, TYPE_SIZE (type), 0)) { - unsigned int align = TYPE_ALIGN (type); + const unsigned int align = TYPE_ALIGN (type); /* In the general case, type alignment is required. */ if (value_factor_p (pos, align)) @@ -2764,10 +2764,12 @@ create_var_decl (tree name, tree asm_name, tree type, tree init, return var_decl; } -/* Return true if TYPE, an aggregate type, contains (or is) an array. */ +/* Return true if TYPE, an aggregate type, contains (or is) an array. + If SELF_REFERENTIAL is true, then an additional requirement on the + array is that it be self-referential. */ -static bool -aggregate_type_contains_array_p (tree type) +bool +aggregate_type_contains_array_p (tree type, bool self_referential) { switch (TREE_CODE (type)) { @@ -2778,13 +2780,14 @@ aggregate_type_contains_array_p (tree type) tree field; for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) if (AGGREGATE_TYPE_P (TREE_TYPE (field)) - && aggregate_type_contains_array_p (TREE_TYPE (field))) + && aggregate_type_contains_array_p (TREE_TYPE (field), + self_referential)) return true; return false; } case ARRAY_TYPE: - return true; + return self_referential ? type_contains_placeholder_p (type) : true; default: gcc_unreachable (); @@ -2808,18 +2811,6 @@ create_field_decl (tree name, tree type, tree record_type, tree size, tree pos, DECL_CONTEXT (field_decl) = record_type; TREE_READONLY (field_decl) = TYPE_READONLY (type); - /* If FIELD_TYPE is BLKmode, we must ensure this is aligned to at least a - byte boundary since GCC cannot handle less-aligned BLKmode bitfields. - Likewise for an aggregate without specified position that contains an - array, because in this case slices of variable length of this array - must be handled by GCC and variable-sized objects need to be aligned - to at least a byte boundary. */ - if (packed && (TYPE_MODE (type) == BLKmode - || (!pos - && AGGREGATE_TYPE_P (type) - && aggregate_type_contains_array_p (type)))) - SET_DECL_ALIGN (field_decl, BITS_PER_UNIT); - /* If a size is specified, use it. Otherwise, if the record type is packed compute a size to use, which may differ from the object's natural size. We always set a size in this case to trigger the checks for bitfield @@ -2872,23 +2863,39 @@ create_field_decl (tree name, tree type, tree record_type, tree size, tree pos, DECL_PACKED (field_decl) = pos ? DECL_BIT_FIELD (field_decl) : packed; + /* If FIELD_TYPE is BLKmode, we must ensure this is aligned to at least a + byte boundary since GCC cannot handle less-aligned BLKmode bitfields. + Likewise for an aggregate without specified position that contains an + array, because in this case slices of variable length of this array + must be handled by GCC and variable-sized objects need to be aligned + to at least a byte boundary. */ + if (packed && (TYPE_MODE (type) == BLKmode + || (!pos + && AGGREGATE_TYPE_P (type) + && aggregate_type_contains_array_p (type, false)))) + SET_DECL_ALIGN (field_decl, BITS_PER_UNIT); + /* Bump the alignment if need be, either for bitfield/packing purposes or - to satisfy the type requirements if no such consideration applies. When + to satisfy the type requirements if no such considerations apply. When we get the alignment from the type, indicate if this is from an explicit user request, which prevents stor-layout from lowering it later on. */ - { - unsigned int bit_align - = (DECL_BIT_FIELD (field_decl) ? 1 - : packed && TYPE_MODE (type) != BLKmode ? BITS_PER_UNIT : 0); + else + { + const unsigned int field_align + = DECL_BIT_FIELD (field_decl) + ? 1 + : packed + ? BITS_PER_UNIT + : 0; - if (bit_align > DECL_ALIGN (field_decl)) - SET_DECL_ALIGN (field_decl, bit_align); - else if (!bit_align && TYPE_ALIGN (type) > DECL_ALIGN (field_decl)) - { - SET_DECL_ALIGN (field_decl, TYPE_ALIGN (type)); - DECL_USER_ALIGN (field_decl) = TYPE_USER_ALIGN (type); - } - } + if (field_align > DECL_ALIGN (field_decl)) + SET_DECL_ALIGN (field_decl, field_align); + else if (!field_align && TYPE_ALIGN (type) > DECL_ALIGN (field_decl)) + { + SET_DECL_ALIGN (field_decl, TYPE_ALIGN (type)); + DECL_USER_ALIGN (field_decl) = TYPE_USER_ALIGN (type); + } + } if (pos) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5044002..715c417 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-08-30 Eric Botcazou + + * gnat.dg/pack24.adb: New test. + 2019-08-30 Jeff Law * gcc.target/mips/r10k-cache-barrier-9.c: Suppress warnings. diff --git a/gcc/testsuite/gnat.dg/pack24.adb b/gcc/testsuite/gnat.dg/pack24.adb new file mode 100644 index 0000000..90d6134 --- /dev/null +++ b/gcc/testsuite/gnat.dg/pack24.adb @@ -0,0 +1,38 @@ +-- { dg-do run } + +with Interfaces; + +procedure Pack24 is + + type Enum_1 is (Lit_1); + for Enum_1'SIZE use 16; + + type Rec1(D1 : Enum_1 := Lit_1) is + record + case D1 is + when Lit_1 => + F1 : Interfaces.Unsigned_16; + when others => + Null; + end case; + end record; + pragma Pack(Rec1); + + type Rec2 is + record + F1 : Interfaces.Unsigned_16; + F2 : Rec1; + end record; + pragma Pack(Rec2); + + type Rec3 is record + F1 : Interfaces.Unsigned_8; + F2 : Rec2; + end record; + pragma Pack(Rec3); + +begin + if Rec3'Size /= 56 then + raise Program_Error; + end if; +end; -- cgit v1.1 From 5e017b1e25655f256a130419b427811bb1016b43 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Fri, 30 Aug 2019 15:15:40 +0000 Subject: trans.c (gnat_to_gnu): Do not set the location on an expression used for a tag. * gcc-interface/trans.c (gnat_to_gnu): Do not set the location on an expression used for a tag. From-SVN: r275197 --- gcc/ada/ChangeLog | 5 +++++ gcc/ada/gcc-interface/trans.c | 10 ++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 636eb7c..f4c510d 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,5 +1,10 @@ 2019-08-30 Eric Botcazou + * gcc-interface/trans.c (gnat_to_gnu): Do not set the location on an + expression used for a tag. + +2019-08-30 Eric Botcazou + * gcc-interface/gigi.h (aggregate_type_contains_array_p): Declare. * gcc-interface/decl.c (gnat_to_gnu_entity) : For an extension, test Has_Record_Rep_Clause instead of Has_Specified_Layout. diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 5579986..e7064c6 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -8727,10 +8727,16 @@ gnat_to_gnu (Node_Id gnat_node) set_gnu_expr_location_from_node (gnu_result, gnat_node); } - /* Set the location information on the result if it's not a simple name. + /* Set the location information on the result if it's not a simple name + or something that contains a simple name, for example a tag, because + we don"t want all the references to get the location of the first use. Note that we may have no result if we tried to build a CALL_EXPR node to a procedure with no side-effects and optimization is enabled. */ - else if (kind != N_Identifier && gnu_result && EXPR_P (gnu_result)) + else if (kind != N_Identifier + && !(kind == N_Selected_Component + && Chars (Selector_Name (gnat_node)) == Name_uTag) + && gnu_result + && EXPR_P (gnu_result)) set_gnu_expr_location_from_node (gnu_result, gnat_node); /* If we're supposed to return something of void_type, it means we have -- cgit v1.1 From 1edbeb153d802dbac524d7177d72d173278183f1 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Fri, 30 Aug 2019 15:22:34 +0000 Subject: ada-tree.h (DECL_FORCED_BY_REF_P): New macro. * gcc-interface/ada-tree.h (DECL_FORCED_BY_REF_P): New macro. * gcc-interface/decl.c (gnat_to_gnu_param): Set it on parameters whose mechanism was forced to by-reference. * gcc-interface/trans.c (Call_to_gnu): Do not issue a warning about a misaligned actual parameter if it is based on a CONSTRUCTOR. Remove obsolete warning for users of Starlet. Issue a warning if a temporary is make around the call for a parameter with DECL_FORCED_BY_REF_P set. (addressable_p): Return true for REAL_CST and ADDR_EXPR. From-SVN: r275198 --- gcc/ada/ChangeLog | 11 +++++++++++ gcc/ada/gcc-interface/ada-tree.h | 3 +++ gcc/ada/gcc-interface/decl.c | 8 +++++++- gcc/ada/gcc-interface/trans.c | 30 +++++++++++------------------- 4 files changed, 32 insertions(+), 20 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index f4c510d..bb43565 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,5 +1,16 @@ 2019-08-30 Eric Botcazou + * gcc-interface/ada-tree.h (DECL_FORCED_BY_REF_P): New macro. + * gcc-interface/decl.c (gnat_to_gnu_param): Set it on parameters + whose mechanism was forced to by-reference. + * gcc-interface/trans.c (Call_to_gnu): Do not issue a warning about a + misaligned actual parameter if it is based on a CONSTRUCTOR. Remove + obsolete warning for users of Starlet. Issue a warning if a temporary + is make around the call for a parameter with DECL_FORCED_BY_REF_P set. + (addressable_p): Return true for REAL_CST and ADDR_EXPR. + +2019-08-30 Eric Botcazou + * gcc-interface/trans.c (gnat_to_gnu): Do not set the location on an expression used for a tag. diff --git a/gcc/ada/gcc-interface/ada-tree.h b/gcc/ada/gcc-interface/ada-tree.h index 2029b7c..acea5d1 100644 --- a/gcc/ada/gcc-interface/ada-tree.h +++ b/gcc/ada/gcc-interface/ada-tree.h @@ -482,6 +482,9 @@ do { \ value of a function call or 'reference to a function call. */ #define DECL_RETURN_VALUE_P(NODE) DECL_LANG_FLAG_5 (VAR_DECL_CHECK (NODE)) +/* Nonzero in a PARM_DECL if its mechanism was forced to by-reference. */ +#define DECL_FORCED_BY_REF_P(NODE) DECL_LANG_FLAG_5 (PARM_DECL_CHECK (NODE)) + /* In a FIELD_DECL corresponding to a discriminant, contains the discriminant number. */ #define DECL_DISCRIMINANT_NUMBER(NODE) DECL_INITIAL (FIELD_DECL_CHECK (NODE)) diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 5fce2ad..85a5e76 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -5208,6 +5208,7 @@ gnat_to_gnu_param (Entity_Id gnat_param, tree gnu_param_type, bool first, bool ro_param = in_param && !Address_Taken (gnat_param); bool by_return = false, by_component_ptr = false; bool by_ref = false; + bool forced_by_ref = false; bool restricted_aliasing_p = false; location_t saved_location = input_location; tree gnu_param; @@ -5235,7 +5236,11 @@ gnat_to_gnu_param (Entity_Id gnat_param, tree gnu_param_type, bool first, /* Or else, see if a Mechanism was supplied that forced this parameter to be passed one way or another. */ else if (mech == Default || mech == By_Copy || mech == By_Reference) - ; + forced_by_ref + = (mech == By_Reference + && !foreign + && !TYPE_IS_BY_REFERENCE_P (gnu_param_type) + && !Is_Aliased (gnat_param)); /* Positive mechanism means by copy for sufficiently small parameters. */ else if (mech > 0) @@ -5368,6 +5373,7 @@ gnat_to_gnu_param (Entity_Id gnat_param, tree gnu_param_type, bool first, gnu_param = create_param_decl (gnu_param_name, gnu_param_type); TREE_READONLY (gnu_param) = ro_param || by_ref || by_component_ptr; DECL_BY_REF_P (gnu_param) = by_ref; + DECL_FORCED_BY_REF_P (gnu_param) = forced_by_ref; DECL_BY_COMPONENT_PTR_P (gnu_param) = by_component_ptr; DECL_POINTS_TO_READONLY_P (gnu_param) = (ro_param && (by_ref || by_component_ptr)); diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index e7064c6..4d2fa93 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -5257,30 +5257,20 @@ Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target, /* Do not issue warnings for CONSTRUCTORs since this is not a copy but sort of an instantiation for them. */ - if (TREE_CODE (gnu_name) == CONSTRUCTOR) + if (TREE_CODE (remove_conversions (gnu_name, true)) == CONSTRUCTOR) ; - /* If the type is passed by reference, a copy is not allowed. */ - else if (TYPE_IS_BY_REFERENCE_P (gnu_formal_type)) + /* If the formal is passed by reference, a copy is not allowed. */ + else if (TYPE_IS_BY_REFERENCE_P (gnu_formal_type) + || Is_Aliased (gnat_formal)) post_error ("misaligned actual cannot be passed by reference", gnat_actual); - /* For users of Starlet we issue a warning because the interface - apparently assumes that by-ref parameters outlive the procedure - invocation. The code still will not work as intended, but we - cannot do much better since low-level parts of the back-end - would allocate temporaries at will because of the misalignment - if we did not do so here. */ - else if (Is_Valued_Procedure (Entity (Name (gnat_node)))) - { - post_error - ("?possible violation of implicit assumption", gnat_actual); - post_error_ne - ("?made by pragma Import_Valued_Procedure on &", gnat_actual, - Entity (Name (gnat_node))); - post_error_ne ("?because of misalignment of &", gnat_actual, - gnat_formal); - } + /* If the mechanism was forced to by-ref, a copy is not allowed but + we issue only a warning because this case is not strict Ada. */ + else if (DECL_FORCED_BY_REF_P (gnu_formal)) + post_error ("misaligned actual cannot be passed by reference??", + gnat_actual); /* If the actual type of the object is already the nominal type, we have nothing to do, except if the size is self-referential @@ -10394,6 +10384,7 @@ addressable_p (tree gnu_expr, tree gnu_type) case STRING_CST: case INTEGER_CST: + case REAL_CST: /* Taking the address yields a pointer to the constant pool. */ return true; @@ -10403,6 +10394,7 @@ addressable_p (tree gnu_expr, tree gnu_type) return TREE_STATIC (gnu_expr) ? true : false; case NULL_EXPR: + case ADDR_EXPR: case SAVE_EXPR: case CALL_EXPR: case PLUS_EXPR: -- cgit v1.1 From 875bdbe2f6d2d54f0ccefd27cea3a533fef834eb Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Fri, 30 Aug 2019 15:32:51 +0000 Subject: decl.c (maybe_saturate_size): New function. * gcc-interface/decl.c (maybe_saturate_size): New function. (gnat_to_gnu_entity): Invoke it on the Esize of types before sending it for back-annotations. * gcc-interface/trans.c: Fix typo. From-SVN: r275200 --- gcc/ada/ChangeLog | 7 +++++++ gcc/ada/gcc-interface/decl.c | 25 ++++++++++++++++++++----- gcc/ada/gcc-interface/trans.c | 2 +- 3 files changed, 28 insertions(+), 6 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index bb43565..410828e 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,5 +1,12 @@ 2019-08-30 Eric Botcazou + * gcc-interface/decl.c (maybe_saturate_size): New function. + (gnat_to_gnu_entity): Invoke it on the Esize of types before sending + it for back-annotations. + * gcc-interface/trans.c: Fix typo. + +2019-08-30 Eric Botcazou + * gcc-interface/ada-tree.h (DECL_FORCED_BY_REF_P): New macro. * gcc-interface/decl.c (gnat_to_gnu_param): Set it on parameters whose mechanism was forced to by-reference. diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 85a5e76..d1082ee 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -232,6 +232,7 @@ static tree build_position_list (tree, bool, tree, tree, unsigned int, tree); static vec build_subst_list (Entity_Id, Entity_Id, bool); static vec build_variant_list (tree, vec, vec); +static tree maybe_saturate_size (tree); static tree validate_size (Uint, tree, Entity_Id, enum tree_code, bool, bool); static void set_rm_size (Uint, tree, Entity_Id); static unsigned int validate_alignment (Uint, Entity_Id, unsigned int); @@ -4327,9 +4328,10 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) { tree gnu_size = TYPE_SIZE (gnu_type); - /* If the size is self-referential, annotate the maximum value. */ + /* If the size is self-referential, annotate the maximum value + after saturating it, if need be, to avoid a No_Uint value. */ if (CONTAINS_PLACEHOLDER_P (gnu_size)) - gnu_size = max_size (gnu_size, true); + gnu_size = maybe_saturate_size (max_size (gnu_size, true)); /* If we are just annotating types and the type is tagged, the tag and the parent components are not generated by the front-end so @@ -4365,7 +4367,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) gnu_size = size_binop (PLUS_EXPR, gnu_size, offset); } - gnu_size = round_up (gnu_size, align); + gnu_size = maybe_saturate_size (round_up (gnu_size, align)); Set_Esize (gnat_entity, annotate_value (gnu_size)); /* Tagged types are Strict_Alignment so RM_Size = Esize. */ @@ -8723,6 +8725,19 @@ build_variant_list (tree qual_union_type, vec subst_list, return gnu_list; } +/* If SIZE has overflowed, return the maximum valid size, which is the upper + bound of the signed sizetype in bits; otherwise return SIZE unmodified. */ + +static tree +maybe_saturate_size (tree size) +{ + if (TREE_CODE (size) == INTEGER_CST && TREE_OVERFLOW (size)) + size = size_binop (MULT_EXPR, + fold_convert (bitsizetype, TYPE_MAX_VALUE (ssizetype)), + build_int_cst (bitsizetype, BITS_PER_UNIT)); + return size; +} + /* UINT_SIZE is a Uint giving the specified size for an object of GNU_TYPE corresponding to GNAT_OBJECT. If the size is valid, return an INTEGER_CST corresponding to its value. Otherwise, return NULL_TREE. KIND is set to @@ -10137,7 +10152,7 @@ concat_name (tree gnu_name, const char *suffix) return get_identifier_with_length (new_name, len); } -/* Initialize data structures of the decl.c module. */ +/* Initialize the data structures of the decl.c module. */ void init_gnat_decl (void) @@ -10149,7 +10164,7 @@ init_gnat_decl (void) dummy_to_subprog_map = hash_table::create_ggc (512); } -/* Destroy data structures of the decl.c module. */ +/* Destroy the data structures of the decl.c module. */ void destroy_gnat_decl (void) diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 4d2fa93..fe02dc4 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -8790,7 +8790,7 @@ gnat_to_gnu (Node_Id gnat_node) 5. If this is a reference to an unconstrained array which is used as the prefix of an attribute reference that requires an lvalue, return the - result unmodified because we want return the original bounds. + result unmodified because we want to return the original bounds. 6. Finally, if the type of the result is already correct. */ -- cgit v1.1 From 5d69df7e9292522d00100b79f84a982359ed8142 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Fri, 30 Aug 2019 17:42:57 +0000 Subject: PR middle-end/91584 - Bogus warning from -Warray-bounds during string assignment gcc/ChangeLog: PR middle-end/91584 * tree-vrp.c (vrp_prop::check_mem_ref): Normalize type domain bounds before using them to validate MEM_REF offset. gcc/testsuite/ChangeLog: * gfortran.dg/char_array_constructor_4.f90: New test. From-SVN: r275210 --- gcc/ChangeLog | 6 ++++++ gcc/testsuite/ChangeLog | 5 +++++ .../gfortran.dg/char_array_constructor_4.f90 | 13 ++++++++++++ gcc/tree-vrp.c | 23 +++++++--------------- 4 files changed, 31 insertions(+), 16 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/char_array_constructor_4.f90 (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e9226d8..45dd3a2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-08-30 Martin Sebor + + PR middle-end/91584 + * tree-vrp.c (vrp_prop::check_mem_ref): Normalize type domain bounds + before using them to validate MEM_REF offset. + 2019-08-30 Marek Polacek * doc/invoke.texi (-Wvolatile): Use @code for volatile. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 715c417..420ddd4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-08-30 Martin Sebor + + PR middle-end/91584 + * gfortran.dg/char_array_constructor_4.f90: New test. + 2019-08-30 Eric Botcazou * gnat.dg/pack24.adb: New test. diff --git a/gcc/testsuite/gfortran.dg/char_array_constructor_4.f90 b/gcc/testsuite/gfortran.dg/char_array_constructor_4.f90 new file mode 100644 index 0000000..e7c68f9 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/char_array_constructor_4.f90 @@ -0,0 +1,13 @@ +! PR 30319 - Bogus warning from -Warray-bounds during string assignment +! { dg-do compile } +! { dg-options "-O2 -Warray-bounds" } + +program test_bounds + + character(256) :: foo + + foo = '1234' ! { dg-bogus "\\\[-Warray-bounds" } + + print *, foo + +end program test_bounds diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index c95b5ad..bc06480 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -4703,31 +4703,23 @@ vrp_prop::check_mem_ref (location_t location, tree ref, || RECORD_OR_UNION_TYPE_P (reftype)) return false; + arrbounds[0] = 0; + offset_int eltsize; if (TREE_CODE (reftype) == ARRAY_TYPE) { eltsize = wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (reftype))); - if (tree dom = TYPE_DOMAIN (reftype)) { tree bnds[] = { TYPE_MIN_VALUE (dom), TYPE_MAX_VALUE (dom) }; - if (array_at_struct_end_p (arg) - || !bnds[0] || !bnds[1]) - { - arrbounds[0] = 0; - arrbounds[1] = wi::lrshift (maxobjsize, wi::floor_log2 (eltsize)); - } + if (array_at_struct_end_p (arg) || !bnds[0] || !bnds[1]) + arrbounds[1] = wi::lrshift (maxobjsize, wi::floor_log2 (eltsize)); else - { - arrbounds[0] = wi::to_offset (bnds[0]) * eltsize; - arrbounds[1] = (wi::to_offset (bnds[1]) + 1) * eltsize; - } + arrbounds[1] = (wi::to_offset (bnds[1]) - wi::to_offset (bnds[0]) + + 1) * eltsize; } else - { - arrbounds[0] = 0; - arrbounds[1] = wi::lrshift (maxobjsize, wi::floor_log2 (eltsize)); - } + arrbounds[1] = wi::lrshift (maxobjsize, wi::floor_log2 (eltsize)); if (TREE_CODE (ref) == MEM_REF) { @@ -4742,7 +4734,6 @@ vrp_prop::check_mem_ref (location_t location, tree ref, else { eltsize = 1; - arrbounds[0] = 0; arrbounds[1] = wi::to_offset (TYPE_SIZE_UNIT (reftype)); } -- cgit v1.1 From 648af1684557e24e54a67b95b57fae2646cc2b56 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Fri, 30 Aug 2019 17:49:17 +0000 Subject: PR middle-end/91599 - GCC does not say where warning is happening gcc/ChangeLog: PR middle-end/91599 * tree-ssa-strlen.c (handle_store): Use a fallback location if the statement doesn't have one. * gimple-pretty-print.c (percent_G_format): Same. gcc/testsuite/ChangeLog: PR middle-end/91599 * gcc.dg/Wstringop-overflow-16.c: New test. From-SVN: r275211 --- gcc/ChangeLog | 5 +++++ gcc/gimple-pretty-print.c | 6 +++++- gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/gcc.dg/Wstringop-overflow-16.c | 21 +++++++++++++++++++++ gcc/tree-ssa-strlen.c | 5 +++++ 5 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-16.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 45dd3a2..1a8026c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2019-08-30 Martin Sebor + PR middle-end/91599 + * tree-ssa-strlen.c (handle_store): Use a fallback location if + the statement doesn't have one. + * gimple-pretty-print.c (percent_G_format): Same. + PR middle-end/91584 * tree-vrp.c (vrp_prop::check_mem_ref): Normalize type domain bounds before using them to validate MEM_REF offset. diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index ce339ee..2d5ece0 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -3034,8 +3034,12 @@ percent_G_format (text_info *text) { gimple *stmt = va_arg (*text->args_ptr, gimple*); + /* Fall back on the rich location if the statement doesn't have one. */ + location_t loc = gimple_location (stmt); + if (loc == UNKNOWN_LOCATION) + loc = text->m_richloc->get_loc (); tree block = gimple_block (stmt); - percent_K_format (text, gimple_location (stmt), block); + percent_K_format (text, loc, block); } #if __GNUC__ >= 10 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 420ddd4..83d17a3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2019-08-30 Martin Sebor + PR middle-end/91599 + * gcc.dg/Wstringop-overflow-16.c: New test. + PR middle-end/91584 * gfortran.dg/char_array_constructor_4.f90: New test. diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-16.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-16.c new file mode 100644 index 0000000..74548a4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-16.c @@ -0,0 +1,21 @@ +/* PR middle-end/91599 - GCC does not say where warning is happening + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +struct charseq { + unsigned char bytes[0]; // { dg-message "object declared here" } +}; + +struct locale_ctype_t { + struct charseq *mboutdigits[10]; +}; + +void ctype_finish (struct locale_ctype_t *ctype) +{ + long unsigned int cnt; + for (cnt = 0; cnt < 20; ++cnt) { + static struct charseq replace[2]; + replace[0].bytes[1] = '\0'; // { dg-warning "\\\[-Wstringop-overflow" } + ctype->mboutdigits[cnt] = &replace[0]; + } +} diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index 7bb5f52..b979320 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -4036,7 +4036,12 @@ handle_store (gimple_stmt_iterator *gsi) if (tree dstsize = compute_objsize (lhs, 1, &decl)) if (compare_tree_int (dstsize, lenrange[2]) < 0) { + /* Fall back on the LHS location if the statement + doesn't have one. */ location_t loc = gimple_nonartificial_location (stmt); + if (loc == UNKNOWN_LOCATION) + loc = tree_nonartificial_location (lhs); + loc = expansion_point_location_if_in_system_header (loc); if (warning_n (loc, OPT_Wstringop_overflow_, lenrange[2], "%Gwriting %u byte into a region of size %E", -- cgit v1.1 From 4a140826453da37a134d792e0224f4e37343e68a Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 30 Aug 2019 21:49:49 +0000 Subject: compile, runtime: permit anonymous and empty fields in C header Permit putting structs with anonymous and empty fields in the C header file runtime.inc that is used to build the C runtime code. This is required for upcoming 1.13 support, as the m struct has picked up an anonymous field. Doing this lets the C header contain all the type descriptor structs, so start using those in the C code. This cuts the number of copies of type descriptor definitions from 3 to 2. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/192343 From-SVN: r275227 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/gogo.cc | 4 ++-- gcc/go/gofrontend/types.cc | 11 +++++++++-- 3 files changed, 12 insertions(+), 5 deletions(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 3ae07c4..e245973 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -db738935c77443840994e5a9f77e619e67a4c43a +11fd9208f8545e882f945d3ed86fcc33abf1a61b The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 7aec0cf..f8114ece 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -5238,11 +5238,11 @@ Gogo::write_c_header() // package they are mostly types defined by mkrsysinfo.sh based // on the C system header files. We don't need to translate // types to C and back to Go. But do accept the special cases - // _defer and _panic. + // _defer, _panic, and _type. std::string name = Gogo::unpack_hidden_name(no->name()); if (name[0] == '_' && (name[1] < 'A' || name[1] > 'Z') - && (name != "_defer" && name != "_panic")) + && (name != "_defer" && name != "_panic" && name != "_type")) continue; if (no->is_type() && no->type_value()->struct_type() != NULL) diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index 20f8f27..0ada841 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -6777,8 +6777,6 @@ Struct_type::can_write_to_c_header( p != fields->end(); ++p) { - if (p->is_anonymous()) - return false; if (!this->can_write_type_to_c_header(p->type(), requires, declare)) return false; if (Gogo::message_name(p->field_name()) == "_") @@ -6847,6 +6845,9 @@ Struct_type::can_write_type_to_c_header( } if (t->struct_type() != NULL) { + // We will accept empty struct fields, but not print them. + if (t->struct_type()->total_field_count() == 0) + return true; requires->push_back(no); return t->struct_type()->can_write_to_c_header(requires, declare); } @@ -6871,6 +6872,12 @@ Struct_type::write_to_c_header(std::ostream& os) const p != fields->end(); ++p) { + // Skip fields that are empty struct types. The C code can't + // refer to them anyhow. + if (p->type()->struct_type() != NULL + && p->type()->struct_type()->total_field_count() == 0) + continue; + os << '\t'; this->write_field_to_c_header(os, p->field_name(), p->type()); os << ';' << std::endl; -- cgit v1.1 From a169f35890152e8a31ef9bdc0d28a2e0a62e866e Mon Sep 17 00:00:00 2001 From: Jim Wilson Date: Fri, 30 Aug 2019 23:32:52 +0000 Subject: RISC-V: Disable -msave-restore for shared libraries. This was noticed while trying to test -msave-restore support. The save/restore routines use the alternate return register t0/x5 which is clobbered by the PLT header, so we can't use them in shared libraries. This patch disables -msave-restore when -fpic (and -mplt), and emits a warning if the user explicitly turned on -msave-restore. gcc/ * config/riscv/riscv.c (riscv_option_override): If -msave-restore and -fpic and -mplt then disable -msave-restore and warn. From-SVN: r275231 --- gcc/ChangeLog | 5 +++++ gcc/config/riscv/riscv.c | 10 ++++++++++ 2 files changed, 15 insertions(+) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1a8026c..04e773a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-08-30 Jim Wilson + + * config/riscv/riscv.c (riscv_option_override): If -msave-restore + and -fpic and -mplt then disable -msave-restore and warn. + 2019-08-30 Martin Sebor PR middle-end/91599 diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c index 9b16a1e..1e7528f 100644 --- a/gcc/config/riscv/riscv.c +++ b/gcc/config/riscv/riscv.c @@ -4636,6 +4636,16 @@ riscv_option_override (void) error ("%<-mriscv-attribute%> RISC-V ELF attribute requires GNU as 2.32" " [%<-mriscv-attribute%>]"); #endif + + /* The save-restore routines use t0 which is clobbered by the plt header, + so we can't use them when building shared libraries. */ + if (TARGET_SAVE_RESTORE && flag_pic && TARGET_PLT) + { + target_flags &= ~MASK_SAVE_RESTORE; + if (target_flags_explicit & MASK_SAVE_RESTORE) + warning (0, "%<-msave-restore%> disabled; not supported with PLT " + "based shared libraries"); + } } /* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */ -- cgit v1.1 From a74e175a434645fcf920d2c01fb88f2cbd86adb2 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sat, 31 Aug 2019 00:17:00 +0000 Subject: Daily bump. From-SVN: r275235 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 53042e9..dcfd94e 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20190830 +20190831 -- cgit v1.1 From 460b985ea3d74a371db90b1e54fd3f02752cf658 Mon Sep 17 00:00:00 2001 From: "Steven G. Kargl" Date: Sat, 31 Aug 2019 00:32:48 +0000 Subject: re PR fortran/91587 (ICE in gfc_resolve_filepos, at fortran/io.c:2913) 2019-08-30 Steven G. Kargl PR fortran/91587 * io.c (match_filepos): MATCH_ERROR should branch to a syntax error. 2019-08-30 Steven G. Kargl PR fortran/91587 * gfortran.dg/pr91587.f90: New test. From-SVN: r275236 --- gcc/fortran/ChangeLog | 5 +++++ gcc/fortran/io.c | 2 +- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gfortran.dg/pr91587.f90 | 12 ++++++++++++ 4 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gfortran.dg/pr91587.f90 (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 0f2efb2..a34b871 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,8 @@ +2019-08-30 Steven G. Kargl + + PR fortran/91587 + * io.c (match_filepos): MATCH_ERROR should branch to a syntax error. + 2019-08-28 Steven G. Kargl PR fortran/91551 diff --git a/gcc/fortran/io.c b/gcc/fortran/io.c index cd21c6b..632e168 100644 --- a/gcc/fortran/io.c +++ b/gcc/fortran/io.c @@ -2845,7 +2845,7 @@ match_filepos (gfc_statement st, gfc_exec_op op) m = match_file_element (fp); if (m == MATCH_ERROR) - goto done; + goto syntax; if (m == MATCH_NO) { m = gfc_match_expr (&fp->unit); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 83d17a3..c590b46 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-08-30 Steven G. Kargl + + PR fortran/91587 + * gfortran.dg/pr91587.f90: New test. + 2019-08-30 Martin Sebor PR middle-end/91599 diff --git a/gcc/testsuite/gfortran.dg/pr91587.f90 b/gcc/testsuite/gfortran.dg/pr91587.f90 new file mode 100644 index 0000000..c07735d --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr91587.f90 @@ -0,0 +1,12 @@ +! { dg-do compile } +! PR fortran/91587 +! Code contributed by Gerhard Steinmetz +program p + backspace(err=!) ! { dg-error "Syntax error in" } + flush(err=!) ! { dg-error "Syntax error in" } + rewind(err=!) ! { dg-error "Syntax error in" } +end + +subroutine bar ! An other matcher runs, and gives a different error. + endfile(err=!) ! { dg-error "Expecting END" } +end -- cgit v1.1 From d24c41ef1a44b72aaf03edc6eb40cae711b27f95 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Sat, 31 Aug 2019 02:55:09 +0000 Subject: runtime: always build panic32.go Avoids problems with arm64 ILP32 mode. We might want to handle that mode better in general, but always building panic32.go is simple and fixes the build. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/192723 From-SVN: r275237 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index e245973..c8605ec 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -11fd9208f8545e882f945d3ed86fcc33abf1a61b +2444eb1e8c697531f8beb403679e4ab00b16dbf5 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From e7c8f75569e792f81a4f4ceee4e1b20f2544e7a4 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Sat, 31 Aug 2019 02:56:55 +0000 Subject: compiler: don't report runtime escapes if we've seen errors If we get errors during compilation, we skip the escape analysis pass. If we are compiling the runtime package, we report an error if a bound method expression escapes. The effect is that if we get an error while compiling the runtime package, we would report confusing and meaningless errors about bound method expressions escaping. This CL stops doing that. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/192720 From-SVN: r275238 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/expressions.cc | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index c8605ec..888e96d 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -2444eb1e8c697531f8beb403679e4ab00b16dbf5 +80403eb9e95c9642ebabb4d7c43deedaa763211f The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 939a5f7..4db4e4a 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -7948,7 +7948,9 @@ Bound_method_expression::do_flatten(Gogo* gogo, Named_object*, Node* n = Node::make_node(this); if ((n->encoding() & ESCAPE_MASK) == Node::ESCAPE_NONE) ret->heap_expression()->set_allocate_on_stack(); - else if (gogo->compiling_runtime() && gogo->package_name() == "runtime") + else if (gogo->compiling_runtime() + && gogo->package_name() == "runtime" + && !saw_errors()) go_error_at(loc, "%s escapes to heap, not allowed in runtime", n->ast_format(gogo).c_str()); -- cgit v1.1 From c70ff9f9be0c7360a37519ec68ac4dd41e8d0a3c Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Sat, 31 Aug 2019 03:01:15 +0000 Subject: compiler, runtime: support and use single argument go:linkname The gc compiler has started permitting go:linkname comments with a single argument to mean that a function should be externally visible outside the package. Implement this in the Go frontend. Change the libgo runtime package to use it, rather than repeating the name just to export a function. Remove a couple of unnecessary go:linkname comments on declarations. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/192197 From-SVN: r275239 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/gogo.cc | 25 ++++++++++++++++++++++--- gcc/go/gofrontend/gogo.h | 12 +++++++++++- gcc/go/gofrontend/lex.cc | 6 +++--- gcc/go/gofrontend/lex.h | 2 +- 5 files changed, 38 insertions(+), 9 deletions(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 888e96d..025e66e 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -80403eb9e95c9642ebabb4d7c43deedaa763211f +289d94b9e6303ec74649d1f08d418300f2b4d0fd The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index f8114ece..d39a4fb 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -2531,9 +2531,22 @@ Gogo::add_linkname(const std::string& go_name, bool is_exported, if (no == NULL) go_error_at(loc, "%s is not defined", go_name.c_str()); else if (no->is_function()) - no->func_value()->set_asm_name(ext_name); + { + if (ext_name.empty()) + no->func_value()->set_is_exported_by_linkname(); + else + no->func_value()->set_asm_name(ext_name); + } else if (no->is_function_declaration()) - no->func_declaration_value()->set_asm_name(ext_name); + { + if (ext_name.empty()) + go_error_at(loc, + ("//% missing external name " + "for declaration of %s"), + go_name.c_str()); + else + no->func_declaration_value()->set_asm_name(ext_name); + } else go_error_at(loc, ("%s is not a function; " @@ -5465,7 +5478,8 @@ Function::Function(Function_type* type, Named_object* enclosing, Block* block, calls_recover_(false), is_recover_thunk_(false), has_recover_thunk_(false), calls_defer_retaddr_(false), is_type_specific_function_(false), in_unique_section_(false), export_for_inlining_(false), - is_inline_only_(false), is_referenced_by_inline_(false) + is_inline_only_(false), is_referenced_by_inline_(false), + is_exported_by_linkname_(false) { } @@ -6220,6 +6234,11 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no) if (this->is_referenced_by_inline_) flags |= Backend::function_is_visible; + // A go:linkname directive can be used to force a function to be + // visible. + if (this->is_exported_by_linkname_) + flags |= Backend::function_is_visible; + // If a function calls the predeclared recover function, we // can't inline it, because recover behaves differently in a // function passed directly to defer. If this is a recover diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h index 087e890..e742b6e 100644 --- a/gcc/go/gofrontend/gogo.h +++ b/gcc/go/gofrontend/gogo.h @@ -547,7 +547,9 @@ class Gogo { this->file_block_names_[name] = location; } // Add a linkname, from the go:linkname compiler directive. This - // changes the externally visible name of go_name to be ext_name. + // changes the externally visible name of GO_NAME to be EXT_NAME. + // If EXT_NAME is the empty string, GO_NAME is unchanged, but the + // symbol is made publicly visible. void add_linkname(const std::string& go_name, bool is_exported, const std::string& ext_name, Location location); @@ -1359,6 +1361,11 @@ class Function set_asm_name(const std::string& asm_name) { this->asm_name_ = asm_name; } + // Mark this symbol as exported by a linkname directive. + void + set_is_exported_by_linkname() + { this->is_exported_by_linkname_ = true; } + // Return the pragmas for this function. unsigned int pragmas() const @@ -1706,6 +1713,9 @@ class Function // True if this function is referenced from an inlined body that // will be put into the export data. bool is_referenced_by_inline_ : 1; + // True if we should make this function visible to other packages + // because of a go:linkname directive. + bool is_exported_by_linkname_ : 1; }; // A snapshot of the current binding state. diff --git a/gcc/go/gofrontend/lex.cc b/gcc/go/gofrontend/lex.cc index 3276de4..f023613 100644 --- a/gcc/go/gofrontend/lex.cc +++ b/gcc/go/gofrontend/lex.cc @@ -1996,7 +1996,7 @@ Lex::skip_cpp_comment() while (ps < pend && *ps != ' ' && *ps != '\t') ++ps; - if (ps < pend) + if (ps <= pend) go_name = std::string(pg, ps - pg); while (ps < pend && (*ps == ' ' || *ps == '\t')) ++ps; @@ -2015,8 +2015,8 @@ Lex::skip_cpp_comment() ext_name.clear(); } } - if (go_name.empty() || ext_name.empty()) - go_error_at(loc, "usage: % localname linkname"); + if (go_name.empty()) + go_error_at(loc, "usage: % localname [linkname]"); else { if (this->linknames_ == NULL) diff --git a/gcc/go/gofrontend/lex.h b/gcc/go/gofrontend/lex.h index 59b770c..3be3806 100644 --- a/gcc/go/gofrontend/lex.h +++ b/gcc/go/gofrontend/lex.h @@ -380,7 +380,7 @@ class Lex struct Linkname { - std::string ext_name; // External name. + std::string ext_name; // External name; empty to just export. bool is_exported; // Whether the internal name is exported. Location loc; // Location of go:linkname directive. -- cgit v1.1 From 3ba155dd1921b55f04866b35a2e054e092670cd6 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Sat, 31 Aug 2019 03:07:48 +0000 Subject: compiler: check for notinheap struct at each struct field When generating write barriers, we were only checking for a notinheap struct at the outermost struct. That mishandled the case of setting a pointer to a notinheap struct as a field of another struct that is not notinheap. This caused an invalid write barrier error when building the 1.13 version of the runtime. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/192279 From-SVN: r275240 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/wb.cc | 50 ++++++++++++++++++++++++------------------------- 2 files changed, 26 insertions(+), 26 deletions(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 025e66e..0add2f0 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -289d94b9e6303ec74649d1f08d418300f2b4d0fd +3b8a505824abb2a69f4c04c555a4ba29ab8b102b The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/wb.cc b/gcc/go/gofrontend/wb.cc index 41d8f94..1eadb3e 100644 --- a/gcc/go/gofrontend/wb.cc +++ b/gcc/go/gofrontend/wb.cc @@ -733,6 +733,31 @@ Gogo::assign_needs_write_barrier( && !lhs->type()->points_to()->in_heap()) return false; + // For a struct assignment, we don't need a write barrier if all + // the field types can not be in the heap. + Struct_type* st = lhs->type()->struct_type(); + if (st != NULL) + { + bool in_heap = false; + const Struct_field_list* fields = st->fields(); + for (Struct_field_list::const_iterator p = fields->begin(); + p != fields->end(); + p++) + { + Type* ft = p->type(); + if (!ft->has_pointer()) + continue; + if (!ft->in_heap()) + continue; + if (ft->points_to() != NULL && !ft->points_to()->in_heap()) + continue; + in_heap = true; + break; + } + if (!in_heap) + return false; + } + Field_reference_expression* fre = lhs->field_reference_expression(); if (fre != NULL) { @@ -788,31 +813,6 @@ Gogo::assign_needs_write_barrier( && this->is_nonwb_pointer(ue->operand(), nonwb_pointers)) return false; - // For a struct assignment, we don't need a write barrier if all the - // pointer types can not be in the heap. - Struct_type* st = lhs->type()->struct_type(); - if (st != NULL) - { - bool in_heap = false; - const Struct_field_list* fields = st->fields(); - for (Struct_field_list::const_iterator p = fields->begin(); - p != fields->end(); - p++) - { - Type* ft = p->type(); - if (!ft->has_pointer()) - continue; - if (!ft->in_heap()) - continue; - if (ft->points_to() != NULL && !ft->points_to()->in_heap()) - continue; - in_heap = true; - break; - } - if (!in_heap) - return false; - } - // Write barrier needed in other cases. return true; } -- cgit v1.1 From fd631eb5a7597a7040f770b2a912cec13af50df4 Mon Sep 17 00:00:00 2001 From: Stafford Horne Date: Sat, 31 Aug 2019 06:00:56 +0000 Subject: or1k: Fix issue with set_got clobbering LR (r9) When compiling glibc we found that the GOT register was being allocated r9 when the instruction was still set_got_tmp. That is a problem because r9 is the Link Register (LR) in OpenRISC which is used/clobbered in set_got. We cannot use r9 as the GOT register. Also, we cannot simply say set_got_tmp clobbers r9 as this is the reason for having the temporary set_got_tmp. Fix by using a register class constraint that does not allow r9 during register allocation. gcc/ChangeLog: * config/or1k/constraints.md (t): New constraint. * config/or1k/or1k.h (GOT_REGS): New register class. * config/or1k/or1k.md (set_got_tmp, set_got): Use t contraint. From-SVN: r275242 --- gcc/ChangeLog | 6 ++++++ gcc/config/or1k/constraints.md | 4 ++++ gcc/config/or1k/or1k.h | 3 +++ gcc/config/or1k/or1k.md | 4 ++-- 4 files changed, 15 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 04e773a..023275e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-08-31 Stafford Horne + + * config/or1k/constraints.md (t): New constraint. + * config/or1k/or1k.h (GOT_REGS): New register class. + * config/or1k/or1k.md (set_got_tmp, set_got): Use t contraint. + 2019-08-30 Jim Wilson * config/riscv/riscv.c (riscv_option_override): If -msave-restore diff --git a/gcc/config/or1k/constraints.md b/gcc/config/or1k/constraints.md index 8cac7eb..3ca477c 100644 --- a/gcc/config/or1k/constraints.md +++ b/gcc/config/or1k/constraints.md @@ -25,6 +25,7 @@ ; We use: ; c - sibcall registers ; d - double pair base registers (excludes r0, r30 and r31 which overflow) +; t - got address registers (excludes LR (r9) which is clobbered by set_got) ; I - constant signed 16-bit ; K - constant unsigned 16-bit ; M - constant signed 16-bit shifted left 16-bits (l.movhi) @@ -36,6 +37,9 @@ (define_register_constraint "d" "DOUBLE_REGS" "Registers which can be used for double reg pairs.") +(define_register_constraint "t" "GOT_REGS" + "Registers which can be used to store the Global Offset Table (GOT) address.") + ;; Immediates (define_constraint "I" "A signed 16-bit immediate in the range -32768 to 32767." diff --git a/gcc/config/or1k/or1k.h b/gcc/config/or1k/or1k.h index 2b29e62..4c32607 100644 --- a/gcc/config/or1k/or1k.h +++ b/gcc/config/or1k/or1k.h @@ -190,6 +190,7 @@ enum reg_class NO_REGS, SIBCALL_REGS, DOUBLE_REGS, + GOT_REGS, GENERAL_REGS, FLAG_REGS, ALL_REGS, @@ -202,6 +203,7 @@ enum reg_class "NO_REGS", \ "SIBCALL_REGS", \ "DOUBLE_REGS", \ + "GOT_REGS", \ "GENERAL_REGS", \ "FLAG_REGS", \ "ALL_REGS" } @@ -215,6 +217,7 @@ enum reg_class { { 0x00000000, 0x00000000 }, \ { SIBCALL_REGS_MASK, 0 }, \ { 0x7f7ffffe, 0x00000000 }, \ + { 0xfffffdff, 0x00000000 }, \ { 0xffffffff, 0x00000003 }, \ { 0x00000000, 0x00000004 }, \ { 0xffffffff, 0x00000007 } \ diff --git a/gcc/config/or1k/or1k.md b/gcc/config/or1k/or1k.md index cee11d0..36bcee3 100644 --- a/gcc/config/or1k/or1k.md +++ b/gcc/config/or1k/or1k.md @@ -706,7 +706,7 @@ ;; set_got pattern below. This works because the set_got_tmp insn is the ;; first insn in the stream and that it isn't moved during RA. (define_insn "set_got_tmp" - [(set (match_operand:SI 0 "register_operand" "=r") + [(set (match_operand:SI 0 "register_operand" "=t") (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_GOT))] "" { @@ -715,7 +715,7 @@ ;; The insn to initialize the GOT. (define_insn "set_got" - [(set (match_operand:SI 0 "register_operand" "=r") + [(set (match_operand:SI 0 "register_operand" "=t") (unspec:SI [(const_int 0)] UNSPEC_SET_GOT)) (clobber (reg:SI LR_REGNUM))] "" -- cgit v1.1 From 8498adc27141f048a0492c5b0cc1438a7fee24b7 Mon Sep 17 00:00:00 2001 From: Gerald Pfeifer Date: Sat, 31 Aug 2019 17:20:28 +0000 Subject: generic.texi (Unary and Binary Expressions): Mark up an instance of TYPE_MIN. * doc/generic.texi (Unary and Binary Expressions): Mark up an instance of TYPE_MIN. From-SVN: r275243 --- gcc/ChangeLog | 5 +++++ gcc/doc/generic.texi | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 023275e..49c371b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-08-31 Gerald Pfeifer + + * doc/generic.texi (Unary and Binary Expressions): Mark up + an instance of TYPE_MIN. + 2019-08-31 Stafford Horne * config/or1k/constraints.md (t): New constraint. diff --git a/gcc/doc/generic.texi b/gcc/doc/generic.texi index 8901d5f..86a53cc 100644 --- a/gcc/doc/generic.texi +++ b/gcc/doc/generic.texi @@ -1373,8 +1373,8 @@ built-in functions. @item ABSU_EXPR These nodes represent the absolute value of the single operand in -equivalent unsigned type such that @code{ABSU_EXPR} of TYPE_MIN is -well defined. +equivalent unsigned type such that @code{ABSU_EXPR} of @code{TYPE_MIN} +is well defined. @item BIT_NOT_EXPR These nodes represent bitwise complement, and will always have integral -- cgit v1.1 From bd486c8cdfd943289c8c729f2dc6e0ef911bdb28 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Sat, 31 Aug 2019 22:49:27 +0100 Subject: * es.po: Update. From-SVN: r275258 --- gcc/po/ChangeLog | 4 + gcc/po/es.po | 274 ++++++++++++++++++++----------------------------------- 2 files changed, 102 insertions(+), 176 deletions(-) (limited to 'gcc') diff --git a/gcc/po/ChangeLog b/gcc/po/ChangeLog index b8d6f01..52a20a0 100644 --- a/gcc/po/ChangeLog +++ b/gcc/po/ChangeLog @@ -1,3 +1,7 @@ +2019-08-31 Joseph Myers + + * es.po: Update. + 2019-08-28 Joseph Myers * es.po: Update. diff --git a/gcc/po/es.po b/gcc/po/es.po index 5b6e205..5d62016 100644 --- a/gcc/po/es.po +++ b/gcc/po/es.po @@ -43,7 +43,7 @@ msgstr "" "Project-Id-Version: gcc 9.1.0\n" "Report-Msgid-Bugs-To: https://gcc.gnu.org/bugs/\n" "POT-Creation-Date: 2019-05-02 20:28+0000\n" -"PO-Revision-Date: 2019-08-28 09:32+0200\n" +"PO-Revision-Date: 2019-08-31 18:04+0200\n" "Last-Translator: Antonio Ceballos Roa \n" "Language-Team: Spanish \n" "Language: es\n" @@ -1961,16 +1961,14 @@ msgid "A threshold on the average loop count considered by the swing modulo sche msgstr "Umbral en el número promedio de bucles considerado por el planificador de cambio de módulo." #: params.def:430 -#, fuzzy, no-c-format -#| msgid "Select fraction of the maximal count of repetitions of basic block in program given basic block needs to have to be considered hot" +#, no-c-format msgid "Select fraction of the maximal count of repetitions of basic block in program given basic block needs to have to be considered hot (used in non-LTO mode)." -msgstr "La selección de fracción de la cuenta maximal de repeticiones del bloque básico en el bloque básico dado de programa que necesita para ser considerado caliente" +msgstr "La selección de fracción de la cuenta maximal de repeticiones del bloque básico en el bloque básico dado de programa que necesita para ser considerado caliente (utilizado en modo no LTO)." #: params.def:435 -#, fuzzy, no-c-format -#| msgid "A basic block profile count is considered hot if it contributes to the given permillage of the entire profiled execution." +#, no-c-format msgid "A basic block profile count is considered hot if it contributes to the given permillage of the entire profiled execution (used in LTO mode)." -msgstr "El número de perfiles de bloque básicos se considera caliente si contribuye al pormillaje dado de la ejecución perfilada completa." +msgstr "El número de perfiles de bloque básicos se considera caliente si contribuye al pormillaje dado de la ejecución perfilada completa (utilizado en modo LTO)." #: params.def:440 #, no-c-format @@ -1988,8 +1986,7 @@ msgid "Select fraction of the maximal frequency of executions of basic block in msgstr "Selección de fracción de la frecuencia máxima de ejecuciones de bloque básico en la función dada para la que el bloque básico consigue alinear." #: params.def:455 -#, fuzzy, no-c-format -#| msgid "Loops iterating at least selected number of iterations will get loop alignment.." +#, no-c-format msgid "Loops iterating at least selected number of iterations will get loop alignment." msgstr "Iterar ciclos por lo menos el número seleccionado de iteraciones que logrará alineación de bucles." @@ -2100,10 +2097,9 @@ msgid "Maximum size (in bytes) of objects tracked bytewise by dead store elimina msgstr "Número máximo (en bytes) de objetos rastreados en btyes por la eliminación de almacenamiento muerto." #: params.def:593 -#, fuzzy, no-c-format -#| msgid "Maximum number of times that an insn could be scheduled." +#, no-c-format msgid "Maximum number of queries into the alias oracle per store." -msgstr "El número máximo de veces que se puede planificar una insns." +msgstr "El número máximo de consultas al oráculo de alias por almacenamiento." #: params.def:598 #, no-c-format @@ -2474,22 +2470,19 @@ msgid "Maximum size of a list of values associated with each parameter for inter msgstr "Tamaño máximo de una lista de valores asociada con cada parámetro para propagación constante entre procedimientos." #: params.def:1092 -#, fuzzy, no-c-format -#| msgid "Threshold ipa-cp opportunity evaluation that is still considered beneficial to clone.." +#, no-c-format msgid "Threshold ipa-cp opportunity evaluation that is still considered beneficial to clone." -msgstr "Rango de evaluación de oportunidad ipa-cp que aún se considera beneficioso para clonar.." +msgstr "Rango de evaluación de oportunidad ipa-cp que aún se considera beneficioso para clonar." #: params.def:1098 -#, fuzzy, no-c-format -#| msgid "Percentage penalty the recursive functions will receive when they are evaluated for cloning.." +#, no-c-format msgid "Percentage penalty the recursive functions will receive when they are evaluated for cloning." -msgstr "Penalización porcentual que recibirán las funciones recursivas cuando se evalúen para clonación.." +msgstr "Penalización porcentual que recibirán las funciones recursivas cuando se evalúen para clonación." #: params.def:1104 -#, fuzzy, no-c-format -#| msgid "Percentage penalty functions containing a single call to another function will receive when they are evaluated for cloning.." +#, no-c-format msgid "Percentage penalty functions containing a single call to another function will receive when they are evaluated for cloning." -msgstr "Penalización porcentual que recibirán las funciones que contien una sola llamada a otra función cuando se evalúen para clonación.." +msgstr "Penalización porcentual que recibirán las funciones que contien una sola llamada a otra función cuando se evalúen para clonación." #: params.def:1110 #, no-c-format @@ -2497,16 +2490,14 @@ msgid "Maximum number of aggregate content items for a parameter in jump functio msgstr "Número máximo de elementos de contenido agregado de un parámetro en funciones de salto y celosías." #: params.def:1116 -#, fuzzy, no-c-format -#| msgid "Compile-time bonus IPA-CP assigns to candidates which make loop bounds or strides known.." +#, no-c-format msgid "Compile-time bonus IPA-CP assigns to candidates which make loop bounds or strides known." -msgstr "Bonificación de tiempo de compilación que IPA-CP asigna a los candidatos que dan a conocer los límites o los pasos de los bucles.." +msgstr "Bonificación de tiempo de compilación que IPA-CP asigna a los candidatos que dan a conocer los límites o los pasos de los bucles." #: params.def:1122 -#, fuzzy, no-c-format -#| msgid "Compile-time bonus IPA-CP assigns to candidates which make an array index known.." +#, no-c-format msgid "Compile-time bonus IPA-CP assigns to candidates which make an array index known." -msgstr "Bonificación de tiempo de compilación que IPA-CP asigna a los candidatos que dan conocer el índice de un array.." +msgstr "Bonificación de tiempo de compilación que IPA-CP asigna a los candidatos que dan conocer el índice de un array." #: params.def:1128 #, no-c-format @@ -2555,10 +2546,9 @@ msgid "Allow new data races on stores to be introduced." msgstr "Permite que se introduzcan carreras de datos nuevos en stores." #: params.def:1187 -#, fuzzy, no-c-format -#| msgid "Set the maximum number of instructions executed in parallel in reassociated tree. If 0, use the target dependent heuristic.." +#, no-c-format msgid "Set the maximum number of instructions executed in parallel in reassociated tree. If 0, use the target dependent heuristic." -msgstr "Establece el número máximo de instrucciones ejecutadas en paralelo en el árbol de reasociación. Si es 0, usa la heurística dependiente del objetivo.." +msgstr "Establece el número máximo de instrucciones ejecutadas en paralelo en el árbol de reasociación. Si es 0, usa la heurística dependiente del objetivo." #: params.def:1193 #, no-c-format @@ -2727,10 +2717,9 @@ msgid "Maximum number of may-defs visited when devirtualizing speculatively." msgstr "Número máximo de definiciones posibles visitadas cuando se desvirtualiza especulativamente." #: params.def:1375 -#, fuzzy, no-c-format -#| msgid "Maximum number of constant stores to merge in the store merging pass." +#, no-c-format msgid "Maximum number of assertions to add along the default edge of a switch statement during VRP." -msgstr "Número máximo de almacenamientos constantes que hay que mezclar en el paso de mezcla de almacenamientos." +msgstr "Número máximo de aserciones que hay que añadir a lo largo del borde predefinido de una sentencia switch durante VRP." #: params.def:1381 #, no-c-format @@ -2745,7 +2734,7 @@ msgstr "" #: params.def:1391 #, no-c-format msgid "Maximum unroll factor for the unroll-and-jam transformation." -msgstr "" +msgstr "Máximo factor de desenrrollado para la transformación unroll-and-jam." #: params.def:1396 #, no-c-format @@ -2755,19 +2744,17 @@ msgstr "Número máximo de bits para el cual evitamos crear FMAs." #: params.def:1401 #, no-c-format msgid "True if a non-short-circuit operation is optimal." -msgstr "" +msgstr "Verdadero si una operación de non-short-circuit es óptima." #: params.def:1406 -#, fuzzy, no-c-format -#| msgid "Maximum number of instructions in basic block to be considered for SLP vectorization." +#, no-c-format msgid "The maximum number of instructions in an inner loop that is being considered for versioning." -msgstr "El número máximo de instrucciones en bloque básico que se consideran para vectorización SLP." +msgstr "El número máximo de instrucciones en un bucle interior que se consideran para versionar." #: params.def:1412 -#, fuzzy, no-c-format -#| msgid "The maximum number of instructions to consider to unroll in a loop." +#, no-c-format msgid "The maximum number of instructions in an outer loop that is being considered for versioning, on top of the instructions in inner loops." -msgstr "El número máximo de instrucciones para considerar el desenrollo en un bucle." +msgstr "El número máximo de instrucciones ien un bucle exterior que se consideran para versionar, por encima de las instrucciones en los bucles interiores." #: c-family/c-format.c:404 msgid "format" @@ -3634,15 +3621,14 @@ msgstr "operando output_condmove_single erróneo" #: config/gcn/gcn.c:5637 config/gcn/gcn.c:5648 config/gcn/gcn.c:5651 #, c-format msgid "bad ADDR_SPACE_GLOBAL address" -msgstr "" +msgstr "dirección ADDR_SPACE_GLOBAL errónea" #: config/gcn/gcn.c:5423 config/gcn/gcn.c:5446 config/gcn/gcn.c:5475 #: config/gcn/gcn.c:5491 config/gcn/gcn.c:5510 config/gcn/gcn.c:5586 #: config/gcn/gcn.c:5782 config/gcn/gcn.c:5879 -#, fuzzy, c-format -#| msgid "invalid operand to %%Z code" +#, c-format msgid "invalid operand %%xn code" -msgstr "operando no válido para el código %%Z" +msgstr "operando no válido para el código %%xn" #: config/gcn/gcn.c:5949 #, c-format @@ -3941,22 +3927,19 @@ msgid "invalid zero extract" msgstr "extracto de cero no válido" #: config/or1k/or1k.c:1124 config/or1k/or1k.c:1132 -#, fuzzy, c-format -#| msgid "invalid operation" +#, c-format msgid "invalid relocation" -msgstr "operación no válida" +msgstr "reubicación no válida" #: config/or1k/or1k.c:1226 -#, fuzzy, c-format -#| msgid "invalid %H value" +#, c-format msgid "invalid %%H value" -msgstr "valor %H no válido" +msgstr "valor %%H no válido" #: config/or1k/or1k.c:1274 -#, fuzzy, c-format -#| msgid "unknown punctuation '%c'" +#, c-format msgid "unknown operand letter: '%c'" -msgstr "puntuación '%c' desconocida" +msgstr "letra de operando desconocida: '%c'" #: config/rl78/rl78.c:2009 config/rl78/rl78.c:2095 #, c-format @@ -3974,46 +3957,32 @@ msgid "Try running '%s' in the shell to raise its limit.\n" msgstr "Pruebe ejecutar '%s' en el intérprete de órdenes para elevar su límite.\n" #: config/rs6000/rs6000.c:3995 -#, fuzzy -#| msgid "-mvsx requires hardware floating point" msgid "%<-mvsx%> requires hardware floating point" -msgstr "-mvsx requiere coma flotante de hardware" +msgstr "%<-mvsx%> requiere coma flotante de hardware" #: config/rs6000/rs6000.c:4003 -#, fuzzy -#| msgid "-mvsx needs indexed addressing" msgid "%<-mvsx%> needs indexed addressing" -msgstr "-mvsx necesita direccionamiento indizado" +msgstr "%<-mvsx%> necesita direccionamiento indexado" #: config/rs6000/rs6000.c:4008 -#, fuzzy -#| msgid "-mvsx and -mno-altivec are incompatible" msgid "%<-mvsx%> and %<-mno-altivec%> are incompatible" -msgstr "-mvsx y -mno-altivec son incompatibles" +msgstr "%<-mvsx%> y -% son incompatibles" #: config/rs6000/rs6000.c:4010 -#, fuzzy -#| msgid "-mno-altivec disables vsx" msgid "%<-mno-altivec%> disables vsx" -msgstr "-mno-altivec desactiva vsx" +msgstr "%<-mno-altivec%> desactiva vsx" #: config/rs6000/rs6000.c:4136 -#, fuzzy -#| msgid "-mquad-memory requires 64-bit mode" msgid "%<-mquad-memory%> requires 64-bit mode" -msgstr "-mquad-memory requiere modo de 64 bits" +msgstr "%<-mquad-memory%> requiere modo de 64 bits" #: config/rs6000/rs6000.c:4139 -#, fuzzy -#| msgid "-mquad-memory-atomic requires 64-bit mode" msgid "%<-mquad-memory-atomic%> requires 64-bit mode" -msgstr "-mquad-memory-atomic requiere modo de 64 bits" +msgstr "%<-mquad-memory-atomic%> requiere modo de 64 bits" #: config/rs6000/rs6000.c:4151 -#, fuzzy -#| msgid "-mquad-memory is not available in little endian mode" msgid "%<-mquad-memory%> is not available in little endian mode" -msgstr "-mquad-memory no está disponible en modo little endian" +msgstr "%<-mquad-memory%> no está disponible en modo little endian" #: config/rs6000/rs6000.c:10374 msgid "bad move" @@ -4079,10 +4048,9 @@ msgid "invalid %%q value" msgstr "valor %%q no válido" #: config/rs6000/rs6000.c:21141 -#, fuzzy, c-format -#| msgid "invalid %%J value" +#, c-format msgid "invalid %%t value" -msgstr "valor %%J no válido" +msgstr "valor %%t no válido" #: config/rs6000/rs6000.c:21158 #, c-format @@ -4100,10 +4068,9 @@ msgid "invalid %%v value" msgstr "valor %%v no válido" #: config/rs6000/rs6000.c:21234 -#, fuzzy, c-format -#| msgid "invalid %%J value" +#, c-format msgid "invalid %%V value" -msgstr "valor %%J no válido" +msgstr "valor %%V no válido" #: config/rs6000/rs6000.c:21251 config/xtensa/xtensa.c:2439 #, c-format @@ -4675,10 +4642,8 @@ msgid "enters synchronized or atomic statement" msgstr "entra en la sentencia sincronizada o atómica" #: cp/decl.c:3254 -#, fuzzy -#| msgid "expected statement" msgid "enters constexpr if statement" -msgstr "se esperaba una declaración" +msgstr "entre en la sentencia if de expresión constante" #: cp/error.c:375 msgid "" @@ -5011,10 +4976,8 @@ msgid "Integer outside symmetric range implied by Standard Fortran at %L" msgstr "Rango simétrico fuera de entero implicado por Standard Fortran en %L" #: fortran/arith.c:118 -#, fuzzy -#| msgid "Illegal character in BOZ constant at %C" msgid "Illegal type in character concatenation at %L" -msgstr "Carácter ilegal en la constante BOZ en %C" +msgstr "Typo ilegal en concatenación de caracteres en %L" #: fortran/arith.c:1384 msgid "elemental binary operation" @@ -5376,10 +5339,9 @@ msgid "Operand of unary numeric operator %%<%s%%> at %%L is %s" msgstr "El operando del operador numérico unitario %%<%s%%> en %%L es %s" #: fortran/resolve.c:3949 -#, fuzzy, c-format -#| msgid "Operands of binary numeric operator %%<%s%%> at %%L are %s/%s" +#, c-format msgid "Unexpected derived-type entities in binary intrinsic numeric operator %%<%s%%> at %%L" -msgstr "Los operandos del operador numérico binario %%<%s%%> en %%L son %s/%s" +msgstr "Entidades de tipos derivados no esperadas en el operador numérico intrínseco binario %%<%s%%> en %%L" #: fortran/resolve.c:3954 #, c-format @@ -5496,7 +5458,7 @@ msgstr "Desborde entero al calcular la cantidad de memoria a reservar" #: fortran/trans-array.c:9544 #, c-format msgid "The value of the PDT LEN parameter '%s' does not agree with that in the dummy declaration" -msgstr "" +msgstr "El valor del parámetro PDT LEN '%s' no concuerda con el de la declaración «dummy»" #: fortran/trans-decl.c:6025 #, c-format @@ -5698,10 +5660,8 @@ msgid "-E or -x required when input is from standard input" msgstr "se requiere -E ó -x cuando la entrada es de entrada estándar" #: config/darwin.h:126 config/darwin.h:427 -#, fuzzy -#| msgid "-pg not supported on this platform" msgid "gsplit-dwarf is not supported on this platform" -msgstr "-pg no se admite en esta plataforma" +msgstr "gsplit-dwarf no se admite en esta plataforma" #: config/darwin.h:170 msgid "rdynamic is not supported" @@ -5767,8 +5727,6 @@ msgstr "-Xbind-now y -Xbind-lazy son incompatibles" #: config/aarch64/aarch64-freebsd.h:37 config/arm/freebsd.h:49 #: config/riscv/freebsd.h:44 -#, fuzzy -#| msgid "consider using `-pg' instead of `-p' with gprof (1) " msgid "consider using `-pg' instead of `-p' with gprof (1)" msgstr "considere usar `-pg' en lugar de `-p' con gprof (1)" @@ -5847,7 +5805,7 @@ msgstr "considere usar `-pg' en lugar de `-p' con gprof(1)" #: config/rs6000/rs6000.h:139 msgid "Missing -mcpu option in ASM_CPU_SPEC?" -msgstr "" +msgstr "¿Falta la opción -mcpu en ASM_CPU_SPEC?" #: config/rx/rx.h:80 msgid "-mas100-syntax is incompatible with -gdwarf" @@ -5870,10 +5828,8 @@ msgid "SH2a does not support little-endian" msgstr "SH2a no se admite para little-endian" #: config/sparc/linux64.h:148 -#, fuzzy -#| msgid "-pie is not supported in this configuration" msgid "-fsanitize=address is not supported in this configuration" -msgstr "-pie no se admite en esta configuración" +msgstr "-fsanitize=dirección no se admite en esta configuración" #: config/sparc/linux64.h:162 config/sparc/linux64.h:168 #: config/sparc/netbsd-elf.h:108 config/sparc/netbsd-elf.h:117 @@ -5939,7 +5895,7 @@ msgstr "Avisa sobre la creación de matrices temporales." #: fortran/lang.opt:214 msgid "Warn about type and rank mismatches between arguments and parameters." -msgstr "" +msgstr "Avisa sobre discordancias de tipo y rango entre argumentos y parámetros." #: fortran/lang.opt:218 msgid "Warn if the type of a variable might be not interoperable with C." @@ -6222,7 +6178,7 @@ msgstr "-ffree-line-length-\tUsa n como ancho de línea de carácter en modo #: fortran/lang.opt:565 msgid "Try to interchange loops if profitable." -msgstr "" +msgstr "Intenta intercambiar bucles si es provechoso." #: fortran/lang.opt:569 msgid "Enable front end optimization." @@ -6238,7 +6194,7 @@ msgstr "-finit-character=\tInicializa las variables de carácter locales al v #: fortran/lang.opt:581 msgid "Initialize components of derived type variables according to other init flags." -msgstr "" +msgstr "Inicializa componentes de variables de tipo derivado en conformidad con otros indicadores de inicialización." #: fortran/lang.opt:585 msgid "-finit-integer=\tInitialize local integer variables to n." @@ -6294,7 +6250,7 @@ msgstr "Protege paréntesis en las expresiones." #: fortran/lang.opt:675 msgid "Path to header file that should be pre-included before each compilation unit." -msgstr "" +msgstr "Ruta de fichero de cabecera que debería preincluirse antes de cada unidad de compilación." #: fortran/lang.opt:679 msgid "Enable range checking during compilation." @@ -6496,7 +6452,7 @@ msgstr "Avisa si un subojeto tiene un atributo abi_tag que el objeto completo no #: c-family/c.opt:276 msgid "Warn on suspicious calls of standard functions computing absolute values." -msgstr "" +msgstr "Advierte de llamadas sospechosas de funciones estándar que calculan valores absolutos." #: c-family/c.opt:280 msgid "Warn about suspicious uses of memory addresses." @@ -6524,7 +6480,7 @@ msgstr "-Walloc-size-larger-than= Avierte de llamadas a funciones de rese #: c-family/c.opt:317 msgid "-Wno-alloc-size-larger-than Disable Walloc-size-larger-than= warning. Equivalent to Walloc-size-larger-than= or larger." -msgstr "" +msgstr "-Wno-alloc-size-larger-than Desactiva el aviso Walloc-size-larger-than=. Equivalente a Walloc-size-larger-than= o mayor." #: c-family/c.opt:321 msgid "-Walloc-zero Warn for calls to allocation functions that specify zero bytes." @@ -6536,7 +6492,7 @@ msgstr "-Walloca-larger-than=\tAdvierte de usos no acotados de alloca y #: c-family/c.opt:331 msgid "-Wno-alloca-larger-than Disable Walloca-larger-than= warning. Equivalent to Walloca-larger-than= or larger." -msgstr "" +msgstr "-Wno-alloca-larger-than Desactiva el aviso Walloca-larger-than=. Equivalente a Walloca-larger-than= o mayor." #: c-family/c.opt:343 msgid "Warn whenever an Objective-C assignment is being intercepted by the garbage collector." @@ -6567,10 +6523,8 @@ msgid "Warn when a built-in preprocessor macro is undefined or redefined." msgstr "Avisa cuando una macro de preprocesador interna está sin definir o redefinida." #: c-family/c.opt:371 -#, fuzzy -#| msgid "Warn about features not present in ISO C99, but present in ISO C11." msgid "Warn about features not present in ISO C11, but present in ISO C2X." -msgstr "Avisa sobre características no presentes en ISO C99, pero presentes en ISO C11." +msgstr "Avisa sobre características no presentes en ISO C11, pero presentes en ISO C2X." #: c-family/c.opt:375 msgid "Warn about features not present in ISO C90, but present in ISO C99." @@ -6620,10 +6574,8 @@ msgstr "Avisa sobre subíndices cuyo tipo es \"char\"." #: c-family/c.opt:1369 c-family/c.opt:1373 c-family/c.opt:1377 #: c-family/c.opt:1381 c-family/c.opt:1385 c-family/c.opt:1389 #: config/i386/i386.opt:967 -#, fuzzy -#| msgid "Deprecated in GCC 8. This switch has no effect." msgid "Deprecated in GCC 9. This switch has no effect." -msgstr "Obsoleto en GCC 8. Esta opción no tiene efecto." +msgstr "Obsoleto en GCC 9. Esta opción no tiene efecto." #: c-family/c.opt:429 msgid "Warn about variables that might be changed by \"longjmp\" or \"vfork\"." @@ -6655,7 +6607,7 @@ msgstr "Avisa cuando todos los constructores y destructores son privados." #: c-family/c.opt:461 msgid "Warn about dangling else." -msgstr "Avisa sobre else colgados." +msgstr "Avisa sobre else congante." #: c-family/c.opt:465 msgid "Warn about __TIME__, __DATE__ and __TIMESTAMP__ usage." @@ -6675,11 +6627,11 @@ msgstr "Avisa al borrar objetos polimórficos con destructores que no son virtua #: c-family/c.opt:485 msgid "Mark implicitly-declared copy operations as deprecated if the class has a user-provided copy operation." -msgstr "" +msgstr "Marca las operaciones de copia declaradas implícitamente como obsoletas si la clase tiene una operación de copia definida por el usuario." #: c-family/c.opt:490 msgid "Mark implicitly-declared copy operations as deprecated if the class has a user-provided copy operation or destructor." -msgstr "" +msgstr "Marca las operaciones de copia declaradas implícitamente como obsoletas si la clase tiene una operación de copia o un destructor definidos por el usuario." #: c-family/c.opt:495 msgid "Warn about positional initialization of structs requiring designated initializers." @@ -6755,7 +6707,7 @@ msgstr "Avisa sobre el uso de cadenas de formato que no son literales." #: c-family/c.opt:575 msgid "Warn about function calls with format strings that write past the end of the destination region. Same as -Wformat-overflow=1." -msgstr "" +msgstr "Advierte de llamadas a función con cadenas de formato que escriben más allá del final de la región de destino. Igual que -Wformat-overflow=1." #: c-family/c.opt:580 msgid "Warn about possible security problems with format functions." @@ -6767,7 +6719,7 @@ msgstr "Advierte de diferencias de signo en funciones de formato." #: c-family/c.opt:588 msgid "Warn about calls to snprintf and similar functions that truncate output. Same as -Wformat-truncation=1." -msgstr "" +msgstr "Advierte de llamadas a snprintf y funciones similares que truncan la salida. Igual que -Wformat-truncation=1." #: c-family/c.opt:593 msgid "Warn about strftime formats yielding 2-digit years." @@ -6803,7 +6755,7 @@ msgstr "Avisa cuando hay conversión entre punteros de tipos incompatibles." #: c-family/c.opt:630 msgid "Warn when the address of packed member of struct or union is taken." -msgstr "" +msgstr "Avisa cuando se toma la dirección del miembro empaquetado de una estructura o unión." #: c-family/c.opt:634 msgid "Warn about variables which are initialized to themselves." @@ -6811,7 +6763,7 @@ msgstr "Avisa sobre variables que se inicialicen ellas mismas." #: c-family/c.opt:638 msgid "Warn about uses of std::initializer_list that can result in dangling pointers." -msgstr "" +msgstr "Avisa sobre usos de std::initializer_list que pueden resultar en punteros " #: c-family/c.opt:642 msgid "Warn about implicit declarations." @@ -7018,14 +6970,12 @@ msgid "Warn when non-templatized friend functions are declared within a template msgstr "Avisa cuando las funciones friend sin plantillas se declaran dentro de una plantilla." #: c-family/c.opt:868 -#, fuzzy -#| msgid "conversion to void will never use a type conversion operator" msgid "Warn when a conversion function will never be called due to the type it converts to." -msgstr "la conversión a void nunca usará un operador de conversión de tipo" +msgstr "Avisa cuando una función de conversión nunca será llamada debido al tipo al que convierte." #: c-family/c.opt:872 msgid "Warn for unsafe raw memory writes to objects of class types." -msgstr "" +msgstr "Avisa en caso de escrituras de memoria en bruto no seguras a objetivos de tipos de clase." #: c-family/c.opt:876 msgid "Warn about non-virtual destructors." @@ -7272,14 +7222,12 @@ msgid "Warn if a variable length array is used." msgstr "Avisa si se usa una matriz de longitud variable." #: c-family/c.opt:1199 -#, fuzzy -#| msgid "-Wvla-larger-than=\tWarn on unbounded uses of variable-length arrays, and on bounded uses of variable-length arrays whose bound can be larger than bytes." msgid "-Wvla-larger-than=\tWarn on unbounded uses of variable-length arrays, and on bounded uses of variable-length arrays whose bound can be larger than bytes. bytes." -msgstr "-Wvla-larger-than=\tAdvierte de usos no acotados de arrays de longitud variable y de usos acotados de arrays de longitud variable cuyo límite pueda ser más grande que bytes." +msgstr "-Wvla-larger-than=\tAdvierte de usos no acotados de arrays de longitud variable y de usos acotados de arrays de longitud variable cuyo límite pueda ser más grande que bytes. bytes" #: c-family/c.opt:1206 msgid "-Wno-vla-larger-than Disable Wvla-larger-than= warning. Equivalent to Wvla-larger-than= or larger." -msgstr "" +msgstr "-Wno-vla-larger-than Desactiva el aviso Wvla-larger-than=. Equivalente a Wvla-larger-than= o mayor." #: c-family/c.opt:1210 msgid "Warn when a register variable is declared volatile." @@ -7391,10 +7339,8 @@ msgid "-fconstexpr-loop-limit=\tSpecify maximum constexpr loop iteration msgstr "-fconstexpr-loop-limit=\tEspecifica el número de iteraciones de bucle constexpr máximo." #: c-family/c.opt:1421 -#, fuzzy -#| msgid "-fconstexpr-loop-limit=\tSpecify maximum constexpr loop iteration count." msgid "-fconstexpr-ops-limit=\tSpecify maximum number of constexpr operations during a single constexpr evaluation." -msgstr "-fconstexpr-loop-limit=\tEspecifica el número de iteraciones de bucle constexpr máximo." +msgstr "-fconstexpr-ops-limit=\tEspecifica el número máximo de operaciones constexpr durante una evaluación de constexpr." #: c-family/c.opt:1425 msgid "Emit debug annotations during preprocessing." @@ -7830,16 +7776,12 @@ msgstr "Obsoleto en favor de -std=c11." #: c-family/c.opt:2017 c-family/c.opt:2021 c-family/c.opt:2139 #: c-family/c.opt:2143 -#, fuzzy -#| msgid "Conform to the ISO 2017 C standard (expected to be published in 2018)." msgid "Conform to the ISO 2017 C standard (published in 2018)." -msgstr "Conforma al estándar ISO 2017 C (publicación prevista en 2018)." +msgstr "Conforma al estándar ISO 2017 C (publicado en 2018)." #: c-family/c.opt:2025 -#, fuzzy -#| msgid "Conform to the ISO 2011 C standard (experimental and incomplete support)" msgid "Conform to the ISO 202X C standard draft (experimental and incomplete support)." -msgstr "Conforma al estándar ISO 2011 C (soporte experimental e incompleto)" +msgstr "Conforma al borrador del estándar ISO 202X C (soporte experimental e incompleto)" #: c-family/c.opt:2029 c-family/c.opt:2033 c-family/c.opt:2119 msgid "Conform to the ISO 1990 C standard." @@ -7894,16 +7836,12 @@ msgid "Deprecated in favor of -std=gnu11." msgstr "Obsoleto en favor de -std=gnu11." #: c-family/c.opt:2091 c-family/c.opt:2095 -#, fuzzy -#| msgid "Conform to the ISO 2017 C standard (expected to be published in 2018) with GNU extensions." msgid "Conform to the ISO 2017 C standard (published in 2018) with GNU extensions." -msgstr "Conforma al estándar ISO 2017 C (publicación prevista en 2018) con extensiones GNU." +msgstr "Conforma al estándar ISO 2017 C (publicado en 2018) con extensiones GNU." #: c-family/c.opt:2099 -#, fuzzy -#| msgid "Conform to the ISO 2011 C standard with GNU extensions (experimental and incomplete support)" msgid "Conform to the ISO 202X C standard draft with GNU extensions (experimental and incomplete support)." -msgstr "Conforma al estándar ISO 2011 C con extensiones GNU (soporte experimental e incompleto)" +msgstr "Conforma al borrador del estándar ISO 202X C con extensiones GNU (soporte experimental e incompleto)." #: c-family/c.opt:2103 c-family/c.opt:2107 msgid "Conform to the ISO 1990 C standard with GNU extensions." @@ -7980,44 +7918,36 @@ msgid "-Hf \tWrite D interface to ." msgstr "-o \tColoca la salida en el ." #: d/lang.opt:123 -#, fuzzy -#| msgid "Warn about casts which discard qualifiers." msgid "Warn about casts that will produce a null result." -msgstr "Avisa sobre conversiones que descartan calificadores." +msgstr "Avisa sobre conversiones que darán resultado nulo." #: d/lang.opt:139 msgid "Warn from speculative compiles such as __traits(compiles)." msgstr "" #: d/lang.opt:151 -#, fuzzy -#| msgid "Generate H8S code." msgid "Generate JSON file." -msgstr "Genera código H8S." +msgstr "Genera fichero JSON." #: d/lang.opt:155 -#, fuzzy -#| msgid "-MF \tWrite dependency output to the given file." msgid "-Xf \tWrite JSON output to the given ." -msgstr "-MF \tEscribe la salida de dependencias al fichero dado." +msgstr "-Xf \tEscribe salida JSON al dado." #: d/lang.opt:159 msgid "Debug library to use instead of phobos." -msgstr "" +msgstr "Biblioteca de depuración que se utilizará en lugar de phobos." #: d/lang.opt:163 msgid "Default library to use instead of phobos." -msgstr "" +msgstr "Biblioteca predefinida que se utilizará en lugar de phobos." #: d/lang.opt:167 msgid "Do link the standard D startup files in the compilation." msgstr "" #: d/lang.opt:174 -#, fuzzy -#| msgid "Generate code for built-in atomic operations." msgid "Generate code for all template instantiations." -msgstr "Genera código para operaciones atómicas internas." +msgstr "Genera código para todas las instanciaciones de plantillas." #: d/lang.opt:178 #, fuzzy @@ -8027,43 +7957,35 @@ msgstr "Genera código para el ensamblador de GNU (gas)." #: d/lang.opt:186 msgid "-fbounds-check=[on|safeonly|off]\tTurn array bounds checks on, in @safe code only, or off." -msgstr "" +msgstr "-fbounds-check=[on|safeonly|off]\tActiva o desactiva las comprobaciones de límites de matrices, solo en código @safe." #: d/lang.opt:210 -#, fuzzy -#| msgid "incompatible index mode" msgid "Compile in debug code." -msgstr "modo de índices incompatibles" +msgstr "Compila en código de depuración." #: d/lang.opt:214 msgid "-fdebug=\tCompile in debug code, code <= , or code identified by ." -msgstr "" +msgstr "-fdebug=\tCompila en código de depuración, código <= , o código identificado por ." #: d/lang.opt:218 -#, fuzzy -#| msgid "Generate norm instruction." msgid "Generate documentation." -msgstr "Genera instrucciones norm." +msgstr "Genera documentación." #: d/lang.opt:222 msgid "-fdoc-dir=\tWrite documentation file to directory ." -msgstr "" +msgstr "-fdoc-dir=\tEscribe el fichero de documentación en el directorio ." #: d/lang.opt:226 -#, fuzzy -#| msgid "-o \tPlace output into ." msgid "-fdoc-file=\tWrite documentation to ." -msgstr "-o \tColoca la salida en el ." +msgstr "-fdoc-file=\tEscribe la documentación en ." #: d/lang.opt:230 msgid "-fdoc-inc=\tInclude a Ddoc macro ." -msgstr "" +msgstr "-fdoc-inc=\tIncluye un de macros Ddoc." #: d/lang.opt:234 -#, fuzzy -#| msgid "Do not assume that standard C libraries and \"main\" exist." msgid "Assume that standard D runtime libraries and \"D main\" exist." -msgstr "No asume que existen las bibliotecas C estándar y \"main\"." +msgstr "Asume que existen bibliotecas D estándar de tiempo de ejecución y \"D main\"." #: d/lang.opt:238 #, fuzzy @@ -8073,7 +7995,7 @@ msgstr "Muestra el árbol del código después de analizar; opción obsoleta." #: d/lang.opt:242 msgid "Ignore unsupported pragmas." -msgstr "" +msgstr "Hace caso omiso de pragmas no admitidas." #: d/lang.opt:246 #, fuzzy @@ -8083,11 +8005,11 @@ msgstr "Genera código para operaciones atómicas internas." #: d/lang.opt:250 msgid "Generate a default D main() function when compiling." -msgstr "" +msgstr "Genera una función main() de D predefinida al compilar." #: d/lang.opt:254 msgid "-fmodule-file==\tuse as source file for ." -msgstr "" +msgstr "-fmodule-file==\tutiliza como fichero fuente para ." #: d/lang.opt:258 #, fuzzy -- cgit v1.1 From ad527d801855d7992e25b1548628566eefcf69e9 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Sat, 31 Aug 2019 18:09:47 -0400 Subject: Add source location to TRAIT_EXPR. Since TRAIT_EXPR is exceptional, maybe_wrap_with_location won't wrap it, so we need to put its location in the TRAIT_EXPR node itself. * cp-tree.h (TRAIT_EXPR_LOCATION): New. (struct tree_trait_expr): Add locus field. * parser.c (cp_parser_trait_expr): Pass trait_loc down. * pt.c (tsubst_copy_and_build) [TRAIT_EXPR]: Likewise. * semantics.c (finish_trait_expr): Add location parm. * tree.c (cp_expr_location): Handle TRAIT_EXPR. From-SVN: r275260 --- gcc/cp/ChangeLog | 10 ++++++++++ gcc/cp/cp-tree.h | 6 +++++- gcc/cp/parser.c | 2 +- gcc/cp/pt.c | 3 ++- gcc/cp/semantics.c | 8 +++++--- gcc/cp/tree.c | 2 ++ gcc/testsuite/g++.dg/ext/is_class_error3.C | 2 ++ 7 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/is_class_error3.C (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 37de3d9..9725dda 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2019-08-30 Jason Merrill + + Add source location to TRAIT_EXPR. + * cp-tree.h (TRAIT_EXPR_LOCATION): New. + (struct tree_trait_expr): Add locus field. + * parser.c (cp_parser_trait_expr): Pass trait_loc down. + * pt.c (tsubst_copy_and_build) [TRAIT_EXPR]: Likewise. + * semantics.c (finish_trait_expr): Add location parm. + * tree.c (cp_expr_location): Handle TRAIT_EXPR. + 2019-08-29 Paolo Carlini * decl.c (check_var_type): Add location_t parameter and use it. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 3c69e54..12eb39a 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1295,10 +1295,14 @@ enum cp_trait_kind #define TRAIT_EXPR_KIND(NODE) \ (((struct tree_trait_expr *)TRAIT_EXPR_CHECK (NODE))->kind) +#define TRAIT_EXPR_LOCATION(NODE) \ + (((struct tree_trait_expr *)TRAIT_EXPR_CHECK (NODE))->locus) + struct GTY (()) tree_trait_expr { struct tree_common common; tree type1; tree type2; + location_t locus; enum cp_trait_kind kind; }; @@ -7174,7 +7178,7 @@ extern tree baselink_for_fns (tree); extern void finish_static_assert (tree, tree, location_t, bool); extern tree finish_decltype_type (tree, bool, tsubst_flags_t); -extern tree finish_trait_expr (enum cp_trait_kind, tree, tree); +extern tree finish_trait_expr (location_t, enum cp_trait_kind, tree, tree); extern tree build_lambda_expr (void); extern tree build_lambda_object (tree); extern tree begin_lambda_type (tree); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 93cdadd..baa60b8 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -10396,7 +10396,7 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword) case CPTK_DIRECT_BASES: return cp_expr (finish_bases (type1, true), trait_loc); default: - return cp_expr (finish_trait_expr (kind, type1, type2), trait_loc); + return finish_trait_expr (trait_loc, kind, type1, type2); } } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 13d3db9..187f9d85 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -19536,7 +19536,8 @@ tsubst_copy_and_build (tree t, else if (type2) type2 = tsubst (type2, args, complain, in_decl); - RETURN (finish_trait_expr (TRAIT_EXPR_KIND (t), type1, type2)); + RETURN (finish_trait_expr (TRAIT_EXPR_LOCATION (t), + TRAIT_EXPR_KIND (t), type1, type2)); } case STMT_EXPR: diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index b61d86f..56f70a0 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -9921,7 +9921,7 @@ check_trait_type (tree type) /* Process a trait expression. */ tree -finish_trait_expr (cp_trait_kind kind, tree type1, tree type2) +finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2) { if (type1 == error_mark_node || type2 == error_mark_node) @@ -9934,6 +9934,7 @@ finish_trait_expr (cp_trait_kind kind, tree type1, tree type2) TRAIT_EXPR_TYPE1 (trait_expr) = type1; TRAIT_EXPR_TYPE2 (trait_expr) = type2; TRAIT_EXPR_KIND (trait_expr) = kind; + TRAIT_EXPR_LOCATION (trait_expr) = loc; return trait_expr; } @@ -9991,8 +9992,9 @@ finish_trait_expr (cp_trait_kind kind, tree type1, tree type2) gcc_unreachable (); } - return (trait_expr_value (kind, type1, type2) - ? boolean_true_node : boolean_false_node); +tree val = (trait_expr_value (kind, type1, type2) + ? boolean_true_node : boolean_false_node); + return maybe_wrap_with_location (val, loc); } /* Do-nothing variants of functions to handle pragma FLOAT_CONST_DECIMAL64, diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 17a4df3..7f71891 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -5500,6 +5500,8 @@ cp_expr_location (const_tree t_) return LAMBDA_EXPR_LOCATION (t); case STATIC_ASSERT: return STATIC_ASSERT_SOURCE_LOCATION (t); + case TRAIT_EXPR: + return TRAIT_EXPR_LOCATION (t); default: return EXPR_LOCATION (t); } diff --git a/gcc/testsuite/g++.dg/ext/is_class_error3.C b/gcc/testsuite/g++.dg/ext/is_class_error3.C new file mode 100644 index 0000000..a3c16a4 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/is_class_error3.C @@ -0,0 +1,2 @@ +struct A {}; +void *p = __is_class (A); // { dg-error "11:cannot convert" } -- cgit v1.1 From 7a9f7e59dd38aff632c9c46234454a4f4b863357 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sun, 1 Sep 2019 00:16:48 +0000 Subject: Daily bump. From-SVN: r275264 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index dcfd94e..de7aab4 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20190831 +20190901 -- cgit v1.1 From 12b19f6aaf6a93be0bdc80e3d17540b94c58e157 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Sun, 1 Sep 2019 10:40:52 +0000 Subject: Fix wrong dates in ChangeLog From-SVN: r275265 --- gcc/ChangeLog | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 49c371b..2599314 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -171,7 +171,7 @@ * config/i386/i386-features.c (convert_scalars_to_vector): Do not add the MD problem. -2019-09-28 Bernd Edlinger +2019-08-28 Bernd Edlinger Richard Biener * expr.c (expand_assignment): Handle misaligned DECLs. @@ -2861,12 +2861,12 @@ * config/i386/mmx.md (usadv8qi): Use register_operand instead of vector_operand. -2019-09-09 Vladimir Makarov +2019-08-09 Vladimir Makarov * reload1.c (finish_spills): Do not check ira_conflicts_p when handling spilled pseudos. -2019-09-09 Richard Earnshaw +2019-08-09 Richard Earnshaw PR target/91386 * config/aarch64/aarch64.c (aarch64_gen_adjusted_ldpstp): Use copy_rtx -- cgit v1.1 From d1e2e50a5f4d077eab6d3c93047203d15f16b324 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sun, 1 Sep 2019 13:56:13 +0200 Subject: =?UTF-8?q?re=20PR=20lto/91572=20(lto1:=20error:=20type=20variant?= =?UTF-8?q?=20has=20different=20=E2=80=98TREE=5FTYPE=E2=80=99=20since=20r2?= =?UTF-8?q?69862)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR lto/91572 * tree.c (find_decls_types_in_node): Also walk TREE_PURPOSE of GIMPLE_ASM TREE_LIST operands. * g++.dg/lto/pr91572_0.C: New test. From-SVN: r275266 --- gcc/ChangeLog | 6 ++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/lto/pr91572_0.C | 12 ++++++++++++ gcc/tree.c | 7 +++++++ 4 files changed, 30 insertions(+) create mode 100644 gcc/testsuite/g++.dg/lto/pr91572_0.C (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2599314..d684c76 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-09-01 Jakub Jelinek + + PR lto/91572 + * tree.c (find_decls_types_in_node): Also walk TREE_PURPOSE of + GIMPLE_ASM TREE_LIST operands. + 2019-08-31 Gerald Pfeifer * doc/generic.texi (Unary and Binary Expressions): Mark up diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c590b46..acb729d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-01 Jakub Jelinek + + PR lto/91572 + * g++.dg/lto/pr91572_0.C: New test. + 2019-08-30 Steven G. Kargl PR fortran/91587 diff --git a/gcc/testsuite/g++.dg/lto/pr91572_0.C b/gcc/testsuite/g++.dg/lto/pr91572_0.C new file mode 100644 index 0000000..95a7e9f --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/pr91572_0.C @@ -0,0 +1,12 @@ +// PR lto/91572 +// { dg-lto-do link } +// { dg-lto-options { { -O -fPIC -flto } } } +// { dg-require-effective-target shared } +// { dg-require-effective-target fpic } +// { dg-extra-ld-options "-shared" } + +void foo (char); +namespace N { + class A { A (); }; + A::A () { asm ("" : : "g" (0)); } +} diff --git a/gcc/tree.c b/gcc/tree.c index 613efa5..afd7020 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -6142,6 +6142,13 @@ find_decls_types_in_node (struct cgraph_node *n, class free_lang_data_d *fld) { tree arg = gimple_op (stmt, i); find_decls_types (arg, fld); + /* find_decls_types doesn't walk TREE_PURPOSE of TREE_LISTs, + which we need for asm stmts. */ + if (arg + && TREE_CODE (arg) == TREE_LIST + && TREE_PURPOSE (arg) + && gimple_code (stmt) == GIMPLE_ASM) + find_decls_types (TREE_PURPOSE (arg), fld); } } } -- cgit v1.1 From 9151048d854e352a9b83b771c6711b8221c73f7e Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sun, 1 Sep 2019 13:57:10 +0200 Subject: re PR middle-end/91623 (-msse4.1 -O3 segfault in /usr/lib/gcc/x86_64-pc-linux-gnu/8.3.0/include/smmintrin.h:270:10) PR middle-end/91623 * optabs.c (expand_vec_cond_expr): If op0 is a VECTOR_CST and only EQ_EXPR/NE_EXPR is supported, verify that op0 only contains zeros or negative elements and use NE_EXPR instead of LT_EXPR against zero vector. * gcc.target/i386/pr91623.c: New test. From-SVN: r275267 --- gcc/ChangeLog | 6 ++++++ gcc/optabs.c | 19 +++++++++++++++++++ gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/gcc.target/i386/pr91623.c | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 gcc/testsuite/gcc.target/i386/pr91623.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d684c76..6c43782 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2019-09-01 Jakub Jelinek + PR middle-end/91623 + * optabs.c (expand_vec_cond_expr): If op0 is a VECTOR_CST and only + EQ_EXPR/NE_EXPR is supported, verify that op0 only contains + zeros or negative elements and use NE_EXPR instead of LT_EXPR against + zero vector. + PR lto/91572 * tree.c (find_decls_types_in_node): Also walk TREE_PURPOSE of GIMPLE_ASM TREE_LIST operands. diff --git a/gcc/optabs.c b/gcc/optabs.c index 9e54dda..cdd07f3 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -5868,6 +5868,25 @@ expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2, icode = get_vcond_icode (mode, cmp_op_mode, unsignedp); if (icode == CODE_FOR_nothing) { + if (tcode == LT_EXPR + && op0a == op0 + && TREE_CODE (op0) == VECTOR_CST) + { + /* A VEC_COND_EXPR condition could be folded from EQ_EXPR/NE_EXPR + into a constant when only get_vcond_eq_icode is supported. + Verify < 0 and != 0 behave the same and change it to NE_EXPR. */ + unsigned HOST_WIDE_INT nelts; + if (!VECTOR_CST_NELTS (op0).is_constant (&nelts)) + { + if (VECTOR_CST_STEPPED_P (op0)) + return 0; + nelts = vector_cst_encoded_nelts (op0); + } + for (unsigned int i = 0; i < nelts; ++i) + if (tree_int_cst_sgn (vector_cst_elt (op0, i)) == 1) + return 0; + tcode = NE_EXPR; + } if (tcode == EQ_EXPR || tcode == NE_EXPR) icode = get_vcond_eq_icode (mode, cmp_op_mode); if (icode == CODE_FOR_nothing) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index acb729d..aa73312 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2019-09-01 Jakub Jelinek + PR middle-end/91623 + * gcc.target/i386/pr91623.c: New test. + PR lto/91572 * g++.dg/lto/pr91572_0.C: New test. diff --git a/gcc/testsuite/gcc.target/i386/pr91623.c b/gcc/testsuite/gcc.target/i386/pr91623.c new file mode 100644 index 0000000..94de4f9 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr91623.c @@ -0,0 +1,32 @@ +/* PR middle-end/91623 */ +/* { dg-do compile } */ +/* { dg-options "-O3 -msse4.1 -mno-sse4.2" } */ + +typedef long long V __attribute__((__vector_size__(16))); +V e, h; +int d; +const int i; + +void foo (void); + +void +bar (int k, int l) +{ + if (d && 0 <= k - 1 && l) + foo (); +} + +void +baz (void) +{ + V n = (V) { 1 }; + V g = (V) {}; + V o = g; + for (int f = 0; f < i; ++f) + { + V a = o == n; + h = a; + bar (f, i); + o = e; + } +} -- cgit v1.1 From 70570ec1927450952efc5baa4de3254507352f09 Mon Sep 17 00:00:00 2001 From: Paul Thomas Date: Sun, 1 Sep 2019 12:53:02 +0000 Subject: array.c (spec_dimen_size): Check for the presence of expressions for the bounds. 2019-09-01 Paul Thomas * array.c (spec_dimen_size): Check for the presence of expressions for the bounds. * decl.c (gfc_match_end): Add case COMP_SELECT_RANK. * dump-parse-tree.c(show_symbol): Show the arrayspec of class entities. (show_code_node): Show the code for SELECT_RANK. * expr.c (gfc_check_vardef_context): Omit the context of variable definition for select rank associate names since the ASSUMED RANK throws. * gfortran.h : Add ST_SELECT_RANK and ST_RANK to enum gfc_statement. Add select_rank_temporary to symbol attribute structure. Add EXEC_SELECT_RANK to enum gfc_exec_op. * match.c (match_exit_cycle): Add COMP_SELECT_RANK. (copy_ts_from_selector_to_associate): Add as special case for assumed rank class variables. (select_intrinsic_set_tmp): Clean up the code by using symbols for references to the temporary and the selector. (select_type_set_tmp): Ditto. (select_rank_set_tmp): New function. (gfc_match_select_rank): New function. (gfc_match_rank_is): New function. * match.h : Add prototypes for gfc_match_select_rank and gfc_match_rank_is. * parse.c (decode_statement): Attempt to match select_rank and rank statements. (next_statement, gfc_ascii_statement): Add ST_SELECT_RANK. (parse_select_rank_block): New function. (parse_executable): Parse select rank block for ST_SELECT_RANK. * parse.h : Add COMP_SELECT_RANK to enum gfc_compile_state. * resolve.c (resolve_variable): Exclude select_rank_temporaries from the check on use of ASSUMED RANK. (gfc_resolve_expr): Make sure that unlimited polymorphic select rank temporaries expressions are not resolved again after being successfully resolved. (resolve_assoc_var): Do not do the rank check for select rank temporaries. (resolve_select_rank): New function. (gfc_resolve_blocks): Deal with case EXEC_SELECT_RANK. (resolve_symbol): Exclude select rank temporaries for check on use of ASSUMED RANK. * st.c (gfc_free_statement): Include EXEC_SELECT_RANK. * trans-array.c (gfc_conv_array_ref): Select rank temporaries may have dimen == 0. (gfc_conv_expr_descriptor): Zero the offset of select rank temporaries. * trans-stmt.c (copy_descriptor): New function. (trans_associate_var): Add code to associate select rank temps. (gfc_trans_select_rank_cases): New function. (gfc_trans_select_rank): New function. * trans-stmt.h : Add prototype for gfc_trans_select_rank. trans.c (trans_code): Add select rank case. 2019-09-01 Paul Thomas * gfortran.dg/select_rank_1.f90 : New test. * gfortran.dg/select_rank_2.f90 : New test. From-SVN: r275269 --- gcc/fortran/ChangeLog | 56 +++- gcc/fortran/array.c | 6 +- gcc/fortran/decl.c | 1 + gcc/fortran/dump-parse-tree.c | 20 +- gcc/fortran/expr.c | 2 +- gcc/fortran/gfortran.h | 12 +- gcc/fortran/match.c | 427 +++++++++++++++++++++++++--- gcc/fortran/match.h | 2 + gcc/fortran/parse.c | 95 ++++++- gcc/fortran/parse.h | 3 +- gcc/fortran/resolve.c | 210 +++++++++++++- gcc/fortran/st.c | 1 + gcc/fortran/trans-array.c | 8 +- gcc/fortran/trans-stmt.c | 315 +++++++++++++++++++- gcc/fortran/trans-stmt.h | 1 + gcc/fortran/trans.c | 4 + gcc/testsuite/ChangeLog | 5 + gcc/testsuite/gfortran.dg/select_rank_1.f90 | 179 ++++++++++++ gcc/testsuite/gfortran.dg/select_rank_2.f90 | 85 ++++++ 19 files changed, 1355 insertions(+), 77 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/select_rank_1.f90 create mode 100644 gcc/testsuite/gfortran.dg/select_rank_2.f90 (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index a34b871..0ed86ce 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,57 @@ +2019-09-01 Paul Thomas + + * array.c (spec_dimen_size): Check for the presence of + expressions for the bounds. + * decl.c (gfc_match_end): Add case COMP_SELECT_RANK. + * dump-parse-tree.c(show_symbol): Show the arrayspec of class + entities. + (show_code_node): Show the code for SELECT_RANK. + * expr.c (gfc_check_vardef_context): Omit the context of + variable definition for select rank associate names since the + ASSUMED RANK throws. + * gfortran.h : Add ST_SELECT_RANK and ST_RANK to enum + gfc_statement. Add select_rank_temporary to symbol attribute + structure. Add EXEC_SELECT_RANK to enum gfc_exec_op. + * match.c (match_exit_cycle): Add COMP_SELECT_RANK. + (copy_ts_from_selector_to_associate): Add as special case for + assumed rank class variables. + (select_intrinsic_set_tmp): Clean up the code by using symbols + for references to the temporary and the selector. + (select_type_set_tmp): Ditto. + (select_rank_set_tmp): New function. + (gfc_match_select_rank): New function. + (gfc_match_rank_is): New function. + * match.h : Add prototypes for gfc_match_select_rank and + gfc_match_rank_is. + * parse.c (decode_statement): Attempt to match select_rank and + rank statements. + (next_statement, gfc_ascii_statement): Add ST_SELECT_RANK. + (parse_select_rank_block): New function. + (parse_executable): Parse select rank block for ST_SELECT_RANK. + * parse.h : Add COMP_SELECT_RANK to enum gfc_compile_state. + * resolve.c (resolve_variable): Exclude select_rank_temporaries + from the check on use of ASSUMED RANK. + (gfc_resolve_expr): Make sure that unlimited polymorphic select + rank temporaries expressions are not resolved again after being + successfully resolved. + (resolve_assoc_var): Do not do the rank check for select rank + temporaries. + (resolve_select_rank): New function. + (gfc_resolve_blocks): Deal with case EXEC_SELECT_RANK. + (resolve_symbol): Exclude select rank temporaries for check on + use of ASSUMED RANK. + * st.c (gfc_free_statement): Include EXEC_SELECT_RANK. + * trans-array.c (gfc_conv_array_ref): Select rank temporaries + may have dimen == 0. + (gfc_conv_expr_descriptor): Zero the offset of select rank + temporaries. + * trans-stmt.c (copy_descriptor): New function. + (trans_associate_var): Add code to associate select rank temps. + (gfc_trans_select_rank_cases): New function. + (gfc_trans_select_rank): New function. + * trans-stmt.h : Add prototype for gfc_trans_select_rank. + trans.c (trans_code): Add select rank case. + 2019-08-30 Steven G. Kargl PR fortran/91587 @@ -49,7 +103,7 @@ 2019-08-27 Mark Eggleston * invoke.texi: Ensure that the option lists fit within the - margins of a PDF page. Re-worded description of + margins of a PDF page. Re-worded description of '-ffrontend-loop-interchange' so that it fits with the margins of a PDF page. Add '-fdec-include', '-fdec-blank-format-item' and '-fdec-format-defaults' to list of options that are enabled diff --git a/gcc/fortran/array.c b/gcc/fortran/array.c index b958e89..b972abe 100644 --- a/gcc/fortran/array.c +++ b/gcc/fortran/array.c @@ -2213,7 +2213,11 @@ spec_dimen_size (gfc_array_spec *as, int dimen, mpz_t *result) gfc_internal_error ("spec_dimen_size(): Bad dimension"); if (as->type != AS_EXPLICIT - || as->lower[dimen]->expr_type != EXPR_CONSTANT + || !as->lower[dimen] + || !as->upper[dimen]) + return false; + + if (as->lower[dimen]->expr_type != EXPR_CONSTANT || as->upper[dimen]->expr_type != EXPR_CONSTANT || as->lower[dimen]->ts.type != BT_INTEGER || as->upper[dimen]->ts.type != BT_INTEGER) diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c index d5c8c33..0711191 100644 --- a/gcc/fortran/decl.c +++ b/gcc/fortran/decl.c @@ -8164,6 +8164,7 @@ gfc_match_end (gfc_statement *st) case COMP_SELECT: case COMP_SELECT_TYPE: + case COMP_SELECT_RANK: *st = ST_END_SELECT; target = " select"; eos_ok = 0; diff --git a/gcc/fortran/dump-parse-tree.c b/gcc/fortran/dump-parse-tree.c index 798519f..513f211 100644 --- a/gcc/fortran/dump-parse-tree.c +++ b/gcc/fortran/dump-parse-tree.c @@ -1000,12 +1000,18 @@ show_symbol (gfc_symbol *sym) show_expr (sym->value); } - if (sym->as) + if (sym->ts.type != BT_CLASS && sym->as) { show_indent (); fputs ("Array spec:", dumpfile); show_array_spec (sym->as); } + else if (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->as) + { + show_indent (); + fputs ("Array spec:", dumpfile); + show_array_spec (CLASS_DATA (sym)->as); + } if (sym->generic) { @@ -2168,18 +2174,22 @@ show_code_node (int level, gfc_code *c) case EXEC_SELECT: case EXEC_SELECT_TYPE: + case EXEC_SELECT_RANK: d = c->block; - if (c->op == EXEC_SELECT_TYPE) + fputc ('\n', dumpfile); + code_indent (level, 0); + if (c->op == EXEC_SELECT_RANK) + fputs ("SELECT RANK ", dumpfile); + else if (c->op == EXEC_SELECT_TYPE) fputs ("SELECT TYPE ", dumpfile); else fputs ("SELECT CASE ", dumpfile); show_expr (c->expr1); - fputc ('\n', dumpfile); for (; d; d = d->block) { + fputc ('\n', dumpfile); code_indent (level, 0); - fputs ("CASE ", dumpfile); for (cp = d->ext.block.case_list; cp; cp = cp->next) { @@ -2190,9 +2200,9 @@ show_code_node (int level, gfc_code *c) fputc (')', dumpfile); fputc (' ', dumpfile); } - fputc ('\n', dumpfile); show_code (level + 1, d->next); + fputc ('\n', dumpfile); } code_indent (level, c->label1); diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c index 4516094..c6d17d6 100644 --- a/gcc/fortran/expr.c +++ b/gcc/fortran/expr.c @@ -6181,7 +6181,7 @@ gfc_check_vardef_context (gfc_expr* e, bool pointer, bool alloc_obj, } } /* Check variable definition context for associate-names. */ - if (!pointer && sym->assoc) + if (!pointer && sym->assoc && !sym->attr.select_rank_temporary) { const char* name; gfc_association_list* assoc; diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index d2f40df..80e31ee 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -216,7 +216,7 @@ enum gfc_statement ST_POINTER_ASSIGNMENT, ST_SELECT_CASE, ST_SEQUENCE, ST_SIMPLE_IF, ST_STATEMENT_FUNCTION, ST_DERIVED_DECL, ST_LABEL_ASSIGNMENT, ST_ENUM, ST_ENUMERATOR, ST_END_ENUM, ST_SELECT_TYPE, ST_TYPE_IS, ST_CLASS_IS, - ST_STRUCTURE_DECL, ST_END_STRUCTURE, + ST_SELECT_RANK, ST_RANK, ST_STRUCTURE_DECL, ST_END_STRUCTURE, ST_UNION, ST_END_UNION, ST_MAP, ST_END_MAP, ST_OACC_PARALLEL_LOOP, ST_OACC_END_PARALLEL_LOOP, ST_OACC_PARALLEL, ST_OACC_END_PARALLEL, ST_OACC_KERNELS, ST_OACC_END_KERNELS, ST_OACC_DATA, @@ -894,9 +894,9 @@ typedef struct event_comp:1, defined_assign_comp:1, unlimited_polymorphic:1, has_dtio_procs:1, caf_token:1; - /* This is a temporary selector for SELECT TYPE or an associate - variable for SELECT_TYPE or ASSOCIATE. */ - unsigned select_type_temporary:1, associate_var:1; + /* This is a temporary selector for SELECT TYPE/RANK or an associate + variable for SELECT TYPE/RANK or ASSOCIATE. */ + unsigned select_type_temporary:1, select_rank_temporary:1, associate_var:1; /* These are the attributes required for parameterized derived types. */ @@ -2555,8 +2555,8 @@ enum gfc_exec_op EXEC_IF, EXEC_ARITHMETIC_IF, EXEC_DO, EXEC_DO_CONCURRENT, EXEC_DO_WHILE, EXEC_SELECT, EXEC_BLOCK, EXEC_FORALL, EXEC_WHERE, EXEC_CYCLE, EXEC_EXIT, EXEC_CALL_PPC, EXEC_ALLOCATE, EXEC_DEALLOCATE, EXEC_END_PROCEDURE, - EXEC_SELECT_TYPE, EXEC_SYNC_ALL, EXEC_SYNC_MEMORY, EXEC_SYNC_IMAGES, - EXEC_OPEN, EXEC_CLOSE, EXEC_WAIT, + EXEC_SELECT_TYPE, EXEC_SELECT_RANK, EXEC_SYNC_ALL, EXEC_SYNC_MEMORY, + EXEC_SYNC_IMAGES, EXEC_OPEN, EXEC_CLOSE, EXEC_WAIT, EXEC_READ, EXEC_WRITE, EXEC_IOLENGTH, EXEC_TRANSFER, EXEC_DT_END, EXEC_BACKSPACE, EXEC_ENDFILE, EXEC_INQUIRE, EXEC_REWIND, EXEC_FLUSH, EXEC_FORM_TEAM, EXEC_CHANGE_TEAM, EXEC_END_TEAM, EXEC_SYNC_TEAM, diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c index f148a02..56d9af0 100644 --- a/gcc/fortran/match.c +++ b/gcc/fortran/match.c @@ -2825,6 +2825,7 @@ match_exit_cycle (gfc_statement st, gfc_exec_op op) case COMP_IF: case COMP_SELECT: case COMP_SELECT_TYPE: + case COMP_SELECT_RANK: gcc_assert (sym); if (op == EXEC_CYCLE) { @@ -6065,7 +6066,14 @@ copy_ts_from_selector_to_associate (gfc_expr *associate, gfc_expr *selector) ref = ref->next; if (selector->ts.type == BT_CLASS && CLASS_DATA (selector)->as - && ref && ref->type == REF_ARRAY) + && CLASS_DATA (selector)->as->type == AS_ASSUMED_RANK) + { + assoc_sym->attr.dimension = 1; + assoc_sym->as = gfc_copy_array_spec (CLASS_DATA (selector)->as); + goto build_class_sym; + } + else if (selector->ts.type == BT_CLASS && CLASS_DATA (selector)->as + && ref && ref->type == REF_ARRAY) { /* Ensure that the array reference type is set. We cannot use gfc_resolve_expr at this point, so the usable parts of @@ -6116,6 +6124,7 @@ copy_ts_from_selector_to_associate (gfc_expr *associate, gfc_expr *selector) else assoc_sym->as = NULL; +build_class_sym: if (selector->ts.type == BT_CLASS) { /* The correct class container has to be available. */ @@ -6149,14 +6158,17 @@ select_intrinsic_set_tmp (gfc_typespec *ts) char name[GFC_MAX_SYMBOL_LEN]; gfc_symtree *tmp; HOST_WIDE_INT charlen = 0; + gfc_symbol *selector = select_type_stack->selector; + gfc_symbol *sym; if (ts->type == BT_CLASS || ts->type == BT_DERIVED) return NULL; - if (select_type_stack->selector->ts.type == BT_CLASS - && !select_type_stack->selector->attr.class_ok) + if (selector->ts.type == BT_CLASS && !selector->attr.class_ok) return NULL; + /* Case value == NULL corresponds to SELECT TYPE cases otherwise + the values correspond to SELECT rank cases. */ if (ts->type == BT_CHARACTER && ts->u.cl && ts->u.cl->length && ts->u.cl->length->expr_type == EXPR_CONSTANT) charlen = gfc_mpz_get_hwi (ts->u.cl->length->value.integer); @@ -6165,29 +6177,28 @@ select_intrinsic_set_tmp (gfc_typespec *ts) sprintf (name, "__tmp_%s_%d", gfc_basic_typename (ts->type), ts->kind); else - snprintf (name, sizeof (name), "__tmp_%s_" HOST_WIDE_INT_PRINT_DEC "_%d", + snprintf (name, sizeof (name), + "__tmp_%s_" HOST_WIDE_INT_PRINT_DEC "_%d", gfc_basic_typename (ts->type), charlen, ts->kind); gfc_get_sym_tree (name, gfc_current_ns, &tmp, false); - gfc_add_type (tmp->n.sym, ts, NULL); + sym = tmp->n.sym; + gfc_add_type (sym, ts, NULL); /* Copy across the array spec to the selector. */ - if (select_type_stack->selector->ts.type == BT_CLASS - && (CLASS_DATA (select_type_stack->selector)->attr.dimension - || CLASS_DATA (select_type_stack->selector)->attr.codimension)) + if (selector->ts.type == BT_CLASS + && (CLASS_DATA (selector)->attr.dimension + || CLASS_DATA (selector)->attr.codimension)) { - tmp->n.sym->attr.pointer = 1; - tmp->n.sym->attr.dimension - = CLASS_DATA (select_type_stack->selector)->attr.dimension; - tmp->n.sym->attr.codimension - = CLASS_DATA (select_type_stack->selector)->attr.codimension; - tmp->n.sym->as - = gfc_copy_array_spec (CLASS_DATA (select_type_stack->selector)->as); + sym->attr.pointer = 1; + sym->attr.dimension = CLASS_DATA (selector)->attr.dimension; + sym->attr.codimension = CLASS_DATA (selector)->attr.codimension; + sym->as = gfc_copy_array_spec (CLASS_DATA (selector)->as); } - gfc_set_sym_referenced (tmp->n.sym); - gfc_add_flavor (&tmp->n.sym->attr, FL_VARIABLE, name, NULL); - tmp->n.sym->attr.select_type_temporary = 1; + gfc_set_sym_referenced (sym); + gfc_add_flavor (&sym->attr, FL_VARIABLE, name, NULL); + sym->attr.select_type_temporary = 1; return tmp; } @@ -6200,6 +6211,8 @@ select_type_set_tmp (gfc_typespec *ts) { char name[GFC_MAX_SYMBOL_LEN]; gfc_symtree *tmp = NULL; + gfc_symbol *selector = select_type_stack->selector; + gfc_symbol *sym; if (!ts) { @@ -6218,42 +6231,45 @@ select_type_set_tmp (gfc_typespec *ts) sprintf (name, "__tmp_class_%s", ts->u.derived->name); else sprintf (name, "__tmp_type_%s", ts->u.derived->name); + gfc_get_sym_tree (name, gfc_current_ns, &tmp, false); - gfc_add_type (tmp->n.sym, ts, NULL); + sym = tmp->n.sym; + gfc_add_type (sym, ts, NULL); - if (select_type_stack->selector->ts.type == BT_CLASS - && select_type_stack->selector->attr.class_ok) + if (selector->ts.type == BT_CLASS && selector->attr.class_ok) { - tmp->n.sym->attr.pointer - = CLASS_DATA (select_type_stack->selector)->attr.class_pointer; + sym->attr.pointer + = CLASS_DATA (selector)->attr.class_pointer; /* Copy across the array spec to the selector. */ - if (CLASS_DATA (select_type_stack->selector)->attr.dimension - || CLASS_DATA (select_type_stack->selector)->attr.codimension) + if (CLASS_DATA (selector)->attr.dimension + || CLASS_DATA (selector)->attr.codimension) { - tmp->n.sym->attr.dimension - = CLASS_DATA (select_type_stack->selector)->attr.dimension; - tmp->n.sym->attr.codimension - = CLASS_DATA (select_type_stack->selector)->attr.codimension; - tmp->n.sym->as - = gfc_copy_array_spec (CLASS_DATA (select_type_stack->selector)->as); + sym->attr.dimension + = CLASS_DATA (selector)->attr.dimension; + sym->attr.codimension + = CLASS_DATA (selector)->attr.codimension; + sym->as + = gfc_copy_array_spec (CLASS_DATA (selector)->as); } - } + } - gfc_set_sym_referenced (tmp->n.sym); - gfc_add_flavor (&tmp->n.sym->attr, FL_VARIABLE, name, NULL); - tmp->n.sym->attr.select_type_temporary = 1; + gfc_set_sym_referenced (sym); + gfc_add_flavor (&sym->attr, FL_VARIABLE, name, NULL); + sym->attr.select_type_temporary = 1; - if (ts->type == BT_CLASS) - gfc_build_class_symbol (&tmp->n.sym->ts, &tmp->n.sym->attr, - &tmp->n.sym->as); + if (ts->type == BT_CLASS) + gfc_build_class_symbol (&sym->ts, &sym->attr, &sym->as); } + else + sym = tmp->n.sym; + /* Add an association for it, so the rest of the parser knows it is an associate-name. The target will be set during resolution. */ - tmp->n.sym->assoc = gfc_get_association_list (); - tmp->n.sym->assoc->dangling = 1; - tmp->n.sym->assoc->st = tmp; + sym->assoc = gfc_get_association_list (); + sym->assoc->dangling = 1; + sym->assoc->st = tmp; select_type_stack->tmp = tmp; } @@ -6374,6 +6390,234 @@ cleanup: } +/* Set the temporary for the current intrinsic SELECT RANK selector. */ + +static void +select_rank_set_tmp (gfc_typespec *ts, int *case_value) +{ + char name[2 * GFC_MAX_SYMBOL_LEN]; + char tname[GFC_MAX_SYMBOL_LEN]; + gfc_symtree *tmp; + gfc_symbol *selector = select_type_stack->selector; + gfc_symbol *sym; + gfc_symtree *st; + HOST_WIDE_INT charlen = 0; + + if (case_value == NULL) + return; + + if (ts->type == BT_CHARACTER && ts->u.cl && ts->u.cl->length + && ts->u.cl->length->expr_type == EXPR_CONSTANT) + charlen = gfc_mpz_get_hwi (ts->u.cl->length->value.integer); + + if (ts->type == BT_CLASS) + sprintf (tname, "class_%s", ts->u.derived->name); + else if (ts->type == BT_DERIVED) + sprintf (tname, "type_%s", ts->u.derived->name); + else if (ts->type != BT_CHARACTER) + sprintf (tname, "%s_%d", gfc_basic_typename (ts->type), ts->kind); + else + sprintf (tname, "%s_" HOST_WIDE_INT_PRINT_DEC "_%d", + gfc_basic_typename (ts->type), charlen, ts->kind); + + /* Case value == NULL corresponds to SELECT TYPE cases otherwise + the values correspond to SELECT rank cases. */ + if (*case_value >=0) + sprintf (name, "__tmp_%s_rank_%d", tname, *case_value); + else + sprintf (name, "__tmp_%s_rank_m%d", tname, -*case_value); + + gfc_find_sym_tree (name, gfc_current_ns, 0, &st); + if (st) + return; + + gfc_get_sym_tree (name, gfc_current_ns, &tmp, false); + sym = tmp->n.sym; + gfc_add_type (sym, ts, NULL); + + /* Copy across the array spec to the selector. */ + if (selector->ts.type == BT_CLASS) + { + sym->ts.u.derived = CLASS_DATA (selector)->ts.u.derived; + sym->attr.pointer = CLASS_DATA (selector)->attr.pointer; + sym->attr.allocatable = CLASS_DATA (selector)->attr.allocatable; + sym->attr.target = CLASS_DATA (selector)->attr.target; + sym->attr.class_ok = 0; + if (case_value && *case_value != 0) + { + sym->attr.dimension = 1; + sym->as = gfc_copy_array_spec (CLASS_DATA (selector)->as); + if (*case_value > 0) + { + sym->as->type = AS_DEFERRED; + sym->as->rank = *case_value; + } + else if (*case_value == -1) + { + sym->as->type = AS_ASSUMED_SIZE; + sym->as->rank = 1; + } + } + } + else + { + sym->attr.pointer = selector->attr.pointer; + sym->attr.allocatable = selector->attr.allocatable; + sym->attr.target = selector->attr.target; + if (case_value && *case_value != 0) + { + sym->attr.dimension = 1; + sym->as = gfc_copy_array_spec (selector->as); + if (*case_value > 0) + { + sym->as->type = AS_DEFERRED; + sym->as->rank = *case_value; + } + else if (*case_value == -1) + { + sym->as->type = AS_ASSUMED_SIZE; + sym->as->rank = 1; + } + } + } + + gfc_set_sym_referenced (sym); + gfc_add_flavor (&sym->attr, FL_VARIABLE, name, NULL); + sym->attr.select_type_temporary = 1; + if (case_value) + sym->attr.select_rank_temporary = 1; + + if (ts->type == BT_CLASS) + gfc_build_class_symbol (&sym->ts, &sym->attr, &sym->as); + + /* Add an association for it, so the rest of the parser knows it is + an associate-name. The target will be set during resolution. */ + sym->assoc = gfc_get_association_list (); + sym->assoc->dangling = 1; + sym->assoc->st = tmp; + + select_type_stack->tmp = tmp; +} + + +/* Match a SELECT RANK statement. */ + +match +gfc_match_select_rank (void) +{ + gfc_expr *expr1, *expr2 = NULL; + match m; + char name[GFC_MAX_SYMBOL_LEN]; + gfc_symbol *sym, *sym2; + gfc_namespace *ns = gfc_current_ns; + gfc_array_spec *as; + + m = gfc_match_label (); + if (m == MATCH_ERROR) + return m; + + m = gfc_match (" select rank ( "); + if (m != MATCH_YES) + return m; + + if (!gfc_notify_std (GFC_STD_F2018, "SELECT RANK statement at %C")) + return MATCH_NO; + + gfc_current_ns = gfc_build_block_ns (ns); + m = gfc_match (" %n => %e", name, &expr2); + if (m == MATCH_YES) + { + expr1 = gfc_get_expr (); + expr1->expr_type = EXPR_VARIABLE; + expr1->where = expr2->where; + expr1->ref = gfc_copy_ref (expr2->ref); + if (gfc_get_sym_tree (name, NULL, &expr1->symtree, false)) + { + m = MATCH_ERROR; + goto cleanup; + } + + sym = expr1->symtree->n.sym; + sym2 = expr2->symtree->n.sym; + + as = sym2->ts.type == BT_CLASS ? CLASS_DATA (sym2)->as : sym2->as; + if (expr2->expr_type != EXPR_VARIABLE + || !(as && as->type == AS_ASSUMED_RANK)) + gfc_error_now ("The SELECT RANK selector at %C must be an assumed " + "rank variable"); + + if (expr2->ts.type == BT_CLASS) + { + copy_ts_from_selector_to_associate (expr1, expr2); + + sym->attr.flavor = FL_VARIABLE; + sym->attr.referenced = 1; + sym->attr.class_ok = 1; + CLASS_DATA (sym)->attr.allocatable = CLASS_DATA (sym2)->attr.allocatable; + CLASS_DATA (sym)->attr.pointer = CLASS_DATA (sym2)->attr.pointer; + CLASS_DATA (sym)->attr.target = CLASS_DATA (sym2)->attr.target; + sym->attr.pointer = 1; + } + else + { + sym->ts = sym2->ts; + sym->as = gfc_copy_array_spec (sym2->as); + sym->attr.dimension = 1; + + sym->attr.flavor = FL_VARIABLE; + sym->attr.referenced = 1; + sym->attr.class_ok = sym2->attr.class_ok; + sym->attr.allocatable = sym2->attr.allocatable; + sym->attr.pointer = sym2->attr.pointer; + sym->attr.target = sym2->attr.target; + } + } + else + { + m = gfc_match (" %e ", &expr1); + + if (m != MATCH_YES) + { + std::swap (ns, gfc_current_ns); + gfc_free_namespace (ns); + return m; + } + + sym = expr1->symtree->n.sym; + as = sym->ts.type == BT_CLASS ? CLASS_DATA (sym)->as : sym->as; + if (expr1->expr_type != EXPR_VARIABLE + || !(as && as->type == AS_ASSUMED_RANK)) + gfc_error_now ("The SELECT RANK selector at %C must be an assumed " + "rank variable"); + } + + m = gfc_match (" )%t"); + if (m != MATCH_YES) + { + gfc_error ("parse error in SELECT RANK statement at %C"); + goto cleanup; + } + + new_st.op = EXEC_SELECT_RANK; + new_st.expr1 = expr1; + new_st.expr2 = expr2; + new_st.ext.block.ns = gfc_current_ns; + + select_type_push (expr1->symtree->n.sym); + gfc_current_ns = ns; + + return MATCH_YES; + +cleanup: + gfc_free_expr (expr1); + gfc_free_expr (expr2); + gfc_undo_symbols (); + std::swap (ns, gfc_current_ns); + gfc_free_namespace (ns); + return m; +} + + /* Match a CASE statement. */ match @@ -6595,6 +6839,107 @@ cleanup: } +/* Match a RANK statement. */ + +match +gfc_match_rank_is (void) +{ + gfc_case *c = NULL; + match m; + int case_value; + + if (gfc_current_state () != COMP_SELECT_RANK) + { + gfc_error ("Unexpected RANK statement at %C"); + return MATCH_ERROR; + } + + if (gfc_match ("% default") == MATCH_YES) + { + m = match_case_eos (); + if (m == MATCH_NO) + goto syntax; + if (m == MATCH_ERROR) + goto cleanup; + + new_st.op = EXEC_SELECT_RANK; + c = gfc_get_case (); + c->ts.type = BT_UNKNOWN; + c->where = gfc_current_locus; + new_st.ext.block.case_list = c; + select_type_stack->tmp = NULL; + return MATCH_YES; + } + + if (gfc_match_char ('(') != MATCH_YES) + goto syntax; + + c = gfc_get_case (); + c->where = gfc_current_locus; + c->ts = select_type_stack->selector->ts; + + m = gfc_match_expr (&c->low); + if (m == MATCH_NO) + { + if (gfc_match_char ('*') == MATCH_YES) + c->low = gfc_get_int_expr (gfc_default_integer_kind, + NULL, -1); + else + goto syntax; + + case_value = -1; + } + else if (m == MATCH_YES) + { + /* F2018: R1150 */ + if (c->low->expr_type != EXPR_CONSTANT + || c->low->ts.type != BT_INTEGER + || c->low->rank) + { + gfc_error ("The SELECT RANK CASE expression at %C must be a " + "scalar, integer constant"); + goto cleanup; + } + + case_value = (int) mpz_get_si (c->low->value.integer); + /* F2018: C1151 */ + if ((case_value < 0) || (case_value > GFC_MAX_DIMENSIONS)) + { + gfc_error ("The value of the SELECT RANK CASE expression at " + "%C must not be less than zero or greater than %d", + GFC_MAX_DIMENSIONS); + goto cleanup; + } + } + else + goto cleanup; + + if (gfc_match_char (')') != MATCH_YES) + goto syntax; + + m = match_case_eos (); + if (m == MATCH_NO) + goto syntax; + if (m == MATCH_ERROR) + goto cleanup; + + new_st.op = EXEC_SELECT_RANK; + new_st.ext.block.case_list = c; + + /* Create temporary variable. Recycle the select type code. */ + select_rank_set_tmp (&c->ts, &case_value); + + return MATCH_YES; + +syntax: + gfc_error ("Syntax error in RANK specification at %C"); + +cleanup: + if (c != NULL) + gfc_free_case_list (c); /* new_st is cleaned up in parse.c. */ + return MATCH_ERROR; +} + /********************* WHERE subroutines ********************/ /* Match the rest of a simple WHERE statement that follows an IF statement. diff --git a/gcc/fortran/match.h b/gcc/fortran/match.h index 29854ee..1bd78b1 100644 --- a/gcc/fortran/match.h +++ b/gcc/fortran/match.h @@ -121,6 +121,8 @@ match gfc_match_select (void); match gfc_match_select_type (void); match gfc_match_type_is (void); match gfc_match_class_is (void); +match gfc_match_select_rank (void); +match gfc_match_rank_is (void); match gfc_match_where (gfc_statement *); match gfc_match_elsewhere (void); match gfc_match_forall (gfc_statement *); diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c index 8950b6a..caea16b 100644 --- a/gcc/fortran/parse.c +++ b/gcc/fortran/parse.c @@ -426,6 +426,7 @@ decode_statement (void) match (NULL, gfc_match_critical, ST_CRITICAL); match (NULL, gfc_match_select, ST_SELECT_CASE); match (NULL, gfc_match_select_type, ST_SELECT_TYPE); + match (NULL, gfc_match_select_rank, ST_SELECT_RANK); /* General statement matching: Instead of testing every possible statement, we eliminate most possibilities by peeking at the @@ -546,6 +547,7 @@ decode_statement (void) break; case 'r': + match ("rank", gfc_match_rank_is, ST_RANK); match ("read", gfc_match_read, ST_READ); match ("return", gfc_match_return, ST_RETURN); match ("rewind", gfc_match_rewind, ST_REWIND); @@ -1537,7 +1539,7 @@ next_statement (void) #define case_exec_markers case ST_DO: case ST_FORALL_BLOCK: \ case ST_IF_BLOCK: case ST_BLOCK: case ST_ASSOCIATE: \ case ST_WHERE_BLOCK: case ST_SELECT_CASE: case ST_SELECT_TYPE: \ - case ST_OMP_PARALLEL: \ + case ST_SELECT_RANK: case ST_OMP_PARALLEL: \ case ST_OMP_PARALLEL_SECTIONS: case ST_OMP_SECTIONS: case ST_OMP_ORDERED: \ case ST_OMP_CRITICAL: case ST_OMP_MASTER: case ST_OMP_SINGLE: \ case ST_OMP_DO: case ST_OMP_PARALLEL_DO: case ST_OMP_ATOMIC: \ @@ -2077,12 +2079,18 @@ gfc_ascii_statement (gfc_statement st) case ST_SELECT_TYPE: p = "SELECT TYPE"; break; + case ST_SELECT_RANK: + p = "SELECT RANK"; + break; case ST_TYPE_IS: p = "TYPE IS"; break; case ST_CLASS_IS: p = "CLASS IS"; break; + case ST_RANK: + p = "RANK"; + break; case ST_SEQUENCE: p = "SEQUENCE"; break; @@ -4179,7 +4187,7 @@ parse_select_block (void) reject_statement (); } - /* At this point, we're got a nonempty select block. */ + /* At this point, we've got a nonempty select block. */ cp = new_level (cp); *cp = new_st; @@ -4263,7 +4271,7 @@ parse_select_type_block (void) reject_statement (); } - /* At this point, we're got a nonempty select block. */ + /* At this point, we've got a nonempty select block. */ cp = new_level (cp); *cp = new_st; @@ -4306,6 +4314,81 @@ done: } +/* Parse a SELECT RANK construct. */ + +static void +parse_select_rank_block (void) +{ + gfc_statement st; + gfc_code *cp; + gfc_state_data s; + + gfc_current_ns = new_st.ext.block.ns; + accept_statement (ST_SELECT_RANK); + + cp = gfc_state_stack->tail; + push_state (&s, COMP_SELECT_RANK, gfc_new_block); + + /* Make sure that the next statement is a RANK IS or RANK DEFAULT. */ + for (;;) + { + st = next_statement (); + if (st == ST_NONE) + unexpected_eof (); + if (st == ST_END_SELECT) + /* Empty SELECT CASE is OK. */ + goto done; + if (st == ST_RANK) + break; + + gfc_error ("Expected RANK or RANK DEFAULT " + "following SELECT RANK at %C"); + + reject_statement (); + } + + /* At this point, we've got a nonempty select block. */ + cp = new_level (cp); + *cp = new_st; + + accept_statement (st); + + do + { + st = parse_executable (ST_NONE); + switch (st) + { + case ST_NONE: + unexpected_eof (); + + case ST_RANK: + cp = new_level (gfc_state_stack->head); + *cp = new_st; + gfc_clear_new_st (); + + accept_statement (st); + /* Fall through */ + + case ST_END_SELECT: + break; + + /* Can't have an executable statement because of + parse_executable(). */ + default: + unexpected_statement (st); + break; + } + } + while (st != ST_END_SELECT); + +done: + pop_state (); + accept_statement (st); + gfc_current_ns = gfc_current_ns->parent; + select_type_pop (); +} + + /* Given a symbol, make sure it is not an iteration variable for a DO statement. This subroutine is called when the symbol is seen in a context that causes it to become redefined. If the symbol is an @@ -5360,6 +5443,10 @@ parse_executable (gfc_statement st) parse_select_type_block (); break; + case ST_SELECT_RANK: + parse_select_rank_block (); + break; + case ST_DO: parse_do_block (); if (check_do_closure () == 1) @@ -6410,7 +6497,7 @@ done: if (flag_dump_fortran_global) gfc_dump_global_symbols (stdout); - + gfc_end_source_files (); return true; diff --git a/gcc/fortran/parse.h b/gcc/fortran/parse.h index 800f2f4..58c2c1b 100644 --- a/gcc/fortran/parse.h +++ b/gcc/fortran/parse.h @@ -30,7 +30,8 @@ enum gfc_compile_state COMP_DERIVED_CONTAINS, COMP_BLOCK, COMP_ASSOCIATE, COMP_IF, COMP_STRUCTURE, COMP_UNION, COMP_MAP, COMP_DO, COMP_SELECT, COMP_FORALL, COMP_WHERE, COMP_CONTAINS, COMP_ENUM, - COMP_SELECT_TYPE, COMP_OMP_STRUCTURED_BLOCK, COMP_CRITICAL, COMP_DO_CONCURRENT + COMP_SELECT_TYPE, COMP_SELECT_RANK, COMP_OMP_STRUCTURED_BLOCK, COMP_CRITICAL, + COMP_DO_CONCURRENT }; /* Stack element for the current compilation state. These structures diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index 1f48045..383ba44 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -1866,7 +1866,7 @@ resolve_procedure_expression (gfc_expr* expr) /* Check that name is not a derived type. */ - + static bool is_dt_name (const char *name) { @@ -5455,13 +5455,16 @@ resolve_variable (gfc_expr *e) } } /* TS 29113, C535b. */ - else if ((sym->ts.type == BT_CLASS && sym->attr.class_ok - && CLASS_DATA (sym)->as - && CLASS_DATA (sym)->as->type == AS_ASSUMED_RANK) - || (sym->ts.type != BT_CLASS && sym->as - && sym->as->type == AS_ASSUMED_RANK)) + else if (((sym->ts.type == BT_CLASS && sym->attr.class_ok + && CLASS_DATA (sym)->as + && CLASS_DATA (sym)->as->type == AS_ASSUMED_RANK) + || (sym->ts.type != BT_CLASS && sym->as + && sym->as->type == AS_ASSUMED_RANK)) + && !sym->attr.select_rank_temporary) { - if (!actual_arg) + if (!actual_arg + && !(cs_base && cs_base->current + && cs_base->current->op == EXEC_SELECT_RANK)) { gfc_error ("Assumed-rank variable %s at %L may only be used as " "actual argument", sym->name, &e->where); @@ -6915,7 +6918,7 @@ gfc_resolve_expr (gfc_expr *e) bool t; bool inquiry_save, actual_arg_save, first_actual_arg_save; - if (e == NULL) + if (e == NULL || e->do_not_resolve_again) return true; /* inquiry_argument only applies to variables. */ @@ -7025,6 +7028,13 @@ gfc_resolve_expr (gfc_expr *e) actual_arg = actual_arg_save; first_actual_arg = first_actual_arg_save; + /* For some reason, resolving these expressions a second time mangles + the typespec of the expression itself. */ + if (t && e->expr_type == EXPR_VARIABLE + && e->symtree->n.sym->attr.select_rank_temporary + && UNLIMITED_POLY (e->symtree->n.sym)) + e->do_not_resolve_again = 1; + return t; } @@ -8841,7 +8851,7 @@ resolve_assoc_var (gfc_symbol* sym, bool resolve_target) if (target->ts.type == BT_CLASS) gfc_fix_class_refs (target); - if (target->rank != 0) + if (target->rank != 0 && !sym->attr.select_rank_temporary) { gfc_array_spec *as; /* The rank may be incorrectly guessed at parsing, therefore make sure @@ -8871,7 +8881,7 @@ resolve_assoc_var (gfc_symbol* sym, bool resolve_target) CLASS_DATA (sym)->attr.codimension = 1; } } - else + else if (!sym->attr.select_rank_temporary) { /* target's rank is 0, but the type of the sym is still array valued, which has to be corrected. */ @@ -9490,6 +9500,175 @@ resolve_select_type (gfc_code *code, gfc_namespace *old_ns) } +/* Resolve a SELECT RANK statement. */ + +static void +resolve_select_rank (gfc_code *code, gfc_namespace *old_ns) +{ + gfc_namespace *ns; + gfc_code *body, *new_st, *tail; + gfc_case *c; + char tname[GFC_MAX_SYMBOL_LEN]; + char name[2 * GFC_MAX_SYMBOL_LEN]; + gfc_symtree *st; + gfc_expr *selector_expr = NULL; + int case_value; + HOST_WIDE_INT charlen = 0; + + ns = code->ext.block.ns; + gfc_resolve (ns); + + code->op = EXEC_BLOCK; + if (code->expr2) + { + gfc_association_list* assoc; + + assoc = gfc_get_association_list (); + assoc->st = code->expr1->symtree; + assoc->target = gfc_copy_expr (code->expr2); + assoc->target->where = code->expr2->where; + /* assoc->variable will be set by resolve_assoc_var. */ + + code->ext.block.assoc = assoc; + code->expr1->symtree->n.sym->assoc = assoc; + + resolve_assoc_var (code->expr1->symtree->n.sym, false); + } + else + code->ext.block.assoc = NULL; + + /* Loop over RANK cases. Note that returning on the errors causes a + cascade of further errors because the case blocks do not compile + correctly. */ + for (body = code->block; body; body = body->block) + { + c = body->ext.block.case_list; + if (c->low) + case_value = (int) mpz_get_si (c->low->value.integer); + else + case_value = -2; + + /* Check for repeated cases. */ + for (tail = code->block; tail; tail = tail->block) + { + gfc_case *d = tail->ext.block.case_list; + int case_value2; + + if (tail == body) + break; + + /* Check F2018: C1153. */ + if (!c->low && !d->low) + gfc_error ("RANK DEFAULT at %L is repeated at %L", + &c->where, &d->where); + + if (!c->low || !d->low) + continue; + + /* Check F2018: C1153. */ + case_value2 = (int) mpz_get_si (d->low->value.integer); + if ((case_value == case_value2) && case_value == -1) + gfc_error ("RANK (*) at %L is repeated at %L", + &c->where, &d->where); + else if (case_value == case_value2) + gfc_error ("RANK (%i) at %L is repeated at %L", + case_value, &c->where, &d->where); + } + + if (!c->low) + continue; + + /* Check F2018: C1155. */ + if (case_value == -1 && (gfc_expr_attr (code->expr1).allocatable + || gfc_expr_attr (code->expr1).pointer)) + gfc_error ("RANK (*) at %L cannot be used with the pointer or " + "allocatable selector at %L", &c->where, &code->expr1->where); + + if (case_value == -1 && (gfc_expr_attr (code->expr1).allocatable + || gfc_expr_attr (code->expr1).pointer)) + gfc_error ("RANK (*) at %L cannot be used with the pointer or " + "allocatable selector at %L", &c->where, &code->expr1->where); + } + + /* Add EXEC_SELECT to switch on rank. */ + new_st = gfc_get_code (code->op); + new_st->expr1 = code->expr1; + new_st->expr2 = code->expr2; + new_st->block = code->block; + code->expr1 = code->expr2 = NULL; + code->block = NULL; + if (!ns->code) + ns->code = new_st; + else + ns->code->next = new_st; + code = new_st; + code->op = EXEC_SELECT_RANK; + + selector_expr = code->expr1; + + /* Loop over SELECT RANK cases. */ + for (body = code->block; body; body = body->block) + { + c = body->ext.block.case_list; + int case_value; + + /* Pass on the default case. */ + if (c->low == NULL) + continue; + + /* Associate temporary to selector. This should only be done + when this case is actually true, so build a new ASSOCIATE + that does precisely this here (instead of using the + 'global' one). */ + if (c->ts.type == BT_CHARACTER && c->ts.u.cl && c->ts.u.cl->length + && c->ts.u.cl->length->expr_type == EXPR_CONSTANT) + charlen = gfc_mpz_get_hwi (c->ts.u.cl->length->value.integer); + + if (c->ts.type == BT_CLASS) + sprintf (tname, "class_%s", c->ts.u.derived->name); + else if (c->ts.type == BT_DERIVED) + sprintf (tname, "type_%s", c->ts.u.derived->name); + else if (c->ts.type != BT_CHARACTER) + sprintf (tname, "%s_%d", gfc_basic_typename (c->ts.type), c->ts.kind); + else + sprintf (tname, "%s_" HOST_WIDE_INT_PRINT_DEC "_%d", + gfc_basic_typename (c->ts.type), charlen, c->ts.kind); + + case_value = (int) mpz_get_si (c->low->value.integer); + if (case_value >= 0) + sprintf (name, "__tmp_%s_rank_%d", tname, case_value); + else + sprintf (name, "__tmp_%s_rank_m%d", tname, -case_value); + + st = gfc_find_symtree (ns->sym_root, name); + gcc_assert (st->n.sym->assoc); + + st->n.sym->assoc->target = gfc_get_variable_expr (selector_expr->symtree); + st->n.sym->assoc->target->where = selector_expr->where; + + new_st = gfc_get_code (EXEC_BLOCK); + new_st->ext.block.ns = gfc_build_block_ns (ns); + new_st->ext.block.ns->code = body->next; + body->next = new_st; + + /* Chain in the new list only if it is marked as dangling. Otherwise + there is a CASE label overlap and this is already used. Just ignore, + the error is diagnosed elsewhere. */ + if (st->n.sym->assoc->dangling) + { + new_st->ext.block.assoc = st->n.sym->assoc; + st->n.sym->assoc->dangling = 0; + } + + resolve_assoc_var (st->n.sym, false); + } + + gfc_current_ns = ns; + gfc_resolve_blocks (code->block, gfc_current_ns); + gfc_current_ns = old_ns; +} + + /* Resolve a transfer statement. This is making sure that: -- a derived type being transferred has only non-pointer components -- a derived type being transferred doesn't have private components, unless @@ -10366,6 +10545,7 @@ gfc_resolve_blocks (gfc_code *b, gfc_namespace *ns) case EXEC_SELECT: case EXEC_SELECT_TYPE: + case EXEC_SELECT_RANK: case EXEC_FORALL: case EXEC_DO: case EXEC_DO_WHILE: @@ -11643,6 +11823,10 @@ start: resolve_select_type (code, ns); break; + case EXEC_SELECT_RANK: + resolve_select_rank (code, ns); + break; + case EXEC_BLOCK: resolve_block_construct (code); break; @@ -13573,7 +13757,7 @@ resolve_typebound_procedure (gfc_symtree* stree) } else { - /* If proc has not been resolved at this point, proc->name may + /* If proc has not been resolved at this point, proc->name may actually be a USE associated entity. See PR fortran/89647. */ if (!proc->resolved && proc->attr.function == 0 && proc->attr.subroutine == 0) @@ -15048,7 +15232,9 @@ resolve_symbol (gfc_symbol *sym) } /* TS 29113, C535a. */ if (as->type == AS_ASSUMED_RANK && !sym->attr.dummy - && !sym->attr.select_type_temporary) + && !sym->attr.select_type_temporary + && !(cs_base && cs_base->current + && cs_base->current->op == EXEC_SELECT_RANK)) { gfc_error ("Assumed-rank array at %L must be a dummy argument", &sym->declared_at); diff --git a/gcc/fortran/st.c b/gcc/fortran/st.c index ade2fce..ee18d7a 100644 --- a/gcc/fortran/st.c +++ b/gcc/fortran/st.c @@ -141,6 +141,7 @@ gfc_free_statement (gfc_code *p) case EXEC_SELECT: case EXEC_SELECT_TYPE: + case EXEC_SELECT_RANK: if (p->ext.block.case_list) gfc_free_case_list (p->ext.block.case_list); break; diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index c8d74e5..da70301 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -3609,7 +3609,7 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_expr *expr, if (ar->dimen == 0) { - gcc_assert (ar->codimen); + gcc_assert (ar->codimen || sym->attr.select_rank_temporary); if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se->expr))) se->expr = build_fold_indirect_ref (gfc_conv_array_data (se->expr)); @@ -7758,6 +7758,12 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr) gfc_conv_descriptor_offset_set (&loop.pre, parm, gfc_conv_descriptor_offset_get (desc)); } + else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)) + && !se->data_not_needed + && gfc_expr_attr (expr).select_rank_temporary) + { + gfc_conv_descriptor_offset_set (&loop.pre, parm, gfc_index_zero_node); + } else if (onebased && (!rank_remap || se->use_offset) && expr->symtree && !(expr->symtree->n.sym && expr->symtree->n.sym->ts.type == BT_CLASS diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c index 3606880..856a171 100644 --- a/gcc/fortran/trans-stmt.c +++ b/gcc/fortran/trans-stmt.c @@ -1641,6 +1641,48 @@ class_has_len_component (gfc_symbol *sym) } +static void +copy_descriptor (stmtblock_t *block, tree dst, tree src, int rank) +{ + int n; + tree dim; + tree tmp; + tree tmp2; + tree size; + tree offset; + + offset = gfc_index_zero_node; + + /* Use memcpy to copy the descriptor. The size is the minimum of + the sizes of 'src' and 'dst'. This avoids a non-trivial conversion. */ + tmp = TYPE_SIZE_UNIT (TREE_TYPE (src)); + tmp2 = TYPE_SIZE_UNIT (TREE_TYPE (dst)); + size = fold_build2_loc (input_location, MIN_EXPR, + TREE_TYPE (tmp), tmp, tmp2); + tmp = builtin_decl_explicit (BUILT_IN_MEMCPY); + tmp = build_call_expr_loc (input_location, tmp, 3, + gfc_build_addr_expr (NULL_TREE, dst), + gfc_build_addr_expr (NULL_TREE, src), + fold_convert (size_type_node, size)); + gfc_add_expr_to_block (block, tmp); + + /* Set the offset correctly. */ + for (n = 0; n < rank; n++) + { + dim = gfc_rank_cst[n]; + tmp = gfc_conv_descriptor_lbound_get (src, dim); + tmp2 = gfc_conv_descriptor_stride_get (src, dim); + tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp), + tmp, tmp2); + offset = fold_build2_loc (input_location, MINUS_EXPR, + TREE_TYPE (offset), offset, tmp); + offset = gfc_evaluate_now (offset, block); + } + + gfc_conv_descriptor_offset_set (block, dst, offset); +} + + /* Do proper initialization for ASSOCIATE names. */ static void @@ -1658,6 +1700,7 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block) bool need_len_assign; bool whole_array = true; gfc_ref *ref; + gfc_symbol *sym2; gcc_assert (sym->assoc); e = sym->assoc->target; @@ -1690,12 +1733,140 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block) && e->ts.u.derived->attr.unlimited_polymorphic)) && (sym->ts.type == BT_CHARACTER || ((sym->ts.type == BT_CLASS || sym->ts.type == BT_DERIVED) - && class_has_len_component (sym)))); + && class_has_len_component (sym))) + && !sym->attr.select_rank_temporary); + /* Do a `pointer assignment' with updated descriptor (or assign descriptor to array temporary) for arrays with either unknown shape or if associating - to a variable. */ - if (sym->attr.dimension && !class_target - && (sym->as->type == AS_DEFERRED || sym->assoc->variable)) + to a variable. Select rank temporaries need somewhat different treatment + to other associate names and case temporaries. This because the selector + is assumed rank and so the offset in particular has to be changed. Also, + the case temporaries carry both allocatable and target attributes if + present in the selector. This means that an allocatation or change of + association can occur and so has to be dealt with. */ + if (sym->attr.select_rank_temporary) + { + gfc_se se; + tree class_decl = NULL_TREE; + int rank = 0; + bool class_ptr; + + sym2 = e->symtree->n.sym; + gfc_init_se (&se, NULL); + if (e->ts.type == BT_CLASS) + { + /* Go straight to the class data. */ + if (sym2->attr.dummy) + { + class_decl = DECL_LANG_SPECIFIC (sym2->backend_decl) ? + GFC_DECL_SAVED_DESCRIPTOR (sym2->backend_decl) : + sym2->backend_decl; + if (POINTER_TYPE_P (TREE_TYPE (class_decl))) + class_decl = build_fold_indirect_ref_loc (input_location, + class_decl); + gcc_assert (GFC_CLASS_TYPE_P (TREE_TYPE (class_decl))); + se.expr = gfc_class_data_get (class_decl); + } + else + { + class_decl = sym2->backend_decl; + gfc_conv_expr_descriptor (&se, e); + if (POINTER_TYPE_P (TREE_TYPE (se.expr))) + se.expr = build_fold_indirect_ref_loc (input_location, + se.expr); + } + + if (CLASS_DATA (sym)->as && CLASS_DATA (sym)->as->rank > 0) + rank = CLASS_DATA (sym)->as->rank; + } + else + { + gfc_conv_expr_descriptor (&se, e); + if (sym->as && sym->as->rank > 0) + rank = sym->as->rank; + } + + desc = sym->backend_decl; + + /* The SELECT TYPE mechanisms turn class temporaries into pointers, which + point to the selector. */ + class_ptr = class_decl != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (desc)); + if (class_ptr) + { + tmp = gfc_create_var (TREE_TYPE (TREE_TYPE (desc)), "class"); + tmp = gfc_build_addr_expr (NULL, tmp); + gfc_add_modify (&se.pre, desc, tmp); + + tmp = gfc_class_vptr_get (class_decl); + gfc_add_modify (&se.pre, gfc_class_vptr_get (desc), tmp); + if (UNLIMITED_POLY (sym)) + gfc_add_modify (&se.pre, gfc_class_len_get (desc), + gfc_class_len_get (class_decl)); + + desc = gfc_class_data_get (desc); + } + + /* SELECT RANK temporaries can carry the allocatable and pointer + attributes so the selector descriptor must be copied in and + copied out. */ + if (rank > 0) + copy_descriptor (&se.pre, desc, se.expr, rank); + else + { + tmp = gfc_conv_descriptor_data_get (se.expr); + gfc_add_modify (&se.pre, desc, + fold_convert (TREE_TYPE (desc), tmp)); + } + + /* Deal with associate_name => selector. Class associate names are + treated in the same way as in SELECT TYPE. */ + sym2 = sym->assoc->target->symtree->n.sym; + if (sym2->assoc && sym->assoc->target && sym2->ts.type != BT_CLASS) + { + sym2 = sym2->assoc->target->symtree->n.sym; + se.expr = sym2->backend_decl; + + if (POINTER_TYPE_P (TREE_TYPE (se.expr))) + se.expr = build_fold_indirect_ref_loc (input_location, + se.expr); + } + + /* There could have been reallocation. Copy descriptor back to the + selector and update the offset. */ + if (sym->attr.allocatable || sym->attr.pointer + || (sym->ts.type == BT_CLASS + && (CLASS_DATA (sym)->attr.allocatable + || CLASS_DATA (sym)->attr.pointer))) + { + if (rank > 0) + copy_descriptor (&se.post, se.expr, desc, rank); + else + { + tmp = gfc_conv_descriptor_data_get (desc); + gfc_conv_descriptor_data_set (&se.post, se.expr, tmp); + } + + /* The dynamic type could have changed too. */ + if (sym->ts.type == BT_CLASS) + { + tmp = sym->backend_decl; + if (class_ptr) + tmp = build_fold_indirect_ref_loc (input_location, tmp); + gfc_add_modify (&se.post, gfc_class_vptr_get (class_decl), + gfc_class_vptr_get (tmp)); + if (UNLIMITED_POLY (sym)) + gfc_add_modify (&se.post, gfc_class_len_get (class_decl), + gfc_class_len_get (tmp)); + } + } + + tmp = gfc_finish_block (&se.post); + + gfc_add_init_cleanup (block, gfc_finish_block (&se.pre), tmp); + } + /* Now all the other kinds of associate variable. */ + else if (sym->attr.dimension && !class_target + && (sym->as->type == AS_DEFERRED || sym->assoc->variable)) { gfc_se se; tree desc; @@ -3424,6 +3595,142 @@ gfc_trans_select_type (gfc_code * code) } +static tree +gfc_trans_select_rank_cases (gfc_code * code) +{ + gfc_code *c; + gfc_case *cp; + tree tmp; + tree cond; + tree low; + tree sexpr; + tree rank; + tree rank_minus_one; + tree minus_one; + gfc_se se; + gfc_se cse; + stmtblock_t block; + stmtblock_t body; + bool def = false; + + gfc_start_block (&block); + + /* Calculate the switch expression. */ + gfc_init_se (&se, NULL); + gfc_conv_expr_descriptor (&se, code->expr1); + rank = gfc_conv_descriptor_rank (se.expr); + rank = gfc_evaluate_now (rank, &block); + minus_one = build_int_cst (TREE_TYPE (rank), -1); + tmp = fold_build2_loc (input_location, MINUS_EXPR, + gfc_array_index_type, + fold_convert (gfc_array_index_type, rank), + build_int_cst (gfc_array_index_type, 1)); + rank_minus_one = gfc_evaluate_now (tmp, &block); + tmp = gfc_conv_descriptor_ubound_get (se.expr, rank_minus_one); + cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, + tmp, build_int_cst (TREE_TYPE (tmp), -1)); + tmp = fold_build3_loc (input_location, COND_EXPR, + TREE_TYPE (rank), cond, + rank, minus_one); + cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, + rank, build_int_cst (TREE_TYPE (rank), 0)); + sexpr = fold_build3_loc (input_location, COND_EXPR, + TREE_TYPE (rank), cond, + rank, tmp); + sexpr = gfc_evaluate_now (sexpr, &block); + TREE_USED (code->exit_label) = 0; + +repeat: + for (c = code->block; c; c = c->block) + { + cp = c->ext.block.case_list; + + /* Assume it's the default case. */ + low = NULL_TREE; + tmp = NULL_TREE; + + /* Put the default case at the end. */ + if ((!def && !cp->low) || (def && cp->low)) + continue; + + if (cp->low) + { + gfc_init_se (&cse, NULL); + gfc_conv_expr_val (&cse, cp->low); + gfc_add_block_to_block (&block, &cse.pre); + low = cse.expr; + } + + gfc_init_block (&body); + + /* Add the statements for this case. */ + tmp = gfc_trans_code (c->next); + gfc_add_expr_to_block (&body, tmp); + + /* Break to the end of the SELECT RANK construct. The default + case just falls through. */ + if (!def) + { + TREE_USED (code->exit_label) = 1; + tmp = build1_v (GOTO_EXPR, code->exit_label); + gfc_add_expr_to_block (&body, tmp); + } + + tmp = gfc_finish_block (&body); + + if (low != NULL_TREE) + { + cond = fold_build2_loc (input_location, EQ_EXPR, + TREE_TYPE (sexpr), sexpr, + fold_convert (TREE_TYPE (sexpr), low)); + tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, + cond, tmp, + build_empty_stmt (input_location)); + } + + gfc_add_expr_to_block (&block, tmp); + } + + if (!def) + { + def = true; + goto repeat; + } + + return gfc_finish_block (&block); +} + + +tree +gfc_trans_select_rank (gfc_code * code) +{ + stmtblock_t block; + tree body; + tree exit_label; + + gcc_assert (code && code->expr1); + gfc_init_block (&block); + + /* Build the exit label and hang it in. */ + exit_label = gfc_build_label_decl (NULL_TREE); + code->exit_label = exit_label; + + /* Empty SELECT constructs are legal. */ + if (code->block == NULL) + body = build_empty_stmt (input_location); + else + body = gfc_trans_select_rank_cases (code); + + /* Build everything together. */ + gfc_add_expr_to_block (&block, body); + + if (TREE_USED (exit_label)) + gfc_add_expr_to_block (&block, build1_v (LABEL_EXPR, exit_label)); + + return gfc_finish_block (&block); +} + + /* Traversal function to substitute a replacement symtree if the symbol in the expression is the same as that passed. f == 2 signals that that variable itself is not to be checked - only the references. diff --git a/gcc/fortran/trans-stmt.h b/gcc/fortran/trans-stmt.h index 9cb0f68..967f779 100644 --- a/gcc/fortran/trans-stmt.h +++ b/gcc/fortran/trans-stmt.h @@ -53,6 +53,7 @@ tree gfc_trans_do_concurrent (gfc_code *); tree gfc_trans_do_while (gfc_code *); tree gfc_trans_select (gfc_code *); tree gfc_trans_select_type (gfc_code *); +tree gfc_trans_select_rank (gfc_code *); tree gfc_trans_sync (gfc_code *, gfc_exec_op); tree gfc_trans_lock_unlock (gfc_code *, gfc_exec_op); tree gfc_trans_event_post_wait (gfc_code *, gfc_exec_op); diff --git a/gcc/fortran/trans.c b/gcc/fortran/trans.c index 583f6e3..2f878f6 100644 --- a/gcc/fortran/trans.c +++ b/gcc/fortran/trans.c @@ -1968,6 +1968,10 @@ trans_code (gfc_code * code, tree cond) res = gfc_trans_select_type (code); break; + case EXEC_SELECT_RANK: + res = gfc_trans_select_rank (code); + break; + case EXEC_FLUSH: res = gfc_trans_flush (code); break; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index aa73312..308e473 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-01 Paul Thomas + + * gfortran.dg/select_rank_1.f90 : New test. + * gfortran.dg/select_rank_2.f90 : New test. + 2019-09-01 Jakub Jelinek PR middle-end/91623 diff --git a/gcc/testsuite/gfortran.dg/select_rank_1.f90 b/gcc/testsuite/gfortran.dg/select_rank_1.f90 new file mode 100644 index 0000000..69f6655 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/select_rank_1.f90 @@ -0,0 +1,179 @@ +! { dg-do run } +! +! Basic tests of SELECT RANK +! +! Contributed by Paul Thomas +! + implicit none + type mytype + real :: r + end type + type, extends(mytype) :: thytype + integer :: i + end type + +! Torture using integers +ints: block + integer, dimension(2,2) :: y = reshape ([1,2,3,4],[2,2]) + integer, dimension(4) :: z = [1,2,3,4] + integer, dimension(2,2,2) :: q = reshape ([11,12,13,14,15,16,17,18],[2,2,2]) + integer :: i = 42 + + call ifoo(y, "y") + if (any (y .ne. reshape ([10,11,12,13], [2,2]))) stop 1 + call ifoo(z, "z") + call ifoo(i, "i") + call ifoo(q, "q") + if (any (q .ne. reshape ([11,12,10,11,15,16,12,13], [2,2,2]))) stop 2 + call ibar(y) +end block ints + +! Check derived types +types: block + integer :: i + type(mytype), allocatable, dimension(:,:) :: t + type(mytype), allocatable :: u + + allocate (t, source = reshape ([(mytype(real(i)), i = 1,4)],[2,2])) + call tfoo(t, "t") + if (any (size (t) .ne. [1,1])) stop 3 ! 't' has been reallocated! + if (abs (t(1,1)%r - 42.0) .ge. 1e-6) stop 4 + allocate (u, source = mytype(42.0)) + call tfoo(u, "u") +end block types + +! Check classes +classes: block + integer :: i + class(mytype), allocatable, dimension(:,:) :: v + class(mytype), allocatable :: w + + allocate (v, source = reshape ([(mytype(real(i)), i = 1,4)],[2,2])) + call cfoo(v, "v") + select type (v) + type is (mytype) + stop 5 + type is (thytype) + if (any (ubound (v) .ne. [3,3])) stop 6 + if (any (abs (v%r - 99.0) .ge. 1e-6)) stop 7 + if (any (v%i .ne. 42)) stop 8 + end select + allocate (w, source = thytype(42.0, 99)) + call cfoo(w, "w") +end block classes + +! Check unlimited polymorphic. +unlimited: block + integer(4) :: i + class(*), allocatable, dimension(:,:,:) :: v + + allocate (v, source = reshape ([(i, i = 1,8)],[2,2,2])) + call ufoo(v, "v") + select type (v) + type is (integer(4)) + stop 9 + type is (real(4)) + if (any (ubound(v) .ne. [2,2,1])) stop 10 + if (abs (sum (v) - 10.0) .gt. 1e-6) stop 11 + end select +end block unlimited + +contains + + recursive subroutine ifoo(w, chr) + integer, dimension(..) :: w + character(1) :: chr + + OUTER: select rank (x => w) + rank (2) + if ((chr .eq. 'y') .and. (any (x(1,:) .ne. [1,3]))) stop 12 + if ((chr .eq. 'r') .and. (any (x(1,:) .ne. [13,17]))) stop 13 + x = reshape ([10,11,12,13], [2,2]) + rank (0) + if ((chr .eq. 'i') .and. (x .ne. 42)) stop 14 + rank (*) + if ((chr .eq. 'w') .and. (any (x(1:4) .ne. [10,11,12,13]))) stop 15 + rank default + if ((chr .eq. 'z') .and. (rank (x) .ne. 1)) stop 16 + if ((chr .eq. 'q') .and. (rank (x) .ne. 3)) stop 17 + INNER: select rank (x) + rank (1) INNER + if ((chr .eq. 'z') .and. (any (x(1:4) .ne. [1,2,3,4]))) stop 18 + rank (3) INNER + ! Pass a rank 2 section otherwise an infinite loop ensues. + call ifoo(x(:,2,:), 'r') + end select INNER + end select OUTER + end subroutine ifoo + + subroutine ibar(x) + integer, dimension(*) :: x + + call ifoo(x, "w") + end subroutine ibar + + subroutine tfoo(w, chr) + type(mytype), dimension(..), allocatable :: w + character(1) :: chr + integer :: i + type(mytype), dimension(2,2) :: r + + select rank (x => w) + rank (2) + if (chr .eq. 't') then + r = reshape ([(mytype(real(i)), i = 1,4)],[2,2]) + if (any (abs (x%r - r%r) .gt. 1e-6)) stop 19 + if (allocated (x)) deallocate (x) + allocate (x(1,1)) + x(1,1) = mytype (42.0) + end if + rank default + if ((chr .eq. 'u') .and. (rank (x) .ne. 0)) stop 20 + end select + end subroutine tfoo + + subroutine cfoo(w, chr) + class(mytype), dimension(..), allocatable :: w + character(1) :: chr + integer :: i + type(mytype), dimension(2,2) :: r + + select rank (c => w) + rank (2) + select type (c) + type is (mytype) + if (chr .eq. 'v') then + r = reshape ([(mytype(real(i)), i = 1,4)],[2,2]) + if (any (abs (c%r - r%r) .gt. 1e-6)) stop 21 + end if + class default + stop 22 + end select + if (allocated (c)) deallocate (c) + allocate (c(3,3), source = thytype (99.0, 42)) + rank default + if ((chr .eq. 'w') .and. (rank (c) .ne. 0)) stop 23 + end select + end subroutine cfoo + + subroutine ufoo(w, chr) + class(*), dimension(..), allocatable :: w + character(1) :: chr + integer :: i + + select rank (c => w) + rank (3) + select type (c) + type is (integer(4)) + if (chr .eq. 'v' .and. (sum (c) .ne. 36)) stop 24 + class default + stop 25 + end select + if (allocated (c)) deallocate(c) + allocate (c, source = reshape ([(real(i), i = 1,4)],[2,2,1])) + rank default + stop 26 + end select + end subroutine ufoo + +end diff --git a/gcc/testsuite/gfortran.dg/select_rank_2.f90 b/gcc/testsuite/gfortran.dg/select_rank_2.f90 new file mode 100644 index 0000000..2415fdf --- /dev/null +++ b/gcc/testsuite/gfortran.dg/select_rank_2.f90 @@ -0,0 +1,85 @@ +! { dg-do compile } +! +! Basic tests of SELECT RANK +! +! Contributed by Paul Thomas +! +subroutine foo1 (arg) + integer :: i + integer, dimension(3) :: arg + select rank (arg) ! { dg-error "must be an assumed rank variable" } + rank (3) + print *, arg + end select +end + +subroutine foo2 (arg) + integer :: i + integer, dimension(..) :: arg + select rank (arg) + rank (i) ! { dg-error "must be a scalar" } + print *, arg ! { dg-error "Expected RANK or RANK DEFAULT" } + end select +end + +subroutine foo3 (arg) + integer :: i + integer, parameter :: r = 3 + integer, dimension(..) :: arg + select rank (arg) + rank (16) ! { dg-error "must not be less than zero or greater than 15" } + print *, arg ! { dg-error "Expected RANK or RANK DEFAULT" } + rank (-1) ! { dg-error "must not be less than zero or greater than 15" } + print *, arg ! { dg-error "Expected RANK or RANK DEFAULT" } + rank (r) ! OK + print *, arg + end select +end + +subroutine foo4 (arg) + integer :: i + integer, dimension(..), pointer :: arg + select rank (arg) ! { dg-error "cannot be used with the pointer or allocatable selector" } + rank (*) ! { dg-error "cannot be used with the pointer or allocatable selector" } + print *, arg(1:1) + rank (1) + print *, arg + end select +end + +subroutine foo5 (arg) + integer :: i + integer, dimension(..), ALLOCATABLE :: arg + select rank (arg) ! { dg-error "cannot be used with the pointer or allocatable selector" } + rank (*) ! { dg-error "pointer or allocatable selector|deferred shape or assumed rank" } + print *, arg(1:1) + rank (1) + print *, arg + end select +end + +subroutine foo6 (arg) + integer :: i + integer, dimension(..) :: arg + select rank (arg) + rank (*) + print *, arg ! { dg-error "assumed.size array" } + rank (1) + print *, arg + end select +end + +subroutine foo7 (arg) + integer :: i + integer, dimension(..) :: arg + select rank (arg) + rank (1) ! { dg-error "is repeated" } + arg = 1 + rank (1) ! { dg-error "is repeated" } + arg = 1 + rank (*) ! { dg-error "is repeated" } + rank (*) ! { dg-error "is repeated" } + rank default ! { dg-error "is repeated" } + rank default ! { dg-error "is repeated" } + end select +end -- cgit v1.1 From 2dae2123477fb0c04b62b313a60ba83254ba27e1 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Sun, 1 Sep 2019 12:55:22 +0000 Subject: re PR target/91472 (gmp testsuite segfaults with gcc-8 and gcc-9, works fine with gcc-7) PR target/91472 * config/sparc/sparc.c (sparc_cannot_force_const_mem): Return true during LRA/reload in PIC mode if the PIC register hasn't been used yet. (sparc_pic_register_p): Test reload_in_progress for consistency's sake. From-SVN: r275270 --- gcc/ChangeLog | 7 +++++ gcc/config/sparc/sparc.c | 9 +++++- gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gcc.c-torture/execute/20190901-1.c | 36 ++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/20190901-1.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6c43782..f17b4d5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2019-09-01 Eric Botcazou + + PR target/91472 + * config/sparc/sparc.c (sparc_cannot_force_const_mem): Return true + during LRA/reload in PIC mode if the PIC register hasn't been used yet. + (sparc_pic_register_p): Test reload_in_progress for consistency's sake. + 2019-09-01 Jakub Jelinek PR middle-end/91623 diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 68e3dce..634a334 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -4201,6 +4201,13 @@ eligible_for_sibcall_delay (rtx_insn *trial) static bool sparc_cannot_force_const_mem (machine_mode mode, rtx x) { + /* After IRA has run in PIC mode, it is too late to put anything into the + constant pool if the PIC register hasn't already been initialized. */ + if ((lra_in_progress || reload_in_progress) + && flag_pic + && !crtl->uses_pic_offset_table) + return true; + switch (GET_CODE (x)) { case CONST_INT: @@ -4450,7 +4457,7 @@ sparc_pic_register_p (rtx x) return true; if (!HARD_REGISTER_P (pic_offset_table_rtx) - && (HARD_REGISTER_P (x) || lra_in_progress) + && (HARD_REGISTER_P (x) || lra_in_progress || reload_in_progress) && ORIGINAL_REGNO (x) == REGNO (pic_offset_table_rtx)) return true; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 308e473..72c0abb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-09-01 Eric Botcazou + + * gcc.c-torture/execute/20190901-1.c: New test. + 2019-09-01 Paul Thomas * gfortran.dg/select_rank_1.f90 : New test. diff --git a/gcc/testsuite/gcc.c-torture/execute/20190901-1.c b/gcc/testsuite/gcc.c-torture/execute/20190901-1.c new file mode 100644 index 0000000..c78715e --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20190901-1.c @@ -0,0 +1,36 @@ +/* PR target/91472 */ +/* Reported by John Paul Adrian Glaubitz */ + +typedef unsigned int gmp_uint_least32_t; + +union ieee_double_extract +{ + struct + { + gmp_uint_least32_t sig:1; + gmp_uint_least32_t exp:11; + gmp_uint_least32_t manh:20; + gmp_uint_least32_t manl:32; + } s; + double d; +}; + +double __attribute__((noipa)) +tests_infinity_d (void) +{ + union ieee_double_extract x; + x.s.exp = 2047; + x.s.manl = 0; + x.s.manh = 0; + x.s.sig = 0; + return x.d; +} + +int +main (void) +{ + double x = tests_infinity_d (); + if (x == 0.0) + __builtin_abort (); + return 0; +} -- cgit v1.1 From 4c122404fabbd651dab4c6a1217257ff5fe03ae9 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Sun, 1 Sep 2019 12:55:58 +0000 Subject: target-supports.exp (check_effective_target_pthread): Add #include directive to the test. * lib/target-supports.exp (check_effective_target_pthread): Add #include directive to the test. From-SVN: r275271 --- gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/lib/target-supports.exp | 5 ++--- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 72c0abb..a84a8b9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -2,6 +2,9 @@ * gcc.c-torture/execute/20190901-1.c: New test. + * lib/target-supports.exp (check_effective_target_pthread): Add + #include directive to the test. + 2019-09-01 Paul Thomas * gfortran.dg/select_rank_1.f90 : New test. diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 300d22a..739321a 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -1052,11 +1052,10 @@ proc check_effective_target_swapcontext {} { }] } -# Return 1 if compilation with -pthread is error-free for trivial -# code, 0 otherwise. - +# Return 1 if the target supports POSIX threads, 0 otherwise. proc check_effective_target_pthread {} { return [check_no_compiler_messages pthread object { + #include void foo (void) { } } "-pthread"] } -- cgit v1.1 From 3791ba494b273413751ce9bbd3142121850f7f5a Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Sun, 1 Sep 2019 18:38:59 +0000 Subject: [testsuite] Unsupport 20190827-1.c for targets without alias support. gcc/testsuite/ 2019-09-01 Iain Sandoe * gcc.c-torture/compile/20190827-1.c: Add dg-requires-alias. From-SVN: r275274 --- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.c-torture/compile/20190827-1.c | 1 + 2 files changed, 5 insertions(+) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a84a8b9..0761ba1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-09-01 Iain Sandoe + + * gcc.c-torture/compile/20190827-1.c: Add dg-requires-alias. + 2019-09-01 Eric Botcazou * gcc.c-torture/execute/20190901-1.c: New test. diff --git a/gcc/testsuite/gcc.c-torture/compile/20190827-1.c b/gcc/testsuite/gcc.c-torture/compile/20190827-1.c index f095617..cdf71d8 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20190827-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20190827-1.c @@ -1,3 +1,4 @@ +/* { dg-require-alias "" } */ typedef unsigned char __u8; typedef __u8 u8; typedef u8 u_int8_t; -- cgit v1.1 From 556f8de3bec99dfe1dac15fecc704025d22b8fd4 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Sun, 1 Sep 2019 22:54:15 +0000 Subject: PR c++/91129 - wrong error with binary op in template argument. * typeck.c (warn_for_null_address): Use fold_for_warn instead of fold_non_dependent_expr. (cp_build_binary_op): Likewise. * g++.dg/cpp1y/nontype1.C: New test. From-SVN: r275285 --- gcc/cp/ChangeLog | 7 ++++++ gcc/cp/typeck.c | 18 ++++++--------- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/cpp1y/nontype1.C | 42 +++++++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1y/nontype1.C (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9725dda..8eb81c5 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2019-09-01 Marek Polacek + + PR c++/91129 - wrong error with binary op in template argument. + * typeck.c (warn_for_null_address): Use fold_for_warn instead of + fold_non_dependent_expr. + (cp_build_binary_op): Likewise. + 2019-08-30 Jason Merrill Add source location to TRAIT_EXPR. diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index d4f2d981..70094d1 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -4305,7 +4305,7 @@ warn_for_null_address (location_t location, tree op, tsubst_flags_t complain) || TREE_NO_WARNING (op)) return; - tree cop = fold_non_dependent_expr (op, complain); + tree cop = fold_for_warn (op); if (TREE_CODE (cop) == ADDR_EXPR && decl_with_nonnull_addr_p (TREE_OPERAND (cop, 0)) @@ -4628,9 +4628,8 @@ cp_build_binary_op (const op_location_t &location, || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE)) { enum tree_code tcode0 = code0, tcode1 = code1; - tree cop1 = fold_non_dependent_expr (op1, complain); doing_div_or_mod = true; - warn_for_div_by_zero (location, cop1); + warn_for_div_by_zero (location, fold_for_warn (op1)); if (tcode0 == COMPLEX_TYPE || tcode0 == VECTOR_TYPE) tcode0 = TREE_CODE (TREE_TYPE (TREE_TYPE (op0))); @@ -4669,11 +4668,8 @@ cp_build_binary_op (const op_location_t &location, case TRUNC_MOD_EXPR: case FLOOR_MOD_EXPR: - { - tree cop1 = fold_non_dependent_expr (op1, complain); - doing_div_or_mod = true; - warn_for_div_by_zero (location, cop1); - } + doing_div_or_mod = true; + warn_for_div_by_zero (location, fold_for_warn (op1)); if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE @@ -4766,7 +4762,7 @@ cp_build_binary_op (const op_location_t &location, } else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) { - tree const_op1 = fold_non_dependent_expr (op1, complain); + tree const_op1 = fold_for_warn (op1); if (TREE_CODE (const_op1) != INTEGER_CST) const_op1 = op1; result_type = type0; @@ -4812,10 +4808,10 @@ cp_build_binary_op (const op_location_t &location, } else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) { - tree const_op0 = fold_non_dependent_expr (op0, complain); + tree const_op0 = fold_for_warn (op0); if (TREE_CODE (const_op0) != INTEGER_CST) const_op0 = op0; - tree const_op1 = fold_non_dependent_expr (op1, complain); + tree const_op1 = fold_for_warn (op1); if (TREE_CODE (const_op1) != INTEGER_CST) const_op1 = op1; result_type = type0; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0761ba1..862e55d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-01 Marek Polacek + + PR c++/91129 - wrong error with binary op in template argument. + * g++.dg/cpp1y/nontype1.C: New test. + 2019-09-01 Iain Sandoe * gcc.c-torture/compile/20190827-1.c: Add dg-requires-alias. diff --git a/gcc/testsuite/g++.dg/cpp1y/nontype1.C b/gcc/testsuite/g++.dg/cpp1y/nontype1.C new file mode 100644 index 0000000..a37e996 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/nontype1.C @@ -0,0 +1,42 @@ +// PR c++/91129 - wrong error with binary op in template argument. +// { dg-do compile { target c++14 } } + +template +struct C +{ + constexpr operator T() const { return v; } + constexpr auto operator()() const { return v; } +}; + +template +struct A +{ +}; + +template +void foo () +{ + A{}> a0; + A{}> a1; + A{}> a2; + A{}> a3; + A{}> a4; + A{}> a5; + A{}> a6; + A{}> a7; + A{}> a8; + A{}> a9; + A{}> a10; + A> C{})> a11; + A{}> a12; + A{}> a13; + A{}> a14; + A{}> a15; + A{}> a16; + A{}> a17; +} + +int main() +{ + foo<10>(); +} -- cgit v1.1 From ea323e9e926409ea4ea6317d81255b43020e4f1c Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Mon, 2 Sep 2019 00:16:37 +0000 Subject: Daily bump. From-SVN: r275290 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index de7aab4..4dad3d2 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20190901 +20190902 -- cgit v1.1 From 9297e013293e4d332fc7c40859ea4dd9616e0d88 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Mon, 2 Sep 2019 09:06:54 +0200 Subject: Consider also negative edges in cycle detection. 2019-09-02 Martin Liska PR gcov-profile/91601 * gcov.c (path_contains_zero_cycle_arc): Rename to ... (path_contains_zero_or_negative_cycle_arc): ... this and handle also negative edges. (circuit): Handle also negative edges as they can happen in some situations. From-SVN: r275291 --- gcc/ChangeLog | 9 +++++++++ gcc/gcov.c | 10 +++++----- 2 files changed, 14 insertions(+), 5 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f17b4d5..6a4f02d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2019-09-02 Martin Liska + + PR gcov-profile/91601 + * gcov.c (path_contains_zero_cycle_arc): Rename to ... + (path_contains_zero_or_negative_cycle_arc): ... this and handle + also negative edges. + (circuit): Handle also negative edges as they can happen + in some situations. + 2019-09-01 Eric Botcazou PR target/91472 diff --git a/gcc/gcov.c b/gcc/gcov.c index c65b715..f4e65ee 100644 --- a/gcc/gcov.c +++ b/gcc/gcov.c @@ -730,10 +730,10 @@ unblock (const block_info *u, block_vector_t &blocked, /* Return true when PATH contains a zero cycle arc count. */ static bool -path_contains_zero_cycle_arc (arc_vector_t &path) +path_contains_zero_or_negative_cycle_arc (arc_vector_t &path) { for (unsigned i = 0; i < path.size (); i++) - if (path[i]->cs_count == 0) + if (path[i]->cs_count <= 0) return true; return false; } @@ -759,7 +759,7 @@ circuit (block_info *v, arc_vector_t &path, block_info *start, { block_info *w = arc->dst; if (w < start - || arc->cs_count == 0 + || arc->cs_count <= 0 || !linfo.has_block (w)) continue; @@ -770,7 +770,7 @@ circuit (block_info *v, arc_vector_t &path, block_info *start, handle_cycle (path, count); loop_found = true; } - else if (!path_contains_zero_cycle_arc (path) + else if (!path_contains_zero_or_negative_cycle_arc (path) && find (blocked.begin (), blocked.end (), w) == blocked.end ()) loop_found |= circuit (w, path, start, blocked, block_lists, linfo, count); @@ -785,7 +785,7 @@ circuit (block_info *v, arc_vector_t &path, block_info *start, { block_info *w = arc->dst; if (w < start - || arc->cs_count == 0 + || arc->cs_count <= 0 || !linfo.has_block (w)) continue; -- cgit v1.1 From ae0d3f6a593058ab9fd56a34f604852ea2dec79b Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Mon, 2 Sep 2019 09:07:11 +0200 Subject: Use cxx_printable_name for __PRETTY_FUNCTION__ in cp_fname_init. 2019-09-02 Martin Liska PR c++/91155 * c-common.c (fname_as_string): Use cxx_printable_name for __PRETTY_FUNCTION__ same as was used before r265711. 2019-09-02 Martin Liska PR c++/91155 * g++.dg/torture/pr91155.C: New test. From-SVN: r275292 --- gcc/c-family/ChangeLog | 6 ++++++ gcc/cp/decl.c | 20 +++++++++++++++++--- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/torture/pr91155.C | 18 ++++++++++++++++++ 4 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/torture/pr91155.C (limited to 'gcc') diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 8b4e75c..1723dda 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2019-09-02 Martin Liska + + PR c++/91155 + * c-common.c (fname_as_string): Use cxx_printable_name for + __PRETTY_FUNCTION__ same as was used before r265711. + 2019-08-28 Marek Polacek Implement P1152R4: Deprecating some uses of volatile. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 3497874..6de95cd 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -4511,13 +4511,27 @@ cp_fname_init (const char* name, tree *type_p) static tree cp_make_fname_decl (location_t loc, tree id, int type_dep) { - const char *const name = (type_dep && in_template_function () - ? NULL : fname_as_string (type_dep)); + const char * name = NULL; + bool release_name = false; + if (!(type_dep && in_template_function ())) + { + if (current_function_decl == NULL_TREE) + name = "top level"; + else if (type_dep == 1) /* __PRETTY_FUNCTION__ */ + name = cxx_printable_name (current_function_decl, 2); + else if (type_dep == 0) /* __FUNCTION__ */ + { + name = fname_as_string (type_dep); + release_name = true; + } + else + gcc_unreachable (); + } tree type; tree init = cp_fname_init (name, &type); tree decl = build_decl (loc, VAR_DECL, id, type); - if (name) + if (release_name) free (CONST_CAST (char *, name)); /* As we're using pushdecl_with_scope, we must set the context. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 862e55d..947a653 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-02 Martin Liska + + PR c++/91155 + * g++.dg/torture/pr91155.C: New test. + 2019-09-01 Marek Polacek PR c++/91129 - wrong error with binary op in template argument. diff --git a/gcc/testsuite/g++.dg/torture/pr91155.C b/gcc/testsuite/g++.dg/torture/pr91155.C new file mode 100644 index 0000000..04e4f7a --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr91155.C @@ -0,0 +1,18 @@ +/* PR c++/91155. */ + +template< char C > struct dummy {}; + +template< typename T > const char *test() +{ + __builtin_printf ("test: %s\n", __PRETTY_FUNCTION__); + return __PRETTY_FUNCTION__; +} + +int main() +{ + if (__builtin_strcmp ("const char* test() [with T = dummy<\'\\000\'>]", test< dummy< '\0' > > ()) != 0) + {};// __builtin_abort (); + if (__builtin_strcmp ("const char* test() [with T = dummy<\'\\\'\'>]", test< dummy< '\'' > > ()) != 0) + {};// __builtin_abort (); + return 0; +} -- cgit v1.1 From 1acbaa7530d7ec1e38fe8f5f1c5313b0d12a4f97 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Mon, 2 Sep 2019 09:09:39 +0200 Subject: Fix thinko in early bail out in tree-switch-conversion. 2019-09-02 Martin Liska * tree-switch-conversion.c (jump_table_cluster::find_jump_tables): Bail out when we'll end up with the same number of clusters as at the beginning. (bit_test_cluster::find_bit_tests): Likewise for bit tests. (jump_table_cluster::can_be_handled): Remove the guard as it's already handled in ::is_enabled. Allocate output after early bail out. From-SVN: r275293 --- gcc/ChangeLog | 10 ++++++++++ gcc/tree-switch-conversion.c | 18 ++++++++---------- 2 files changed, 18 insertions(+), 10 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6a4f02d..990c895 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,15 @@ 2019-09-02 Martin Liska + * tree-switch-conversion.c (jump_table_cluster::find_jump_tables): + Bail out when we'll end up with the same number of clusters as + at the beginning. + (bit_test_cluster::find_bit_tests): Likewise for bit tests. + (jump_table_cluster::can_be_handled): Remove the guard + as it's already handled in ::is_enabled. Allocate output + after early bail out. + +2019-09-02 Martin Liska + PR gcov-profile/91601 * gcov.c (path_contains_zero_cycle_arc): Rename to ... (path_contains_zero_or_negative_cycle_arc): ... this and handle diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c index e8692a7..b714903 100644 --- a/gcc/tree-switch-conversion.c +++ b/gcc/tree-switch-conversion.c @@ -1214,14 +1214,14 @@ jump_table_cluster::find_jump_tables (vec &clusters) } /* No result. */ - if (min[l].m_count == INT_MAX) + if (min[l].m_count == l) return clusters.copy (); vec output; output.create (4); /* Find and build the clusters. */ - for (int end = l;;) + for (unsigned int end = l;;) { int start = min[end].m_start; @@ -1258,11 +1258,9 @@ jump_table_cluster::can_be_handled (const vec &clusters, make a sequence of conditional branches instead of a dispatch. The definition of "much bigger" depends on whether we are - optimizing for size or for speed. */ - if (!flag_jump_tables) - return false; + optimizing for size or for speed. - /* For algorithm correctness, jump table for a single case must return + For algorithm correctness, jump table for a single case must return true. We bail out in is_beneficial if it's called just for a single case. */ if (start == end) @@ -1312,9 +1310,6 @@ jump_table_cluster::is_beneficial (const vec &, vec bit_test_cluster::find_bit_tests (vec &clusters) { - vec output; - output.create (4); - unsigned l = clusters.length (); auto_vec min; min.reserve (l + 1); @@ -1337,9 +1332,12 @@ bit_test_cluster::find_bit_tests (vec &clusters) } /* No result. */ - if (min[l].m_count == INT_MAX) + if (min[l].m_count == l) return clusters.copy (); + vec output; + output.create (4); + /* Find and build the clusters. */ for (unsigned end = l;;) { -- cgit v1.1 From 0f605e4049160519f72d1824b3307ff8cdfc31dd Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Mon, 2 Sep 2019 08:14:47 +0000 Subject: gimple-ssa-strength-reduction.c (valid_mem_ref_cand_p): New function. * gimple-ssa-strength-reduction.c (valid_mem_ref_cand_p): New function. (replace_ref): Do not replace a chain of only two candidates which are valid memory references. From-SVN: r275297 --- gcc/ChangeLog | 6 ++++++ gcc/gimple-ssa-strength-reduction.c | 27 +++++++++++++++++++++++++++ gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.dg/tree-ssa/slsr-42.c | 17 +++++++++++++++++ 4 files changed, 54 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/slsr-42.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 990c895..c585787 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-09-02 Eric Botcazou + + * gimple-ssa-strength-reduction.c (valid_mem_ref_cand_p): New function. + (replace_ref): Do not replace a chain of only two candidates which are + valid memory references. + 2019-09-02 Martin Liska * tree-switch-conversion.c (jump_table_cluster::find_jump_tables): diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c index d343da0..de7f360 100644 --- a/gcc/gimple-ssa-strength-reduction.c +++ b/gcc/gimple-ssa-strength-reduction.c @@ -1999,6 +1999,23 @@ replace_ref (tree *expr, slsr_cand_t c) update_stmt (c->cand_stmt); } +/* Return true if CAND_REF candidate C is a valid memory reference. */ + +static bool +valid_mem_ref_cand_p (slsr_cand_t c) +{ + if (TREE_CODE (TREE_OPERAND (c->stride, 1)) != INTEGER_CST) + return false; + + struct mem_address addr + = { NULL_TREE, c->base_expr, TREE_OPERAND (c->stride, 0), + TREE_OPERAND (c->stride, 1), wide_int_to_tree (sizetype, c->index) }; + + return + valid_mem_ref_p (TYPE_MODE (c->cand_type), TYPE_ADDR_SPACE (c->cand_type), + &addr); +} + /* Replace CAND_REF candidate C, each sibling of candidate C, and each dependent of candidate C with an equivalent strength-reduced data reference. */ @@ -2006,6 +2023,16 @@ replace_ref (tree *expr, slsr_cand_t c) static void replace_refs (slsr_cand_t c) { + /* Replacing a chain of only 2 candidates which are valid memory references + is generally counter-productive because you cannot recoup the additional + calculation added in front of them. */ + if (c->basis == 0 + && c->dependent + && !lookup_cand (c->dependent)->dependent + && valid_mem_ref_cand_p (c) + && valid_mem_ref_cand_p (lookup_cand (c->dependent))) + return; + if (dump_file && (dump_flags & TDF_DETAILS)) { fputs ("Replacing reference: ", dump_file); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 947a653..b6dbf76 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-09-02 Eric Botcazou + + * gcc.dg/tree-ssa/slsr-42.c: New test. + 2019-09-02 Martin Liska PR c++/91155 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/slsr-42.c b/gcc/testsuite/gcc.dg/tree-ssa/slsr-42.c new file mode 100644 index 0000000..0495fcf --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/slsr-42.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-slsr-details" } */ + +struct x +{ + int a[16]; + int b[16]; +}; + +void +set (struct x *p, unsigned int n, int i) +{ + p->a[n] = i; + p->b[n] = i; +} + +/* { dg-final { scan-tree-dump-not "Replacing reference: " "slsr" { target i?86-*-* x86_64-*-* } } } */ -- cgit v1.1 From 976f9aa1e8b30112c0932b761e815cafcc69641f Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 2 Sep 2019 10:38:13 +0200 Subject: re PR go/91617 (Many go test case failures after r275026) PR go/91617 * fold-const.c (range_check_type): For enumeral and boolean type, pass 1 to type_for_size langhook instead of TYPE_UNSIGNED (etype). Return unsigned_type_for result whenever etype isn't TYPE_UNSIGNED INTEGER_TYPE. (build_range_check): Don't call unsigned_type_for for pointer types. * match.pd (X / C1 op C2): Don't call unsigned_type_for on range_check_type result. From-SVN: r275299 --- gcc/ChangeLog | 11 +++++++++++ gcc/fold-const.c | 10 ++++------ gcc/match.pd | 2 -- 3 files changed, 15 insertions(+), 8 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c585787..a6bcdf9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2019-09-02 Jakub Jelinek + + PR go/91617 + * fold-const.c (range_check_type): For enumeral and boolean + type, pass 1 to type_for_size langhook instead of + TYPE_UNSIGNED (etype). Return unsigned_type_for result whenever + etype isn't TYPE_UNSIGNED INTEGER_TYPE. + (build_range_check): Don't call unsigned_type_for for pointer types. + * match.pd (X / C1 op C2): Don't call unsigned_type_for on + range_check_type result. + 2019-09-02 Eric Botcazou * gimple-ssa-strength-reduction.c (valid_mem_ref_cand_p): New function. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 0376cdb..a99dafe 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -4938,10 +4938,9 @@ range_check_type (tree etype) /* First make sure that arithmetics in this type is valid, then make sure that it wraps around. */ if (TREE_CODE (etype) == ENUMERAL_TYPE || TREE_CODE (etype) == BOOLEAN_TYPE) - etype = lang_hooks.types.type_for_size (TYPE_PRECISION (etype), - TYPE_UNSIGNED (etype)); + etype = lang_hooks.types.type_for_size (TYPE_PRECISION (etype), 1); - if (TREE_CODE (etype) == INTEGER_TYPE && !TYPE_OVERFLOW_WRAPS (etype)) + if (TREE_CODE (etype) == INTEGER_TYPE && !TYPE_UNSIGNED (etype)) { tree utype, minv, maxv; @@ -4959,6 +4958,8 @@ range_check_type (tree etype) else return NULL_TREE; } + else if (POINTER_TYPE_P (etype)) + etype = unsigned_type_for (etype); return etype; } @@ -5049,9 +5050,6 @@ build_range_check (location_t loc, tree type, tree exp, int in_p, if (etype == NULL_TREE) return NULL_TREE; - if (POINTER_TYPE_P (etype)) - etype = unsigned_type_for (etype); - high = fold_convert_loc (loc, etype, high); low = fold_convert_loc (loc, etype, low); exp = fold_convert_loc (loc, etype, exp); diff --git a/gcc/match.pd b/gcc/match.pd index 13e41a9..cd75dac 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1569,8 +1569,6 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) tree etype = range_check_type (TREE_TYPE (@0)); if (etype) { - if (! TYPE_UNSIGNED (etype)) - etype = unsigned_type_for (etype); hi = fold_convert (etype, hi); lo = fold_convert (etype, lo); hi = const_binop (MINUS_EXPR, etype, hi, lo); -- cgit v1.1 From 000a5f8d23c04cc52f265519fccf37c81b5a0bad Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Mon, 2 Sep 2019 10:10:23 +0000 Subject: re PR target/91323 (LTGT rtx produces UCOMISS instead of COMISS) PR target/91323 * doc/generic.texi (LTGT_EXPR): Merge with other comparison operators. * rtl.def (LTGT): Likewise. Add note about floating-point exceptions. * tree.def (LTGT_EXPR): Likewise. * config/sparc/sparc.c (select_cc_mode): Return CCFPEmode for LTGT. From-SVN: r275303 --- gcc/ChangeLog | 8 ++++++++ gcc/config/sparc/sparc.c | 2 +- gcc/doc/generic.texi | 26 +++++++++++++------------- gcc/rtl.def | 14 ++++++++------ gcc/tree.def | 15 ++++++++------- 5 files changed, 38 insertions(+), 27 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a6bcdf9..25f8478 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2019-09-02 Eric Botcazou + + PR target/91323 + * doc/generic.texi (LTGT_EXPR): Merge with other comparison operators. + * rtl.def (LTGT): Likewise. Add note about floating-point exceptions. + * tree.def (LTGT_EXPR): Likewise. + * config/sparc/sparc.c (select_cc_mode): Return CCFPEmode for LTGT. + 2019-09-02 Jakub Jelinek PR go/91617 diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 634a334..32767bc 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -3203,13 +3203,13 @@ select_cc_mode (enum rtx_code op, rtx x, rtx y) case UNGT: case UNGE: case UNEQ: - case LTGT: return CCFPmode; case LT: case LE: case GT: case GE: + case LTGT: return CCFPEmode; default: diff --git a/gcc/doc/generic.texi b/gcc/doc/generic.texi index 86a53cc..94e339c 100644 --- a/gcc/doc/generic.texi +++ b/gcc/doc/generic.texi @@ -1564,21 +1564,23 @@ allows the backend to choose between the faster of @code{TRUNC_DIV_EXPR}, @itemx LE_EXPR @itemx GT_EXPR @itemx GE_EXPR +@itemx LTGT_EXPR @itemx EQ_EXPR @itemx NE_EXPR -These nodes represent the less than, less than or equal to, greater -than, greater than or equal to, equal, and not equal comparison -operators. The first and second operands will either be both of integral -type, both of floating type or both of vector type. The result type of -these expressions will always be of integral, boolean or signed integral -vector type. These operations return the result type's zero value for -false, the result type's one value for true, and a vector whose elements -are zero (false) or minus one (true) for vectors. +These nodes represent the less than, less than or equal to, greater than, +greater than or equal to, less or greater than, equal, and not equal +comparison operators. The first and second operands will either be both +of integral type, both of floating type or both of vector type, except for +LTGT_EXPR where they will only be both of floating type. The result type +of these expressions will always be of integral, boolean or signed integral +vector type. These operations return the result type's zero value for false, +the result type's one value for true, and a vector whose elements are zero +(false) or minus one (true) for vectors. For floating point comparisons, if we honor IEEE NaNs and either operand is NaN, then @code{NE_EXPR} always returns true and the remaining operators always return false. On some targets, comparisons against an IEEE NaN, -other than equality and inequality, may generate a floating point exception. +other than equality and inequality, may generate a floating-point exception. @item ORDERED_EXPR @itemx UNORDERED_EXPR @@ -1596,15 +1598,13 @@ and the result type's one value for true. @itemx UNGT_EXPR @itemx UNGE_EXPR @itemx UNEQ_EXPR -@itemx LTGT_EXPR These nodes represent the unordered comparison operators. These operations take two floating point operands and determine whether the operands are unordered or are less than, less than or equal to, greater than, greater than or equal to, or equal respectively. For example, @code{UNLT_EXPR} returns true if either operand is an IEEE -NaN or the first operand is less than the second. With the possible -exception of @code{LTGT_EXPR}, all of these operations are guaranteed -not to generate a floating point exception. The result +NaN or the first operand is less than the second. All these operations +are guaranteed not to generate a floating point exception. The result type of these expressions will always be of integral or boolean type. These operations return the result type's zero value for false, and the result type's one value for true. diff --git a/gcc/rtl.def b/gcc/rtl.def index 63b09b3..c756af8 100644 --- a/gcc/rtl.def +++ b/gcc/rtl.def @@ -552,20 +552,25 @@ DEF_RTL_EXPR(POST_INC, "post_inc", "e", RTX_AUTOINC) DEF_RTL_EXPR(PRE_MODIFY, "pre_modify", "ee", RTX_AUTOINC) DEF_RTL_EXPR(POST_MODIFY, "post_modify", "ee", RTX_AUTOINC) -/* Comparison operations. The ordered comparisons exist in two - flavors, signed and unsigned. */ +/* Comparison operations. The first 6 are allowed only for integral, +floating-point and vector modes. LTGT is only allowed for floating-point +modes. The last 4 are allowed only for integral and vector modes. +For floating-point operations, if either operand is a NaN, then NE returns +true and the remaining operations return false. The operations other than +EQ and NE may generate an exception on quiet NaNs. */ DEF_RTL_EXPR(NE, "ne", "ee", RTX_COMM_COMPARE) DEF_RTL_EXPR(EQ, "eq", "ee", RTX_COMM_COMPARE) DEF_RTL_EXPR(GE, "ge", "ee", RTX_COMPARE) DEF_RTL_EXPR(GT, "gt", "ee", RTX_COMPARE) DEF_RTL_EXPR(LE, "le", "ee", RTX_COMPARE) DEF_RTL_EXPR(LT, "lt", "ee", RTX_COMPARE) +DEF_RTL_EXPR(LTGT, "ltgt", "ee", RTX_COMM_COMPARE) DEF_RTL_EXPR(GEU, "geu", "ee", RTX_COMPARE) DEF_RTL_EXPR(GTU, "gtu", "ee", RTX_COMPARE) DEF_RTL_EXPR(LEU, "leu", "ee", RTX_COMPARE) DEF_RTL_EXPR(LTU, "ltu", "ee", RTX_COMPARE) -/* Additional floating point unordered comparison flavors. */ +/* Additional floating-point unordered comparison flavors. */ DEF_RTL_EXPR(UNORDERED, "unordered", "ee", RTX_COMM_COMPARE) DEF_RTL_EXPR(ORDERED, "ordered", "ee", RTX_COMM_COMPARE) @@ -576,9 +581,6 @@ DEF_RTL_EXPR(UNGT, "ungt", "ee", RTX_COMPARE) DEF_RTL_EXPR(UNLE, "unle", "ee", RTX_COMPARE) DEF_RTL_EXPR(UNLT, "unlt", "ee", RTX_COMPARE) -/* This is an ordered NE, ie !UNEQ, ie false for NaN. */ -DEF_RTL_EXPR(LTGT, "ltgt", "ee", RTX_COMM_COMPARE) - /* Represents the result of sign-extending the sole operand. The machine modes of the operand and of the SIGN_EXTEND expression determine how much sign-extension is going on. */ diff --git a/gcc/tree.def b/gcc/tree.def index bfb486d..fb6e734 100644 --- a/gcc/tree.def +++ b/gcc/tree.def @@ -793,9 +793,12 @@ DEFTREECODE (TRUTH_XOR_EXPR, "truth_xor_expr", tcc_expression, 2) DEFTREECODE (TRUTH_NOT_EXPR, "truth_not_expr", tcc_expression, 1) /* Relational operators. - `EQ_EXPR' and `NE_EXPR' are allowed for any types. - The others are allowed only for integer (or pointer or enumeral) - or real types. + EQ_EXPR and NE_EXPR are allowed for any types. The others, except for + LTGT_EXPR, are allowed only for integral, floating-point and vector types. + LTGT_EXPR is allowed only for floating-point types. + For floating-point operators, if either operand is a NaN, then NE_EXPR + returns true and the remaining operators return false. The operators + other than EQ_EXPR and NE_EXPR may generate an exception on quiet NaNs. In all cases the operands will have the same type, and the value is either the type used by the language for booleans or an integer vector type of the same size and with the same number @@ -805,10 +808,11 @@ DEFTREECODE (LT_EXPR, "lt_expr", tcc_comparison, 2) DEFTREECODE (LE_EXPR, "le_expr", tcc_comparison, 2) DEFTREECODE (GT_EXPR, "gt_expr", tcc_comparison, 2) DEFTREECODE (GE_EXPR, "ge_expr", tcc_comparison, 2) +DEFTREECODE (LTGT_EXPR, "ltgt_expr", tcc_comparison, 2) DEFTREECODE (EQ_EXPR, "eq_expr", tcc_comparison, 2) DEFTREECODE (NE_EXPR, "ne_expr", tcc_comparison, 2) -/* Additional relational operators for floating point unordered. */ +/* Additional relational operators for floating-point unordered. */ DEFTREECODE (UNORDERED_EXPR, "unordered_expr", tcc_comparison, 2) DEFTREECODE (ORDERED_EXPR, "ordered_expr", tcc_comparison, 2) @@ -819,9 +823,6 @@ DEFTREECODE (UNGT_EXPR, "ungt_expr", tcc_comparison, 2) DEFTREECODE (UNGE_EXPR, "unge_expr", tcc_comparison, 2) DEFTREECODE (UNEQ_EXPR, "uneq_expr", tcc_comparison, 2) -/* This is the reverse of uneq_expr. */ -DEFTREECODE (LTGT_EXPR, "ltgt_expr", tcc_comparison, 2) - DEFTREECODE (RANGE_EXPR, "range_expr", tcc_binary, 2) /* Represents a re-association barrier for floating point expressions -- cgit v1.1 From 1525fa83cc704ba18738eb2eab76a7f4d6bfde6b Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 2 Sep 2019 15:35:54 +0200 Subject: re PR tree-optimization/91632 (Probably wrong code since r275026) PR tree-optimization/91632 * gcc.c-torture/execute/pr91632.c: New test. From-SVN: r275318 --- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.c-torture/execute/pr91632.c | 30 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr91632.c (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b6dbf76..3f46b84 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-02 Jakub Jelinek + + PR tree-optimization/91632 + * gcc.c-torture/execute/pr91632.c: New test. + 2019-09-02 Eric Botcazou * gcc.dg/tree-ssa/slsr-42.c: New test. diff --git a/gcc/testsuite/gcc.c-torture/execute/pr91632.c b/gcc/testsuite/gcc.c-torture/execute/pr91632.c new file mode 100644 index 0000000..c16c3da --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr91632.c @@ -0,0 +1,30 @@ +/* PR tree-optimization/91632 */ +/* { dg-additional-options "-fwrapv" } */ + +static int +__attribute__((noipa)) +foo (char x) +{ + switch (x) + { + case '"': + case '<': + case '>': + case '\\': + case '^': + case '`': + case '{': + case '|': + case '}': + return 0; + } + return 1; +} + +int +main () +{ + if (foo ('h') == 0) + __builtin_abort (); + return 0; +} -- cgit v1.1 From b82c2e6fce74a6283fb3efd195d62aa6a88ef561 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Mon, 2 Sep 2019 14:26:26 +0000 Subject: re PR middle-end/91605 (ICE in ix86_avx256_split_vector_move_misalign, at config/i386/i386-expand.c:489 since r274986) 2019-09-02 Bernd Edlinger PR middle-end/91605 * expr.c (addr_expr_of_non_mem_decl_p_1): Refactor into... (non_mem_decl_p): ...this. (mem_ref_refers_to_non_mem_p): Handle DECL_P as well ase MEM_REF. (expand_assignment): Call mem_ref_referes_to_non_mem_p unconditionally as before. testsuite: 2019-09-02 Bernd Edlinger PR middle-end/91605 * g++.target/i386/pr91605.C: New test. From-SVN: r275320 --- gcc/ChangeLog | 9 ++++++++ gcc/expr.c | 37 ++++++++++++++++++++------------- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.target/i386/pr91605.C | 13 ++++++++++++ 4 files changed, 50 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/g++.target/i386/pr91605.C (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 25f8478..3a0f917 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2019-09-02 Bernd Edlinger + + PR middle-end/91605 + * expr.c (addr_expr_of_non_mem_decl_p_1): Refactor into... + (non_mem_decl_p): ...this. + (mem_ref_refers_to_non_mem_p): Handle DECL_P as well ase MEM_REF. + (expand_assignment): Call mem_ref_referes_to_non_mem_p + unconditionally as before. + 2019-09-02 Eric Botcazou PR target/91323 diff --git a/gcc/expr.c b/gcc/expr.c index 022b571..3c3f15a 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -4942,37 +4942,46 @@ get_bit_range (poly_uint64_pod *bitstart, poly_uint64_pod *bitend, tree exp, *bitend = *bitstart + tree_to_poly_uint64 (DECL_SIZE (repr)) - 1; } -/* Returns true if ADDR is an ADDR_EXPR of a DECL that does not reside - in memory and has non-BLKmode. DECL_RTL must not be a MEM; if - DECL_RTL was not set yet, return NORTL. */ +/* Returns true if BASE is a DECL that does not reside in memory and + has non-BLKmode. DECL_RTL must not be a MEM; if + DECL_RTL was not set yet, return false. */ static inline bool -addr_expr_of_non_mem_decl_p_1 (tree addr, bool nortl) +non_mem_decl_p (tree base) { - if (TREE_CODE (addr) != ADDR_EXPR) - return false; - - tree base = TREE_OPERAND (addr, 0); - if (!DECL_P (base) || TREE_ADDRESSABLE (base) || DECL_MODE (base) == BLKmode) return false; if (!DECL_RTL_SET_P (base)) - return nortl; + return false; return (!MEM_P (DECL_RTL (base))); } -/* Returns true if the MEM_REF REF refers to an object that does not +/* Returns true if REF refers to an object that does not reside in memory and has non-BLKmode. */ static inline bool mem_ref_refers_to_non_mem_p (tree ref) { - tree base = TREE_OPERAND (ref, 0); - return addr_expr_of_non_mem_decl_p_1 (base, false); + tree base; + + if (TREE_CODE (ref) == MEM_REF + || TREE_CODE (ref) == TARGET_MEM_REF) + { + tree addr = TREE_OPERAND (ref, 0); + + if (TREE_CODE (addr) != ADDR_EXPR) + return false; + + base = TREE_OPERAND (addr, 0); + } + else + base = ref; + + return non_mem_decl_p (base); } /* Expand an assignment that stores the value of FROM into TO. If NONTEMPORAL @@ -5004,7 +5013,7 @@ expand_assignment (tree to, tree from, bool nontemporal) || TREE_CODE (to) == TARGET_MEM_REF || DECL_P (to)) && mode != BLKmode - && (DECL_P (to) || !mem_ref_refers_to_non_mem_p (to)) + && !mem_ref_refers_to_non_mem_p (to) && ((align = get_object_alignment (to)) < GET_MODE_ALIGNMENT (mode)) && (((icode = optab_handler (movmisalign_optab, mode)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3f46b84..a7c473e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-02 Bernd Edlinger + + PR middle-end/91605 + * g++.target/i386/pr91605.C: New test. + 2019-09-02 Jakub Jelinek PR tree-optimization/91632 diff --git a/gcc/testsuite/g++.target/i386/pr91605.C b/gcc/testsuite/g++.target/i386/pr91605.C new file mode 100644 index 0000000..8bceedb --- /dev/null +++ b/gcc/testsuite/g++.target/i386/pr91605.C @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-fpack-struct -mavx" } */ + +struct A { + __attribute__((__vector_size__(4 * sizeof(double)))) double data; +}; +struct B { + A operator*(B); +}; +void fn1() { + B x, y; + x *y; +} -- cgit v1.1 From be0fb5484a64414878c31a1606b07175b54ecb90 Mon Sep 17 00:00:00 2001 From: "Steven G. Kargl" Date: Mon, 2 Sep 2019 16:46:54 +0000 Subject: re PR fortran/91552 (ICE with valid array constructor) 2019-09-02 Steven G. Kargl PR fortran/91552 * array.c (walk_array_constructor): New function. (gfc_match_array_constructor): Use it. 2019-09-02 Steven G. Kargl PR fortran/91552 * gfortran.dg/pr91552.f90: New test. From-SVN: r275322 --- gcc/fortran/ChangeLog | 6 ++++++ gcc/fortran/array.c | 36 +++++++++++++++++++++++++++++------ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gfortran.dg/pr91552.f90 | 10 ++++++++++ 4 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/pr91552.f90 (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 0ed86ce..b0dfb0e 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,9 @@ +2019-09-02 Steven G. Kargl + + PR fortran/91552 + * array.c (walk_array_constructor): New function. + (gfc_match_array_constructor): Use it. + 2019-09-01 Paul Thomas * array.c (spec_dimen_size): Check for the presence of diff --git a/gcc/fortran/array.c b/gcc/fortran/array.c index b972abe..ba8a816 100644 --- a/gcc/fortran/array.c +++ b/gcc/fortran/array.c @@ -1134,6 +1134,31 @@ done: } +/* Convert components of an array constructor to the type in ts. */ + +static match +walk_array_constructor (gfc_typespec *ts, gfc_constructor_base head) +{ + gfc_constructor *c; + gfc_expr *e; + match m; + + for (c = gfc_constructor_first (head); c; c = gfc_constructor_next (c)) + { + e = c->expr; + if (e->expr_type == EXPR_ARRAY && e->ts.type == BT_UNKNOWN + && !e->ref && e->value.constructor) + { + m = walk_array_constructor (ts, e->value.constructor); + if (m == MATCH_ERROR) + return m; + } + else if (!gfc_convert_type (e, ts, 1) && e->ts.type != BT_UNKNOWN) + return MATCH_ERROR; + } + return MATCH_YES; +} + /* Match an array constructor. */ match @@ -1263,14 +1288,13 @@ done: } } - /* Walk the constructor and ensure type conversion for numeric types. */ + /* Walk the constructor, and if possible, do type conversion for + numeric types. */ if (gfc_numeric_ts (&ts)) { - c = gfc_constructor_first (head); - for (; c; c = gfc_constructor_next (c)) - if (!gfc_convert_type (c->expr, &ts, 1) - && c->expr->ts.type != BT_UNKNOWN) - return MATCH_ERROR; + m = walk_array_constructor (&ts, head); + if (m == MATCH_ERROR) + return m; } } else diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a7c473e..c2608ce 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-02 Steven G. Kargl + + PR fortran/91552 + * gfortran.dg/pr91552.f90: New test. + 2019-09-02 Bernd Edlinger PR middle-end/91605 diff --git a/gcc/testsuite/gfortran.dg/pr91552.f90 b/gcc/testsuite/gfortran.dg/pr91552.f90 new file mode 100644 index 0000000..bb95918 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr91552.f90 @@ -0,0 +1,10 @@ +! { dg-do run } +! PR fortran/91552 +! Code contributed by Gerhard Steinmetz. +program p + real :: y(3), z(4) + y = 2.0 * [real :: 1, [2], 3] + z = 2.0 * [real :: 1, [2, [4]], 3] + if (any(y /= [2., 4., 6.])) stop 1 + if (any(z /= [2., 4., 8., 6.])) stop 2 +end -- cgit v1.1 From f79be3a7dbf8d9cd7e675918472ebc3c2c9d5e47 Mon Sep 17 00:00:00 2001 From: Paul Thomas Date: Mon, 2 Sep 2019 19:54:02 +0000 Subject: re PR fortran/91589 (ICE in gfc_conv_component_ref, at fortran/trans-expr.c:2447) 2019-09-02 Paul Thomas PR fortran/91589 * primary.c (gfc_match_varspec): Return MATCH_NO on an apparent component ref, when the primary type is intrinsic. 2019-09-02 Paul Thomas PR fortran/91589 * gfortran.dg/pr91589.f90 : New test. From-SVN: r275324 --- gcc/fortran/ChangeLog | 6 ++++++ gcc/fortran/primary.c | 15 ++++++++++++--- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gfortran.dg/pr91589.f90 | 15 +++++++++++++++ 4 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/pr91589.f90 (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index b0dfb0e..065099a 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,9 @@ +2019-09-02 Paul Thomas + + PR fortran/91589 + * primary.c (gfc_match_varspec): Return MATCH_NO on an apparent + component ref, when the primary type is intrinsic. + 2019-09-02 Steven G. Kargl PR fortran/91552 diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c index a33a797..e94ea82 100644 --- a/gcc/fortran/primary.c +++ b/gcc/fortran/primary.c @@ -2028,6 +2028,7 @@ gfc_match_varspec (gfc_expr *primary, int equiv_flag, bool sub_flag, match m; bool unknown; bool inquiry; + bool intrinsic; locus old_loc; char sep; @@ -2232,11 +2233,15 @@ gfc_match_varspec (gfc_expr *primary, int equiv_flag, bool sub_flag, if (m != MATCH_YES) return MATCH_ERROR; + intrinsic = false; if (primary->ts.type != BT_CLASS && primary->ts.type != BT_DERIVED) { inquiry = is_inquiry_ref (name, &tmp); if (inquiry) sym = NULL; + + if (sep == '%' && primary->ts.type != BT_UNKNOWN) + intrinsic = true; } else inquiry = false; @@ -2296,12 +2301,16 @@ gfc_match_varspec (gfc_expr *primary, int equiv_flag, bool sub_flag, break; } - if (!inquiry) + if (!inquiry && !intrinsic) component = gfc_find_component (sym, name, false, false, &tmp); else component = NULL; - if (component == NULL && !inquiry) + /* In some cases, returning MATCH_NO gives a better error message. Most + cases return "Unclassifiable statement at..." */ + if (intrinsic && !inquiry) + return MATCH_NO; + else if (component == NULL && !inquiry) return MATCH_ERROR; /* Extend the reference chain determined by gfc_find_component or @@ -2598,7 +2607,7 @@ gfc_variable_attr (gfc_expr *expr, gfc_typespec *ts) case AR_UNKNOWN: /* For standard conforming code, AR_UNKNOWN should not happen. - For nonconforming code, gfortran can end up here. Treat it + For nonconforming code, gfortran can end up here. Treat it as a no-op. */ break; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c2608ce..2f93d91 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-02 Paul Thomas + + PR fortran/91589 + * gfortran.dg/pr91589.f90 : New test. + 2019-09-02 Steven G. Kargl PR fortran/91552 diff --git a/gcc/testsuite/gfortran.dg/pr91589.f90 b/gcc/testsuite/gfortran.dg/pr91589.f90 new file mode 100644 index 0000000..d02cb64 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr91589.f90 @@ -0,0 +1,15 @@ +! { dg-do compile } +! +! Check the fix for PR91589, in which the invalid expression caused an ICE. +! Other statements using this invalid expression cause "Unclassifiable statement at..." +! +! Contributed by Gerhardt Steinmetz +! +program p + type t + integer :: a + end type + type(t) :: x = t(1) + call sub (x%a%a) ! { dg-error "Syntax error in argument list" } +end + -- cgit v1.1 From 97d6a7c80e63563390bda35b1e7126b48e3a51f3 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Tue, 3 Sep 2019 00:16:40 +0000 Subject: Daily bump. From-SVN: r275328 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 4dad3d2..f282342 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20190902 +20190903 -- cgit v1.1 From e4a8d4a7ec496dbd6602e373dcfcb72c25c60f86 Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Tue, 3 Sep 2019 06:06:02 +0000 Subject: [x86 testsuite] preserve full register across main This test uses a call-saved register as a global variable. It attempts to preserve its value across main, but only the lower int part is preserved, which is not good enough for x86_64, when the runtime that calls main() happens to hold something in the chosen register that is not a zero-extension from the 32-bit value, and rightfully expects the full register to remain unchanged when main() returns. for gcc/testsuite/ChangeLog * gcc.target/i386/20020616-1.c: Preserve full register across main. From-SVN: r275329 --- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.target/i386/20020616-1.c | 14 +++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2f93d91..efb25df 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-03 Alexandre Oliva + + * gcc.target/i386/20020616-1.c: Preserve full register across + main. + 2019-09-02 Paul Thomas PR fortran/91589 diff --git a/gcc/testsuite/gcc.target/i386/20020616-1.c b/gcc/testsuite/gcc.target/i386/20020616-1.c index 5641826..48dea27 100644 --- a/gcc/testsuite/gcc.target/i386/20020616-1.c +++ b/gcc/testsuite/gcc.target/i386/20020616-1.c @@ -2,12 +2,16 @@ /* { dg-do run } */ /* { dg-options "-O2" } */ +/* We need this type to be as wide as the register chosen below, so + that, when we preserve it across main, we preserve all of it. */ +typedef int __attribute__ ((mode (__word__))) reg_type; + #if !__PIC__ -register int k asm("%ebx"); +register reg_type k asm("%ebx"); #elif __amd64 -register int k asm("%r12"); +register reg_type k asm("%r12"); #else -register int k asm("%esi"); +register reg_type k asm("%esi"); #endif void __attribute__((noinline)) @@ -18,7 +22,7 @@ foo() void test() { - int i; + reg_type i; for (i = 0; i < 10; i += k) { k = 0; @@ -28,7 +32,7 @@ void test() int main() { - int old = k; + reg_type old = k; test(); k = old; return 0; -- cgit v1.1 From 3729852e407e5e1c4f1bbacea1b53e61d7609dad Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 3 Sep 2019 09:50:46 +0200 Subject: re PR tree-optimization/91597 (GCC miscompiles a branch depending on a pointer tag) PR tree-optimization/91597 * tree-vrp.c (extract_range_from_binary_expr): Remove unsafe BIT_AND_EXPR optimization for pointers, even if both operand ranges don't include NULL, the result can be NULL. * gcc.c-torture/execute/pr91597.c: New test. Co-Authored-By: Richard Biener From-SVN: r275330 --- gcc/ChangeLog | 8 +++++ gcc/testsuite/ChangeLog | 6 ++++ gcc/testsuite/gcc.c-torture/execute/pr91597.c | 48 +++++++++++++++++++++++++++ gcc/tree-vrp.c | 4 +-- 4 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr91597.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3a0f917..1d20ffc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2019-09-03 Jakub Jelinek + Richard Biener + + PR tree-optimization/91597 + * tree-vrp.c (extract_range_from_binary_expr): Remove unsafe + BIT_AND_EXPR optimization for pointers, even if both operand + ranges don't include NULL, the result can be NULL. + 2019-09-02 Bernd Edlinger PR middle-end/91605 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index efb25df..651baeb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2019-09-03 Jakub Jelinek + Richard Biener + + PR tree-optimization/91597 + * gcc.c-torture/execute/pr91597.c: New test. + 2019-09-03 Alexandre Oliva * gcc.target/i386/20020616-1.c: Preserve full register across diff --git a/gcc/testsuite/gcc.c-torture/execute/pr91597.c b/gcc/testsuite/gcc.c-torture/execute/pr91597.c new file mode 100644 index 0000000..6a917cb --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr91597.c @@ -0,0 +1,48 @@ +/* PR tree-optimization/91597 */ + +enum E { A, B, C }; +struct __attribute__((aligned (4))) S { enum E e; }; + +enum E +foo (struct S *o) +{ + if (((__UINTPTR_TYPE__) (o) & 1) == 0) + return o->e; + else + return A; +} + +int +bar (struct S *o) +{ + return foo (o) == B || foo (o) == C; +} + +static inline void +baz (struct S *o, int d) +{ + if (__builtin_expect (!bar (o), 0)) + __builtin_abort (); + if (d > 2) return; + baz (o, d + 1); +} + +void +qux (struct S *o) +{ + switch (o->e) + { + case A: return; + case B: baz (o, 0); break; + case C: baz (o, 0); break; + } +} + +struct S s = { C }; + +int +main () +{ + qux (&s); + return 0; +} diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index bc06480..0a7e7c7 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -1741,9 +1741,7 @@ extract_range_from_binary_expr (value_range_base *vr, { /* For pointer types, we are really only interested in asserting whether the expression evaluates to non-NULL. */ - if (!range_includes_zero_p (&vr0) && !range_includes_zero_p (&vr1)) - vr->set_nonzero (expr_type); - else if (vr0.zero_p () || vr1.zero_p ()) + if (vr0.zero_p () || vr1.zero_p ()) vr->set_zero (expr_type); else vr->set_varying (expr_type); -- cgit v1.1 From 75f935365dba3eb5e9cbd11bc0d75009cad3d019 Mon Sep 17 00:00:00 2001 From: Kyrylo Tkachov Date: Tue, 3 Sep 2019 08:06:43 +0000 Subject: [AArch64] Add Linux hwcap strings for some extensions This patch adds feature strings for some of the extensions. This string is what is read from /proc/cpuinfo on Linux systems and used during -march=native detection. The strings are taken from the kernel source tree at: https://github.com/torvalds/linux/blob/master/arch/arm64/kernel/cpuinfo.c#L45 * config/aarch64/aarch64-option-extensions.def (sb): Add feature string. (ssbs): Likewise. (sve2): Likewise. (sve2-sm4): Likewise. (sveaes): Likewise. (svesha3): Likewise. (svebitperm): Likewise. From-SVN: r275331 --- gcc/ChangeLog | 11 +++++++++++ gcc/config/aarch64/aarch64-option-extensions.def | 14 +++++++------- 2 files changed, 18 insertions(+), 7 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1d20ffc..5c4eaf2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2019-09-03 Kyrylo Tkachov + + * config/aarch64/aarch64-option-extensions.def (sb): Add feature + string. + (ssbs): Likewise. + (sve2): Likewise. + (sve2-sm4): Likewise. + (sveaes): Likewise. + (svesha3): Likewise. + (svebitperm): Likewise. + 2019-09-03 Jakub Jelinek Richard Biener diff --git a/gcc/config/aarch64/aarch64-option-extensions.def b/gcc/config/aarch64/aarch64-option-extensions.def index 9919edd..de91550 100644 --- a/gcc/config/aarch64/aarch64-option-extensions.def +++ b/gcc/config/aarch64/aarch64-option-extensions.def @@ -155,10 +155,10 @@ AARCH64_OPT_EXTENSION("rng", AARCH64_FL_RNG, 0, 0, false, "") AARCH64_OPT_EXTENSION("memtag", AARCH64_FL_MEMTAG, 0, 0, false, "") /* Enabling/Disabling "sb" only changes "sb". */ -AARCH64_OPT_EXTENSION("sb", AARCH64_FL_SB, 0, 0, false, "") +AARCH64_OPT_EXTENSION("sb", AARCH64_FL_SB, 0, 0, false, "sb") /* Enabling/Disabling "ssbs" only changes "ssbs". */ -AARCH64_OPT_EXTENSION("ssbs", AARCH64_FL_SSBS, 0, 0, false, "") +AARCH64_OPT_EXTENSION("ssbs", AARCH64_FL_SSBS, 0, 0, false, "ssbs") /* Enabling/Disabling "predres" only changes "predres". */ AARCH64_OPT_EXTENSION("predres", AARCH64_FL_PREDRES, 0, 0, false, "") @@ -169,31 +169,31 @@ AARCH64_OPT_EXTENSION("predres", AARCH64_FL_PREDRES, 0, 0, false, "") AARCH64_OPT_EXTENSION("sve2", AARCH64_FL_SVE2, AARCH64_FL_SVE | \ AARCH64_FL_FP | AARCH64_FL_SIMD | AARCH64_FL_F16, \ AARCH64_FL_SVE2_AES | AARCH64_FL_SVE2_SHA3 | \ - AARCH64_FL_SVE2_SM4 | AARCH64_FL_SVE2_BITPERM, false, "") + AARCH64_FL_SVE2_SM4 | AARCH64_FL_SVE2_BITPERM, false, "sve2") /* Enabling "sve2-sm4" also enables "sm4", "simd", "fp16", "fp", "sve", and "sve2". Disabling "sve2-sm4" just disables "sve2-sm4". */ AARCH64_OPT_EXTENSION("sve2-sm4", AARCH64_FL_SVE2_SM4, AARCH64_FL_SM4 | \ AARCH64_FL_SIMD | AARCH64_FL_F16 | AARCH64_FL_FP | \ - AARCH64_FL_SVE | AARCH64_FL_SVE2, 0, false, "") + AARCH64_FL_SVE | AARCH64_FL_SVE2, 0, false, "svesm4") /* Enabling "sve2-aes" also enables "aes", "simd", "fp16", "fp", "sve", and "sve2". Disabling "sve2-aes" just disables "sve2-aes". */ AARCH64_OPT_EXTENSION("sve2-aes", AARCH64_FL_SVE2_AES, AARCH64_FL_AES | \ AARCH64_FL_SIMD | AARCH64_FL_F16 | AARCH64_FL_FP | \ - AARCH64_FL_SVE | AARCH64_FL_SVE2, 0, false, "") + AARCH64_FL_SVE | AARCH64_FL_SVE2, 0, false, "sveaes") /* Enabling "sve2-sha3" also enables "sha3", "simd", "fp16", "fp", "sve", and "sve2". Disabling "sve2-sha3" just disables "sve2-sha3". */ AARCH64_OPT_EXTENSION("sve2-sha3", AARCH64_FL_SVE2_SHA3, AARCH64_FL_SHA3 | \ AARCH64_FL_SIMD | AARCH64_FL_F16 | AARCH64_FL_FP | \ - AARCH64_FL_SVE | AARCH64_FL_SVE2, 0, false, "") + AARCH64_FL_SVE | AARCH64_FL_SVE2, 0, false, "svesha3") /* Enabling "sve2-bitperm" also enables "simd", "fp16", "fp", "sve", and "sve2". Disabling "sve2-bitperm" just disables "sve2-bitperm". */ AARCH64_OPT_EXTENSION("sve2-bitperm", AARCH64_FL_SVE2_BITPERM, AARCH64_FL_SIMD | \ AARCH64_FL_F16 | AARCH64_FL_FP | AARCH64_FL_SVE | \ - AARCH64_FL_SVE2, 0, false, "") + AARCH64_FL_SVE2, 0, false, "svebitperm") /* Enabling or disabling "tme" only changes "tme". */ AARCH64_OPT_EXTENSION("tme", AARCH64_FL_TME, 0, 0, false, "") -- cgit v1.1 From e0664b7a63ed8305e9f8539309df7fb3eb13babe Mon Sep 17 00:00:00 2001 From: Dennis Zhang Date: Tue, 3 Sep 2019 08:27:58 +0000 Subject: [AArch64] Add support for missing CPUs This patch adds '-mcpu' options for following CPUs: Cortex-A77, Cortex-A76AE, Cortex-A65, Cortex-A65AE, and Cortex-A34. Related specifications are as following: https://developer.arm.com/ip-products/processors/cortex-a Bootstraped/regtested for aarch64-none-linux-gnu. 2019-09-03 Dennis Zhang * config/aarch64/aarch64-cores.def (AARCH64_CORE): New entries for Cortex-A77, Cortex-A76AE, Cortex-A65, Cortex-A65AE, and Cortex-A34. * config/aarch64/aarch64-tune.md: Regenerated. * doc/invoke.texi: Document the new processors. From-SVN: r275333 --- gcc/ChangeLog | 8 ++++++++ gcc/config/aarch64/aarch64-cores.def | 5 +++++ gcc/config/aarch64/aarch64-tune.md | 2 +- gcc/doc/invoke.texi | 4 +++- 4 files changed, 17 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5c4eaf2..3c90c32 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2019-09-03 Dennis Zhang + + * config/aarch64/aarch64-cores.def (AARCH64_CORE): New entries + for Cortex-A77, Cortex-A76AE, Cortex-A65, Cortex-A65AE, and + Cortex-A34. + * config/aarch64/aarch64-tune.md: Regenerated. + * doc/invoke.texi: Document the new processors. + 2019-09-03 Kyrylo Tkachov * config/aarch64/aarch64-option-extensions.def (sb): Add feature diff --git a/gcc/config/aarch64/aarch64-cores.def b/gcc/config/aarch64/aarch64-cores.def index bd257ae..053c639 100644 --- a/gcc/config/aarch64/aarch64-cores.def +++ b/gcc/config/aarch64/aarch64-cores.def @@ -46,6 +46,7 @@ /* ARMv8-A Architecture Processors. */ /* ARM ('A') cores. */ +AARCH64_CORE("cortex-a34", cortexa34, cortexa53, 8A, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC, cortexa35, 0x41, 0xd02, -1) AARCH64_CORE("cortex-a35", cortexa35, cortexa53, 8A, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC, cortexa35, 0x41, 0xd04, -1) AARCH64_CORE("cortex-a53", cortexa53, cortexa53, 8A, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC, cortexa53, 0x41, 0xd03, -1) AARCH64_CORE("cortex-a57", cortexa57, cortexa57, 8A, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC, cortexa57, 0x41, 0xd07, -1) @@ -100,6 +101,10 @@ AARCH64_CORE("thunderx2t99", thunderx2t99, thunderx2t99, 8_1A, AARCH64_FL_FOR AARCH64_CORE("cortex-a55", cortexa55, cortexa53, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD, cortexa53, 0x41, 0xd05, -1) AARCH64_CORE("cortex-a75", cortexa75, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD, cortexa73, 0x41, 0xd0a, -1) AARCH64_CORE("cortex-a76", cortexa76, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD, neoversen1, 0x41, 0xd0b, -1) +AARCH64_CORE("cortex-a76ae", cortexa76ae, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_SSBS, cortexa72, 0x41, 0xd0e, -1) +AARCH64_CORE("cortex-a77", cortexa77, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_SSBS, cortexa72, 0x41, 0xd0d, -1) +AARCH64_CORE("cortex-a65", cortexa65, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_SSBS, cortexa73, 0x41, 0xd06, -1) +AARCH64_CORE("cortex-a65ae", cortexa65ae, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_SSBS, cortexa73, 0x41, 0xd43, -1) AARCH64_CORE("ares", ares, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_PROFILE, neoversen1, 0x41, 0xd0c, -1) AARCH64_CORE("neoverse-n1", neoversen1, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_PROFILE, neoversen1, 0x41, 0xd0c, -1) AARCH64_CORE("neoverse-e1", neoversee1, cortexa53, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_SSBS, cortexa53, 0x41, 0xd4a, -1) diff --git a/gcc/config/aarch64/aarch64-tune.md b/gcc/config/aarch64/aarch64-tune.md index 2b1ec85..a6a14b7 100644 --- a/gcc/config/aarch64/aarch64-tune.md +++ b/gcc/config/aarch64/aarch64-tune.md @@ -1,5 +1,5 @@ ;; -*- buffer-read-only: t -*- ;; Generated automatically by gentune.sh from aarch64-cores.def (define_attr "tune" - "cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88p1,thunderxt88,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,ares,neoversen1,neoversee1,tsv110,saphira,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55" + "cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88p1,thunderxt88,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa65,cortexa65ae,ares,neoversen1,neoversee1,tsv110,saphira,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55" (const (symbol_ref "((enum attr_tune) aarch64_tune)"))) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 44a8801..cfa3f86 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -15953,7 +15953,9 @@ Specify the name of the target processor for which GCC should tune the performance of the code. Permissible values for this option are: @samp{generic}, @samp{cortex-a35}, @samp{cortex-a53}, @samp{cortex-a55}, @samp{cortex-a57}, @samp{cortex-a72}, @samp{cortex-a73}, @samp{cortex-a75}, -@samp{cortex-a76}, @samp{ares}, @samp{exynos-m1}, @samp{emag}, @samp{falkor}, +@samp{cortex-a76}, @samp{cortex-a76ae}, @samp{cortex-a77}, +@samp{cortex-a65}, @samp{cortex-a65ae}, @samp{cortex-a34}, +@samp{ares}, @samp{exynos-m1}, @samp{emag}, @samp{falkor}, @samp{neoverse-e1},@samp{neoverse-n1},@samp{qdf24xx}, @samp{saphira}, @samp{phecda}, @samp{xgene1}, @samp{vulcan}, @samp{octeontx}, @samp{octeontx81}, @samp{octeontx83}, @samp{thunderx}, @samp{thunderxt88}, -- cgit v1.1 From 10bd1d964ef12daa9f92ff0b8d1e5f600aa63f7b Mon Sep 17 00:00:00 2001 From: Kyrylo Tkachov Date: Tue, 3 Sep 2019 08:38:08 +0000 Subject: [AArch64] Implement ACLE intrinsics for FRINT[32,64][Z,X] This patch implements the ACLE intrinsics to access the FRINT[32,64][Z,X] scalar[1] and vector[2][3] instructions from Armv8.5-a. These are enabled when the __ARM_FEATURE_FRINT macro is defined. They're added in a fairly standard way through builtins and unspecs at the RTL level. * config/aarch64/aarch64.md ("unspec"): Add UNSPEC_FRINT32Z, UNSPEC_FRINT32X, UNSPEC_FRINT64Z, UNSPEC_FRINT64X. (aarch64_): New define_insn. * config/aarch64/aarch64.h (TARGET_FRINT): Define. * config/aarch64/aarch64-c.c (aarch64_update_cpp_builtins): Define __ARM_FEATURE_FRINT when appropriate. * config/aarch64/aarch64-simd-builtins.def: Add builtins for frint32z, frint32x, frint64z, frint64x. * config/aarch64/arm_acle.h (__rint32zf, __rint32z, __rint64zf, __rint64z, __rint32xf, __rint32x, __rint64xf, __rint64x): Define. * config/aarch64/arm_neon.h (vrnd32z_f32, vrnd32zq_f32, vrnd32z_f64, vrnd32zq_f64, vrnd32x_f32, vrnd32xq_f32, vrnd32x_f64, vrnd32xq_f64, vrnd64z_f32, vrnd64zq_f32, vrnd64z_f64, vrnd64zq_f64, vrnd64x_f32, vrnd64xq_f32, vrnd64x_f64, vrnd64xq_f64): Define. * config/aarch64/iterators.md (VSFDF): Define. (FRINTNZX): Likewise. (frintnzs_op): Likewise. * gcc.target/aarch64/acle/rintnzx_1.c: New test. * gcc.target/aarch64/simd/vrndnzx_1.c: Likewise. From-SVN: r275334 --- gcc/ChangeLog | 20 ++++ gcc/config/aarch64/aarch64-c.c | 1 + gcc/config/aarch64/aarch64-simd-builtins.def | 6 + gcc/config/aarch64/aarch64.h | 3 + gcc/config/aarch64/aarch64.md | 14 +++ gcc/config/aarch64/arm_acle.h | 53 +++++++++ gcc/config/aarch64/arm_neon.h | 118 +++++++++++++++++++ gcc/config/aarch64/iterators.md | 9 ++ gcc/testsuite/ChangeLog | 5 + gcc/testsuite/gcc.target/aarch64/acle/rintnzx_1.c | 73 ++++++++++++ gcc/testsuite/gcc.target/aarch64/simd/vrndnzx_1.c | 137 ++++++++++++++++++++++ 11 files changed, 439 insertions(+) create mode 100644 gcc/testsuite/gcc.target/aarch64/acle/rintnzx_1.c create mode 100644 gcc/testsuite/gcc.target/aarch64/simd/vrndnzx_1.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3c90c32..c6df078 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +2019-09-03 Kyrylo Tkachov + + * config/aarch64/aarch64.md ("unspec"): Add UNSPEC_FRINT32Z, + UNSPEC_FRINT32X, UNSPEC_FRINT64Z, UNSPEC_FRINT64X. + (aarch64_): New define_insn. + * config/aarch64/aarch64.h (TARGET_FRINT): Define. + * config/aarch64/aarch64-c.c (aarch64_update_cpp_builtins): Define + __ARM_FEATURE_FRINT when appropriate. + * config/aarch64/aarch64-simd-builtins.def: Add builtins for frint32z, + frint32x, frint64z, frint64x. + * config/aarch64/arm_acle.h (__rint32zf, __rint32z, __rint64zf, + __rint64z, __rint32xf, __rint32x, __rint64xf, __rint64x): Define. + * config/aarch64/arm_neon.h (vrnd32z_f32, vrnd32zq_f32, vrnd32z_f64, + vrnd32zq_f64, vrnd32x_f32, vrnd32xq_f32, vrnd32x_f64, vrnd32xq_f64, + vrnd64z_f32, vrnd64zq_f32, vrnd64z_f64, vrnd64zq_f64, vrnd64x_f32, + vrnd64xq_f32, vrnd64x_f64, vrnd64xq_f64): Define. + * config/aarch64/iterators.md (VSFDF): Define. + (FRINTNZX): Likewise. + (frintnzs_op): Likewise. + 2019-09-03 Dennis Zhang * config/aarch64/aarch64-cores.def (AARCH64_CORE): New entries diff --git a/gcc/config/aarch64/aarch64-c.c b/gcc/config/aarch64/aarch64-c.c index e532c6c..c05efed 100644 --- a/gcc/config/aarch64/aarch64-c.c +++ b/gcc/config/aarch64/aarch64-c.c @@ -157,6 +157,7 @@ aarch64_update_cpp_builtins (cpp_reader *pfile) aarch64_def_or_undef (TARGET_SM4, "__ARM_FEATURE_SM4", pfile); aarch64_def_or_undef (TARGET_F16FML, "__ARM_FEATURE_FP16_FML", pfile); + aarch64_def_or_undef (TARGET_FRINT, "__ARM_FEATURE_FRINT", pfile); aarch64_def_or_undef (TARGET_TME, "__ARM_FEATURE_TME", pfile); /* Not for ACLE, but required to keep "float.h" correct if we switch diff --git a/gcc/config/aarch64/aarch64-simd-builtins.def b/gcc/config/aarch64/aarch64-simd-builtins.def index 779111a..f4ca35a 100644 --- a/gcc/config/aarch64/aarch64-simd-builtins.def +++ b/gcc/config/aarch64/aarch64-simd-builtins.def @@ -676,3 +676,9 @@ /* Implemented by aarch64_fmllq_laneq_highv4sf. */ VAR1 (QUADOP_LANE, fmlalq_laneq_high, 0, v4sf) VAR1 (QUADOP_LANE, fmlslq_laneq_high, 0, v4sf) + + /* Implemented by aarch64_. */ + BUILTIN_VSFDF (UNOP, frint32z, 0) + BUILTIN_VSFDF (UNOP, frint32x, 0) + BUILTIN_VSFDF (UNOP, frint64z, 0) + BUILTIN_VSFDF (UNOP, frint64x, 0) diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h index 0c27d90..e621238 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -291,6 +291,9 @@ extern unsigned aarch64_architecture_version; /* Armv8.3-a Complex number extension to AdvSIMD extensions. */ #define TARGET_COMPLEX (TARGET_SIMD && TARGET_ARMV8_3) +/* Floating-point rounding instructions from Armv8.5-a. */ +#define TARGET_FRINT (AARCH64_ISA_V8_5 && TARGET_FLOAT) + /* TME instructions are enabled. */ #define TARGET_TME (AARCH64_ISA_TME) diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 88e04df..f1f9b21 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -141,6 +141,10 @@ UNSPEC_CRC32X UNSPEC_FCVTZS UNSPEC_FCVTZU + UNSPEC_FRINT32Z + UNSPEC_FRINT32X + UNSPEC_FRINT64Z + UNSPEC_FRINT64X UNSPEC_URECPE UNSPEC_FRECPE UNSPEC_FRECPS @@ -7306,6 +7310,16 @@ (set_attr "speculation_barrier" "true")] ) +(define_insn "aarch64_" + [(set (match_operand:VSFDF 0 "register_operand" "=w") + (unspec:VSFDF [(match_operand:VSFDF 1 "register_operand" "w")] + FRINTNZX))] + "TARGET_FRINT && TARGET_FLOAT + && !(VECTOR_MODE_P (mode) && !TARGET_SIMD)" + "\\t%0, %1" + [(set_attr "type" "f_rint")] +) + ;; Transactional Memory Extension (TME) instructions. (define_insn "tstart" diff --git a/gcc/config/aarch64/arm_acle.h b/gcc/config/aarch64/arm_acle.h index d4de691..01a82be 100644 --- a/gcc/config/aarch64/arm_acle.h +++ b/gcc/config/aarch64/arm_acle.h @@ -34,6 +34,59 @@ extern "C" { #endif #pragma GCC push_options +#pragma GCC target ("arch=armv8.5-a") +__extension__ static __inline float __attribute__ ((__always_inline__)) +__rint32zf (float __a) +{ + return __builtin_aarch64_frint32zsf (__a); +} + +__extension__ static __inline double __attribute__ ((__always_inline__)) +__rint32z (double __a) +{ + return __builtin_aarch64_frint32zdf (__a); +} + +__extension__ static __inline float __attribute__ ((__always_inline__)) +__rint64zf (float __a) +{ + return __builtin_aarch64_frint64zsf (__a); +} + +__extension__ static __inline double __attribute__ ((__always_inline__)) +__rint64z (double __a) +{ + return __builtin_aarch64_frint64zdf (__a); +} + +__extension__ static __inline float __attribute__ ((__always_inline__)) +__rint32xf (float __a) +{ + return __builtin_aarch64_frint32xsf (__a); +} + +__extension__ static __inline double __attribute__ ((__always_inline__)) +__rint32x (double __a) +{ + return __builtin_aarch64_frint32xdf (__a); +} + +__extension__ static __inline float __attribute__ ((__always_inline__)) +__rint64xf (float __a) +{ + return __builtin_aarch64_frint64xsf (__a); +} + +__extension__ static __inline double __attribute__ ((__always_inline__)) +__rint64x (double __a) +{ + return __builtin_aarch64_frint64xdf (__a); +} + + +#pragma GCC pop_options + +#pragma GCC push_options #pragma GCC target ("+nothing+crc") diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h index 9ecc00c..e1b2268 100644 --- a/gcc/config/aarch64/arm_neon.h +++ b/gcc/config/aarch64/arm_neon.h @@ -34469,6 +34469,124 @@ vfmlslq_laneq_high_f16 (float32x4_t __r, float16x8_t __a, float16x8_t __b, #pragma GCC pop_options +#pragma GCC push_options +#pragma GCC target ("arch=armv8.5-a") + +__extension__ extern __inline float32x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vrnd32z_f32 (float32x2_t __a) +{ + return __builtin_aarch64_frint32zv2sf (__a); +} + +__extension__ extern __inline float32x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vrnd32zq_f32 (float32x4_t __a) +{ + return __builtin_aarch64_frint32zv4sf (__a); +} + +__extension__ extern __inline float64x1_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vrnd32z_f64 (float64x1_t __a) +{ + return (float64x1_t) + {__builtin_aarch64_frint32zdf (vget_lane_f64 (__a, 0))}; +} + +__extension__ extern __inline float64x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vrnd32zq_f64 (float64x2_t __a) +{ + return __builtin_aarch64_frint32zv2df (__a); +} + +__extension__ extern __inline float32x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vrnd32x_f32 (float32x2_t __a) +{ + return __builtin_aarch64_frint32xv2sf (__a); +} + +__extension__ extern __inline float32x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vrnd32xq_f32 (float32x4_t __a) +{ + return __builtin_aarch64_frint32xv4sf (__a); +} + +__extension__ extern __inline float64x1_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vrnd32x_f64 (float64x1_t __a) +{ + return (float64x1_t) {__builtin_aarch64_frint32xdf (vget_lane_f64 (__a, 0))}; +} + +__extension__ extern __inline float64x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vrnd32xq_f64 (float64x2_t __a) +{ + return __builtin_aarch64_frint32xv2df (__a); +} + +__extension__ extern __inline float32x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vrnd64z_f32 (float32x2_t __a) +{ + return __builtin_aarch64_frint64zv2sf (__a); +} + +__extension__ extern __inline float32x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vrnd64zq_f32 (float32x4_t __a) +{ + return __builtin_aarch64_frint64zv4sf (__a); +} + +__extension__ extern __inline float64x1_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vrnd64z_f64 (float64x1_t __a) +{ + return (float64x1_t) {__builtin_aarch64_frint64zdf (vget_lane_f64 (__a, 0))}; +} + +__extension__ extern __inline float64x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vrnd64zq_f64 (float64x2_t __a) +{ + return __builtin_aarch64_frint64zv2df (__a); +} + +__extension__ extern __inline float32x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vrnd64x_f32 (float32x2_t __a) +{ + return __builtin_aarch64_frint64xv2sf (__a); +} + +__extension__ extern __inline float32x4_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vrnd64xq_f32 (float32x4_t __a) +{ + return __builtin_aarch64_frint64xv4sf (__a); +} + +__extension__ extern __inline float64x1_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vrnd64x_f64 (float64x1_t __a) +{ + return (float64x1_t) {__builtin_aarch64_frint64xdf (vget_lane_f64 (__a, 0))}; +} + +__extension__ extern __inline float64x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vrnd64xq_f64 (float64x2_t __a) +{ + return __builtin_aarch64_frint64xv2df (__a); +} + +#pragma GCC pop_options + #undef __aarch64_vget_lane_any #undef __aarch64_vdup_lane_any diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index e8ba4f3..49d227f 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -128,6 +128,9 @@ (HF "TARGET_SIMD_F16INST") SF DF]) +;; Scalar and vetor modes for SF, DF. +(define_mode_iterator VSFDF [V2SF V4SF V2DF DF SF]) + ;; Advanced SIMD single Float modes. (define_mode_iterator VDQSF [V2SF V4SF]) @@ -1758,6 +1761,9 @@ UNSPEC_FCMLA180 UNSPEC_FCMLA270]) +(define_int_iterator FRINTNZX [UNSPEC_FRINT32Z UNSPEC_FRINT32X + UNSPEC_FRINT64Z UNSPEC_FRINT64X]) + ;; Iterators for atomic operations. (define_int_iterator ATOMIC_LDOP @@ -2041,6 +2047,9 @@ (define_int_attr f16mac1 [(UNSPEC_FMLAL "a") (UNSPEC_FMLSL "s") (UNSPEC_FMLAL2 "a") (UNSPEC_FMLSL2 "s")]) +(define_int_attr frintnzs_op [(UNSPEC_FRINT32Z "frint32z") (UNSPEC_FRINT32X "frint32x") + (UNSPEC_FRINT64Z "frint64z") (UNSPEC_FRINT64X "frint64x")]) + ;; The condition associated with an UNSPEC_COND_. (define_int_attr cmp_op [(UNSPEC_COND_FCMEQ "eq") (UNSPEC_COND_FCMGE "ge") diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 651baeb..0189c42 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-03 Kyrylo Tkachov + + * gcc.target/aarch64/acle/rintnzx_1.c: New test. + * gcc.target/aarch64/simd/vrndnzx_1.c: Likewise. + 2019-09-03 Jakub Jelinek Richard Biener diff --git a/gcc/testsuite/gcc.target/aarch64/acle/rintnzx_1.c b/gcc/testsuite/gcc.target/aarch64/acle/rintnzx_1.c new file mode 100644 index 0000000..1257208 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/acle/rintnzx_1.c @@ -0,0 +1,73 @@ +/* Test the __rint[32,64][z,x] intrinsics. */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -march=armv8.5-a" } */ + +#include + +#ifdef __ARM_FEATURE_FRINT +float +foo_32z_f32_scal (float a) +{ + return __rint32zf (a); +} + +/* { dg-final { scan-assembler-times "frint32z\ts\[0-9\]+, s\[0-9\]+\n" 1 } } */ + +double +foo_32z_f64_scal (double a) +{ + return __rint32z (a); +} + +/* { dg-final { scan-assembler-times "frint32z\td\[0-9\]+, d\[0-9\]+\n" 1 } } */ + +float +foo_32x_f32_scal (float a) +{ + return __rint32xf (a); +} + +/* { dg-final { scan-assembler-times "frint32x\ts\[0-9\]+, s\[0-9\]+\n" 1 } } */ + +double +foo_32x_f64_scal (double a) +{ + return __rint32x (a); +} + +/* { dg-final { scan-assembler-times "frint32x\td\[0-9\]+, d\[0-9\]+\n" 1 } } */ + +float +foo_64z_f32_scal (float a) +{ + return __rint64zf (a); +} + +/* { dg-final { scan-assembler-times "frint64z\ts\[0-9\]+, s\[0-9\]+\n" 1 } } */ + +double +foo_64z_f64_scal (double a) +{ + return __rint64z (a); +} + +/* { dg-final { scan-assembler-times "frint64z\td\[0-9\]+, d\[0-9\]+\n" 1 } } */ + +float +foo_64x_f32_scal (float a) +{ + return __rint64xf (a); +} + +/* { dg-final { scan-assembler-times "frint64x\ts\[0-9\]+, s\[0-9\]+\n" 1 } } */ + +double +foo_64x_f64_scal (double a) +{ + return __rint64x (a); +} + +/* { dg-final { scan-assembler-times "frint64x\td\[0-9\]+, d\[0-9\]+\n" 1 } } */ + +#endif diff --git a/gcc/testsuite/gcc.target/aarch64/simd/vrndnzx_1.c b/gcc/testsuite/gcc.target/aarch64/simd/vrndnzx_1.c new file mode 100644 index 0000000..0399b83 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/simd/vrndnzx_1.c @@ -0,0 +1,137 @@ +/* Test the vrnd[32,64][z,x] intrinsics. */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -march=armv8.5-a" } */ + +#include "arm_neon.h" + +#ifdef __ARM_FEATURE_FRINT + +float32x2_t +foo_32z (float32x2_t a) +{ + return vrnd32z_f32 (a); +} + +/* { dg-final { scan-assembler-times "frint32z\tv\[0-9\]+\.2s, v\[0-9\]+\.2s\n" 1 } } */ + +float32x4_t +foo_32z_q (float32x4_t a) +{ + return vrnd32zq_f32 (a); +} + +/* { dg-final { scan-assembler-times "frint32z\tv\[0-9\]+\.4s, v\[0-9\]+\.4s\n" 1 } } */ + +float64x1_t +foo_32z_f64 (float64x1_t a) +{ + return vrnd32z_f64 (a); +} + +/* { dg-final { scan-assembler-times "frint32z\td\[0-9\]+, d\[0-9\]+\n" 1 } } */ + +float64x2_t +foo_32z_q_f64 (float64x2_t a) +{ + return vrnd32zq_f64 (a); +} + +/* { dg-final { scan-assembler-times "frint32z\tv\[0-9\]+\.2d, v\[0-9\]+\.2d\n" 1 } } */ + +float32x2_t +foo_32x (float32x2_t a) +{ + return vrnd32x_f32 (a); +} + +/* { dg-final { scan-assembler-times "frint32x\tv\[0-9\]+\.2s, v\[0-9\]+\.2s\n" 1 } } */ + +float32x4_t +foo_32x_q (float32x4_t a) +{ + return vrnd32xq_f32 (a); +} + +/* { dg-final { scan-assembler-times "frint32x\tv\[0-9\]+\.4s, v\[0-9\]+\.4s\n" 1 } } */ + +float64x1_t +foo_32x_f64 (float64x1_t a) +{ + return vrnd32x_f64 (a); +} + +/* { dg-final { scan-assembler-times "frint32x\td\[0-9\]+, d\[0-9\]+\n" 1 } } */ + +float64x2_t +foo_32x_q_f64 (float64x2_t a) +{ + return vrnd32xq_f64 (a); +} + +/* { dg-final { scan-assembler-times "frint32x\tv\[0-9\]+\.2d, v\[0-9\]+\.2d\n" 1 } } */ + +float32x2_t +foo_64z (float32x2_t a) +{ + return vrnd64z_f32 (a); +} + +/* { dg-final { scan-assembler-times "frint64z\tv\[0-9\]+\.2s, v\[0-9\]+\.2s\n" 1 } } */ + +float32x4_t +foo_64z_q (float32x4_t a) +{ + return vrnd64zq_f32 (a); +} + +/* { dg-final { scan-assembler-times "frint64z\tv\[0-9\]+\.4s, v\[0-9\]+\.4s\n" 1 } } */ + +float64x1_t +foo_64z_f64 (float64x1_t a) +{ + return vrnd64z_f64 (a); +} + +/* { dg-final { scan-assembler-times "frint64z\td\[0-9\]+, d\[0-9\]+\n" 1 } } */ + +float64x2_t +foo_64z_q_f64 (float64x2_t a) +{ + return vrnd64zq_f64 (a); +} + +/* { dg-final { scan-assembler-times "frint64z\tv\[0-9\]+\.2d, v\[0-9\]+\.2d\n" 1 } } */ + +float32x2_t +foo_64x (float32x2_t a) +{ + return vrnd64x_f32 (a); +} + +/* { dg-final { scan-assembler-times "frint64x\tv\[0-9\]+\.2s, v\[0-9\]+\.2s\n" 1 } } */ + +float32x4_t +foo_64x_q (float32x4_t a) +{ + return vrnd64xq_f32 (a); +} + +/* { dg-final { scan-assembler-times "frint64x\tv\[0-9\]+\.4s, v\[0-9\]+\.4s\n" 1 } } */ + +float64x1_t +foo_64x_f64 (float64x1_t a) +{ + return vrnd64x_f64 (a); +} + +/* { dg-final { scan-assembler-times "frint64x\td\[0-9\]+, d\[0-9\]+\n" 1 } } */ + +float64x2_t +foo_64x_q_f64 (float64x2_t a) +{ + return vrnd64xq_f64 (a); +} + +/* { dg-final { scan-assembler-times "frint64x\tv\[0-9\]+\.2d, v\[0-9\]+\.2d\n" 1 } } */ +#endif -- cgit v1.1 From e1d5d19ec4f84b67ac693fef5b2add7dc9cf056d Mon Sep 17 00:00:00 2001 From: Kyrylo Tkachov Date: Tue, 3 Sep 2019 08:40:30 +0000 Subject: [AArch64] Add support for __jcvt intrinsic This patch implements the __jcvt ACLE intrinsic [1] that maps down to the FJCVTZS [2] instruction from Armv8.3-a. No fancy mode iterators or nothing. Just a single builtin, UNSPEC and define_insn and the associate plumbing. This patch also defines __ARM_FEATURE_JCVT to indicate when the intrinsic is available. [1] https://developer.arm.com/docs/101028/latest/data-processing-intrinsics [2] https://developer.arm.com/docs/ddi0596/latest/simd-and-floating-point-instructions-alphabetic-order/fjcvtzs-floating-point-javascript-convert-to-signed-fixed-point-rounding-toward-zero * config/aarch64/aarch64.md (UNSPEC_FJCVTZS): Define. (aarch64_fjcvtzs): New define_insn. * config/aarch64/aarch64.h (TARGET_JSCVT): Define. * config/aarch64/aarch64-builtins.c (aarch64_builtins): Add AARCH64_JSCVT. (aarch64_init_builtins): Initialize __builtin_aarch64_jcvtzs. (aarch64_expand_builtin): Handle AARCH64_JSCVT. * config/aarch64/aarch64-c.c (aarch64_update_cpp_builtins): Define __ARM_FEATURE_JCVT where appropriate. * config/aarch64/arm_acle.h (__jcvt): Define. * gcc.target/aarch64/acle/jcvt_1.c: New test. From-SVN: r275335 --- gcc/ChangeLog | 13 +++++++++++++ gcc/config/aarch64/aarch64-builtins.c | 18 ++++++++++++++++++ gcc/config/aarch64/aarch64-c.c | 1 + gcc/config/aarch64/aarch64.h | 3 +++ gcc/config/aarch64/aarch64.md | 10 ++++++++++ gcc/config/aarch64/arm_acle.h | 10 ++++++++++ gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.target/aarch64/acle/jcvt_1.c | 15 +++++++++++++++ 8 files changed, 74 insertions(+) create mode 100644 gcc/testsuite/gcc.target/aarch64/acle/jcvt_1.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c6df078..401cfda 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,18 @@ 2019-09-03 Kyrylo Tkachov + * config/aarch64/aarch64.md (UNSPEC_FJCVTZS): Define. + (aarch64_fjcvtzs): New define_insn. + * config/aarch64/aarch64.h (TARGET_JSCVT): Define. + * config/aarch64/aarch64-builtins.c (aarch64_builtins): + Add AARCH64_JSCVT. + (aarch64_init_builtins): Initialize __builtin_aarch64_jcvtzs. + (aarch64_expand_builtin): Handle AARCH64_JSCVT. + * config/aarch64/aarch64-c.c (aarch64_update_cpp_builtins): Define + __ARM_FEATURE_JCVT where appropriate. + * config/aarch64/arm_acle.h (__jcvt): Define. + +2019-09-03 Kyrylo Tkachov + * config/aarch64/aarch64.md ("unspec"): Add UNSPEC_FRINT32Z, UNSPEC_FRINT32X, UNSPEC_FRINT64Z, UNSPEC_FRINT64X. (aarch64_): New define_insn. diff --git a/gcc/config/aarch64/aarch64-builtins.c b/gcc/config/aarch64/aarch64-builtins.c index 2fc5cf7..9f26104 100644 --- a/gcc/config/aarch64/aarch64-builtins.c +++ b/gcc/config/aarch64/aarch64-builtins.c @@ -438,6 +438,8 @@ enum aarch64_builtins /* Special cased Armv8.3-A Complex FMA by Lane quad Builtins. */ AARCH64_SIMD_FCMLA_LANEQ_BUILTIN_BASE, AARCH64_SIMD_FCMLA_LANEQ_BUILTINS + /* Builtin for Arm8.3-a Javascript conversion instruction. */ + AARCH64_JSCVT, /* TME builtins. */ AARCH64_TME_BUILTIN_TSTART, AARCH64_TME_BUILTIN_TCOMMIT, @@ -1130,6 +1132,12 @@ aarch64_init_builtins (void) aarch64_init_crc32_builtins (); aarch64_init_builtin_rsqrt (); + tree ftype_jcvt + = build_function_type_list (intSI_type_node, double_type_node, NULL); + aarch64_builtin_decls[AARCH64_JSCVT] + = add_builtin_function ("__builtin_aarch64_jcvtzs", ftype_jcvt, + AARCH64_JSCVT, BUILT_IN_MD, NULL, NULL_TREE); + /* Initialize pointer authentication builtins which are backed by instructions in NOP encoding space. @@ -1682,6 +1690,16 @@ aarch64_expand_builtin (tree exp, return target; + case AARCH64_JSCVT: + arg0 = CALL_EXPR_ARG (exp, 0); + op0 = force_reg (DFmode, expand_normal (arg0)); + if (!target) + target = gen_reg_rtx (SImode); + else + target = force_reg (SImode, target); + emit_insn (GEN_FCN (CODE_FOR_aarch64_fjcvtzs) (target, op0)); + return target; + case AARCH64_SIMD_BUILTIN_FCMLA_LANEQ0_V2SF: case AARCH64_SIMD_BUILTIN_FCMLA_LANEQ90_V2SF: case AARCH64_SIMD_BUILTIN_FCMLA_LANEQ180_V2SF: diff --git a/gcc/config/aarch64/aarch64-c.c b/gcc/config/aarch64/aarch64-c.c index c05efed..137aa18 100644 --- a/gcc/config/aarch64/aarch64-c.c +++ b/gcc/config/aarch64/aarch64-c.c @@ -110,6 +110,7 @@ aarch64_update_cpp_builtins (cpp_reader *pfile) aarch64_def_or_undef (TARGET_CRC32, "__ARM_FEATURE_CRC32", pfile); aarch64_def_or_undef (TARGET_DOTPROD, "__ARM_FEATURE_DOTPROD", pfile); aarch64_def_or_undef (TARGET_COMPLEX, "__ARM_FEATURE_COMPLEX", pfile); + aarch64_def_or_undef (TARGET_JSCVT, "__ARM_FEATURE_JCVT", pfile); cpp_undef (pfile, "__AARCH64_CMODEL_TINY__"); cpp_undef (pfile, "__AARCH64_CMODEL_SMALL__"); diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h index e621238..7bbeed4 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -288,6 +288,9 @@ extern unsigned aarch64_architecture_version; /* ARMv8.3-A features. */ #define TARGET_ARMV8_3 (AARCH64_ISA_V8_3) +/* Javascript conversion instruction from Armv8.3-a. */ +#define TARGET_JSCVT (TARGET_FLOAT && AARCH64_ISA_V8_3) + /* Armv8.3-a Complex number extension to AdvSIMD extensions. */ #define TARGET_COMPLEX (TARGET_SIMD && TARGET_ARMV8_3) diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index f1f9b21..e4f9005 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -141,6 +141,7 @@ UNSPEC_CRC32X UNSPEC_FCVTZS UNSPEC_FCVTZU + UNSPEC_FJCVTZS UNSPEC_FRINT32Z UNSPEC_FRINT32X UNSPEC_FRINT64Z @@ -6887,6 +6888,15 @@ [(set_attr "length" "0")] ) +(define_insn "aarch64_fjcvtzs" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec:SI [(match_operand:DF 1 "register_operand" "w")] + UNSPEC_FJCVTZS))] + "TARGET_JSCVT" + "fjcvtzs\\t%w0, %d1" + [(set_attr "type" "f_cvtf2i")] +) + ;; Pointer authentication patterns are always provided. In architecture ;; revisions prior to ARMv8.3-A these HINT instructions operate as NOPs. ;; This lets the user write portable software which authenticates pointers diff --git a/gcc/config/aarch64/arm_acle.h b/gcc/config/aarch64/arm_acle.h index 01a82be..147dfe0 100644 --- a/gcc/config/aarch64/arm_acle.h +++ b/gcc/config/aarch64/arm_acle.h @@ -34,6 +34,16 @@ extern "C" { #endif #pragma GCC push_options +#pragma GCC target ("arch=armv8.3-a") +__extension__ static __inline int32_t __attribute__ ((__always_inline__)) +__jcvt (double __a) +{ + return __builtin_aarch64_jcvtzs (__a); +} + +#pragma GCC pop_options + +#pragma GCC push_options #pragma GCC target ("arch=armv8.5-a") __extension__ static __inline float __attribute__ ((__always_inline__)) __rint32zf (float __a) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0189c42..40d11f9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2019-09-03 Kyrylo Tkachov + * gcc.target/aarch64/acle/jcvt_1.c: New test. + +2019-09-03 Kyrylo Tkachov + * gcc.target/aarch64/acle/rintnzx_1.c: New test. * gcc.target/aarch64/simd/vrndnzx_1.c: Likewise. diff --git a/gcc/testsuite/gcc.target/aarch64/acle/jcvt_1.c b/gcc/testsuite/gcc.target/aarch64/acle/jcvt_1.c new file mode 100644 index 0000000..0c900b1 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/acle/jcvt_1.c @@ -0,0 +1,15 @@ +/* Test the __jcvt ACLE intrinsic. */ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=armv8.3-a" } */ + +#include + +#ifdef __ARM_FEATURE_JCVT +int32_t +test_jcvt (double a) +{ + return __jcvt (a); +} +#endif + +/* { dg-final { scan-assembler-times "fjcvtzs\tw\[0-9\]+, d\[0-9\]+\n" 1 } } */ -- cgit v1.1 From 837ee1e0b6e7c0936110b93ed70d8303ab316a16 Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Tue, 3 Sep 2019 09:29:02 +0000 Subject: S/390: Fix failing RTL check in s390_canonicalize_comparison The new sigfpe-eh.c fails with internal compiler error: RTL check: expected elt 0 type 'e' or 'u', have 'w' (rtx const_int) This is most likely due to a typo: XEXP (*op1, 0) was used, when XEXP (*op0, 1) was intended. This did not cause any user-visible problems, because reversed_comparison_code_parts ignores the respective argument, and the release compiler is built without RTL checks. gcc/ChangeLog: 2019-09-03 Ilya Leoshkevich * config/s390/s390.c (s390_canonicalize_comparison): Use XEXP (*op0, 1) instead of XEXP (*op1, 0). gcc/testsuite/ChangeLog: 2019-09-03 Ilya Leoshkevich * gcc.target/s390/sigfpe-eh.c: New test. From-SVN: r275336 --- gcc/ChangeLog | 5 +++++ gcc/config/s390/s390.c | 2 +- gcc/testsuite/ChangeLog | 4 ++++ 3 files changed, 10 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 401cfda..a6a481c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-09-03 Ilya Leoshkevich + + * config/s390/s390.c (s390_canonicalize_comparison): Use XEXP + (*op0, 1) instead of XEXP (*op1, 0). + 2019-09-03 Kyrylo Tkachov * config/aarch64/aarch64.md (UNSPEC_FJCVTZS): Define. diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index fa17d7d5d..2478426 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -1783,7 +1783,7 @@ s390_canonicalize_comparison (int *code, rtx *op0, rtx *op1, if (*code == EQ) new_code = reversed_comparison_code_parts (GET_CODE (*op0), XEXP (*op0, 0), - XEXP (*op1, 0), NULL); + XEXP (*op0, 1), NULL); else new_code = GET_CODE (*op0); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 40d11f9..2771cd9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-09-03 Ilya Leoshkevich + + * gcc.target/s390/sigfpe-eh.c: New test. + 2019-09-03 Kyrylo Tkachov * gcc.target/aarch64/acle/jcvt_1.c: New test. -- cgit v1.1 From 70b766b25a484e847ad15a51a83e2f018a7b0171 Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Tue, 3 Sep 2019 10:27:04 +0000 Subject: S/390: Commit forgotten test for r275336 gcc/testsuite/ChangeLog: 2019-09-03 Ilya Leoshkevich * gcc.target/s390/sigfpe-eh.c: Forgotten test. From-SVN: r275337 --- gcc/testsuite/gcc.target/s390/sigfpe-eh.c | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 gcc/testsuite/gcc.target/s390/sigfpe-eh.c (limited to 'gcc') diff --git a/gcc/testsuite/gcc.target/s390/sigfpe-eh.c b/gcc/testsuite/gcc.target/s390/sigfpe-eh.c new file mode 100644 index 0000000..52b0bf3 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/sigfpe-eh.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-march=z196 -O2 -fexceptions -fnon-call-exceptions" } */ + +extern float f (void); +extern float g (void); + +float h (float x, float y) +{ + return x < y ? f () : g (); +} -- cgit v1.1 From c8d3491299d4680847c2899a8ef1a34ad880cdb0 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 3 Sep 2019 11:24:18 +0000 Subject: tree-ssa-sccvn.h (vn_nary_op_lookup): Remove. 2019-09-03 Richard Biener * tree-ssa-sccvn.h (vn_nary_op_lookup): Remove. (vn_nary_op_insert): Likewise. * tree-ssa-sccvn.c (init_vn_nary_op_from_op): Remove. (vn_nary_op_lookup): Likewise. (vn_nary_op_insert): Likewise. From-SVN: r275338 --- gcc/ChangeLog | 8 ++++++++ gcc/tree-ssa-sccvn.c | 45 --------------------------------------------- gcc/tree-ssa-sccvn.h | 2 -- 3 files changed, 8 insertions(+), 47 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a6a481c..cf628e1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2019-09-03 Richard Biener + + * tree-ssa-sccvn.h (vn_nary_op_lookup): Remove. + (vn_nary_op_insert): Likewise. + * tree-ssa-sccvn.c (init_vn_nary_op_from_op): Remove. + (vn_nary_op_lookup): Likewise. + (vn_nary_op_insert): Likewise. + 2019-09-03 Ilya Leoshkevich * config/s390/s390.c (s390_canonicalize_comparison): Use XEXP diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 336a7c7..f5d75bd 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -3325,20 +3325,6 @@ init_vn_nary_op_from_pieces (vn_nary_op_t vno, unsigned int length, memcpy (&vno->op[0], ops, sizeof (tree) * length); } -/* Initialize VNO from OP. */ - -static void -init_vn_nary_op_from_op (vn_nary_op_t vno, tree op) -{ - unsigned i; - - vno->opcode = TREE_CODE (op); - vno->length = TREE_CODE_LENGTH (TREE_CODE (op)); - vno->type = TREE_TYPE (op); - for (i = 0; i < vno->length; ++i) - vno->op[i] = TREE_OPERAND (op, i); -} - /* Return the number of operands for a vn_nary ops structure from STMT. */ static unsigned int @@ -3440,22 +3426,6 @@ vn_nary_op_lookup_pieces (unsigned int length, enum tree_code code, return vn_nary_op_lookup_1 (vno1, vnresult); } -/* Lookup OP in the current hash table, and return the resulting value - number if it exists in the hash table. Return NULL_TREE if it does - not exist in the hash table or if the result field of the operation - is NULL. VNRESULT will contain the vn_nary_op_t from the hashtable - if it exists. */ - -tree -vn_nary_op_lookup (tree op, vn_nary_op_t *vnresult) -{ - vn_nary_op_t vno1 - = XALLOCAVAR (struct vn_nary_op_s, - sizeof_vn_nary_op (TREE_CODE_LENGTH (TREE_CODE (op)))); - init_vn_nary_op_from_op (vno1, op); - return vn_nary_op_lookup_1 (vno1, vnresult); -} - /* Lookup the rhs of STMT in the current hash table, and return the resulting value number if it exists in the hash table. Return NULL_TREE if it does not exist in the hash table. VNRESULT will contain the @@ -3708,21 +3678,6 @@ vn_nary_op_get_predicated_value (vn_nary_op_t vno, basic_block bb) return NULL_TREE; } -/* Insert OP into the current hash table with a value number of - RESULT. Return the vn_nary_op_t structure we created and put in - the hashtable. */ - -vn_nary_op_t -vn_nary_op_insert (tree op, tree result) -{ - unsigned length = TREE_CODE_LENGTH (TREE_CODE (op)); - vn_nary_op_t vno1; - - vno1 = alloc_vn_nary_op (length, result, VN_INFO (result)->value_id); - init_vn_nary_op_from_op (vno1, op); - return vn_nary_op_insert_into (vno1, valid_info->nary, true); -} - /* Insert the rhs of STMT into the current hash table with a value number of RESULT. */ diff --git a/gcc/tree-ssa-sccvn.h b/gcc/tree-ssa-sccvn.h index 1a5f238..77b668a 100644 --- a/gcc/tree-ssa-sccvn.h +++ b/gcc/tree-ssa-sccvn.h @@ -244,11 +244,9 @@ bool has_VN_INFO (tree); extern vn_ssa_aux_t VN_INFO (tree); tree vn_get_expr_for (tree); void scc_vn_restore_ssa_info (void); -tree vn_nary_op_lookup (tree, vn_nary_op_t *); tree vn_nary_op_lookup_stmt (gimple *, vn_nary_op_t *); tree vn_nary_op_lookup_pieces (unsigned int, enum tree_code, tree, tree *, vn_nary_op_t *); -vn_nary_op_t vn_nary_op_insert (tree, tree); vn_nary_op_t vn_nary_op_insert_pieces (unsigned int, enum tree_code, tree, tree *, tree, unsigned int); bool ao_ref_init_from_vn_reference (ao_ref *, alias_set_type, tree, -- cgit v1.1 From 934392185369af22fee845e4edd92c420b8c248b Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Tue, 3 Sep 2019 14:37:41 +0000 Subject: re PR middle-end/91603 (Unaligned access in expand_assignment) 2019-09-03 Bernd Edlinger PR middle-end/91603 PR middle-end/91612 PR middle-end/91613 * expr.c (expand_expr_real_1): Handle unaligned decl_rtl and SSA_NAME referring to CONSTANT_P correctly. testsuite: 2019-09-03 Bernd Edlinger PR middle-end/91603 * testsuite/gcc.target/arm/pr91603.c: New test. From-SVN: r275342 --- gcc/ChangeLog | 10 +++++++- gcc/expr.c | 43 +++++++++++++++++++++++++++++++--- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.target/arm/pr91603.c | 23 ++++++++++++++++++ 4 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.target/arm/pr91603.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cf628e1..9c88006 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2019-09-03 Bernd Edlinger + + PR middle-end/91603 + PR middle-end/91612 + PR middle-end/91613 + * expr.c (expand_expr_real_1): Handle unaligned decl_rtl + and SSA_NAME referring to CONSTANT_P correctly. + 2019-09-03 Richard Biener * tree-ssa-sccvn.h (vn_nary_op_lookup): Remove. @@ -76,7 +84,7 @@ PR middle-end/91605 * expr.c (addr_expr_of_non_mem_decl_p_1): Refactor into... (non_mem_decl_p): ...this. - (mem_ref_refers_to_non_mem_p): Handle DECL_P as well ase MEM_REF. + (mem_ref_refers_to_non_mem_p): Handle DECL_P as well as MEM_REF. (expand_assignment): Call mem_ref_referes_to_non_mem_p unconditionally as before. diff --git a/gcc/expr.c b/gcc/expr.c index 3c3f15a..0c96551 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -10062,6 +10062,42 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, { if (exp && MEM_P (temp) && REG_P (XEXP (temp, 0))) mark_reg_pointer (XEXP (temp, 0), DECL_ALIGN (exp)); + } + else if (MEM_P (decl_rtl)) + temp = decl_rtl; + + if (temp != 0) + { + if (MEM_P (temp) + && modifier != EXPAND_WRITE + && modifier != EXPAND_MEMORY + && modifier != EXPAND_INITIALIZER + && modifier != EXPAND_CONST_ADDRESS + && modifier != EXPAND_SUM + && !inner_reference_p + && mode != BLKmode + && MEM_ALIGN (temp) < GET_MODE_ALIGNMENT (mode)) + { + enum insn_code icode; + + if ((icode = optab_handler (movmisalign_optab, mode)) + != CODE_FOR_nothing) + { + class expand_operand ops[2]; + + /* We've already validated the memory, and we're creating a + new pseudo destination. The predicates really can't fail, + nor can the generator. */ + create_output_operand (&ops[0], NULL_RTX, mode); + create_fixed_operand (&ops[1], temp); + expand_insn (icode, 2, ops); + temp = ops[0].value; + } + else if (targetm.slow_unaligned_access (mode, MEM_ALIGN (temp))) + temp = extract_bit_field (temp, GET_MODE_BITSIZE (mode), + 0, unsignedp, NULL_RTX, + mode, mode, false, NULL); + } return temp; } @@ -10974,9 +11010,10 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, op0 = copy_rtx (op0); /* Don't set memory attributes if the base expression is - SSA_NAME that got expanded as a MEM. In that case, we should - just honor its original memory attributes. */ - if (TREE_CODE (tem) != SSA_NAME || !MEM_P (orig_op0)) + SSA_NAME that got expanded as a MEM or a CONSTANT. In that case, + we should just honor its original memory attributes. */ + if (!(TREE_CODE (tem) == SSA_NAME + && (MEM_P (orig_op0) || CONSTANT_P (orig_op0)))) set_mem_attributes (op0, exp, 0); if (REG_P (XEXP (op0, 0))) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2771cd9..24e0d2b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-03 Bernd Edlinger + + PR middle-end/91603 + * gcc.target/arm/pr91603.c: New test. + 2019-09-03 Ilya Leoshkevich * gcc.target/s390/sigfpe-eh.c: New test. diff --git a/gcc/testsuite/gcc.target/arm/pr91603.c b/gcc/testsuite/gcc.target/arm/pr91603.c new file mode 100644 index 0000000..ab09c3b --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr91603.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target arm_neon_ok } */ +/* { dg-options "-O3" } */ +/* { dg-add-options arm_neon } */ + +typedef __simd64_int32_t int32x2_t; +typedef __attribute__((aligned (1))) int32x2_t unalignedvec; + +unalignedvec a = {11, 13}; + +void foo(unalignedvec *); + +void test() +{ + unalignedvec x = a; + foo (&x); + a = x; +} + +/* { dg-final { scan-assembler-times "vld1.32" 1 } } */ +/* { dg-final { scan-assembler-times "vst1.32" 1 } } */ +/* { dg-final { scan-assembler-times "vldr" 1 } } */ +/* { dg-final { scan-assembler-times "vstr" 1 } } */ -- cgit v1.1 From 2f2aeda98f3aa24034a700e7efcb6c1a9397836f Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Tue, 3 Sep 2019 15:08:28 +0000 Subject: Remove Cell Broadband Engine SPU targets From-SVN: r275343 --- gcc/ChangeLog | 13 + gcc/common/config/spu/spu-common.c | 56 - gcc/config.gcc | 33 +- gcc/config/spu/constraints.md | 179 - gcc/config/spu/predicates.md | 122 - gcc/config/spu/spu-builtins.def | 781 -- gcc/config/spu/spu-builtins.md | 864 --- gcc/config/spu/spu-c.c | 233 - gcc/config/spu/spu-elf.h | 75 - gcc/config/spu/spu-modes.def | 29 - gcc/config/spu/spu-protos.h | 95 - gcc/config/spu/spu.c | 7469 -------------------- gcc/config/spu/spu.h | 517 -- gcc/config/spu/spu.md | 5255 -------------- gcc/config/spu/spu.opt | 105 - gcc/config/spu/spu_cache.h | 39 - gcc/config/spu/spu_internals.h | 421 -- gcc/config/spu/spu_intrinsics.h | 83 - gcc/config/spu/spu_mfcio.h | 342 - gcc/config/spu/t-spu-elf | 34 - gcc/config/spu/vec_types.h | 36 - gcc/config/spu/vmx2spu.h | 3985 ----------- gcc/configure | 2 +- gcc/configure.ac | 2 +- gcc/doc/extend.texi | 113 +- gcc/doc/invoke.texi | 147 - gcc/doc/md.texi | 70 - gcc/doc/sourcebuild.texi | 10 - gcc/testsuite/ChangeLog | 165 + .../c-c++-common/torture/complex-sign-add.c | 2 - .../c-c++-common/torture/complex-sign-mixed-add.c | 2 - .../c-c++-common/torture/complex-sign-mixed-div.c | 2 - .../c-c++-common/torture/complex-sign-mixed-mul.c | 2 - .../c-c++-common/torture/complex-sign-mixed-sub.c | 2 - .../torture/complex-sign-mul-minus-one.c | 2 - .../c-c++-common/torture/complex-sign-mul-one.c | 2 - .../c-c++-common/torture/complex-sign-mul.c | 2 - .../c-c++-common/torture/complex-sign-sub.c | 2 - gcc/testsuite/g++.dg/opt/temp1.C | 5 - gcc/testsuite/g++.dg/opt/vt1.C | 1 - gcc/testsuite/g++.dg/torture/type-generic-1.C | 1 - gcc/testsuite/g++.dg/warn/pr30551-2.C | 1 - gcc/testsuite/g++.dg/warn/pr30551.C | 1 - gcc/testsuite/g++.old-deja/g++.jason/thunk2.C | 1 - gcc/testsuite/g++.old-deja/g++.other/comdat5.C | 1 - .../g++.old-deja/g++.other/local-alloc1.C | 1 - gcc/testsuite/gcc.c-torture/compile/20001226-1.c | 1 - gcc/testsuite/gcc.c-torture/execute/20030222-1.c | 1 - gcc/testsuite/gcc.c-torture/execute/20031003-1.c | 6 - gcc/testsuite/gcc.c-torture/execute/20101011-1.c | 3 - gcc/testsuite/gcc.c-torture/execute/conversion.c | 12 - .../gcc.c-torture/execute/ieee/20010114-2.x | 6 - .../gcc.c-torture/execute/ieee/20030331-1.x | 6 - .../gcc.c-torture/execute/ieee/920518-1.x | 6 - .../gcc.c-torture/execute/ieee/compare-fp-1.x | 6 - .../gcc.c-torture/execute/ieee/compare-fp-4.x | 6 - .../gcc.c-torture/execute/ieee/fp-cmp-2.x | 6 - .../gcc.c-torture/execute/ieee/fp-cmp-4f.x | 6 - .../gcc.c-torture/execute/ieee/fp-cmp-8f.x | 6 - gcc/testsuite/gcc.c-torture/execute/ieee/inf-1.c | 9 - gcc/testsuite/gcc.c-torture/execute/ieee/inf-2.c | 4 - .../execute/ieee/mul-subnormal-single-1.x | 5 - gcc/testsuite/gcc.c-torture/execute/ieee/rbug.c | 6 - gcc/testsuite/gcc.c-torture/execute/pr39228.c | 1 - gcc/testsuite/gcc.dg/20020312-2.c | 2 - gcc/testsuite/gcc.dg/20030702-1.c | 1 - gcc/testsuite/gcc.dg/and-1.c | 6 +- gcc/testsuite/gcc.dg/builtin-inf-1.c | 2 +- gcc/testsuite/gcc.dg/builtins-1.c | 2 +- gcc/testsuite/gcc.dg/builtins-43.c | 5 - gcc/testsuite/gcc.dg/builtins-44.c | 7 - gcc/testsuite/gcc.dg/builtins-45.c | 10 - gcc/testsuite/gcc.dg/float-range-1.c | 1 - gcc/testsuite/gcc.dg/float-range-3.c | 1 - gcc/testsuite/gcc.dg/float-range-4.c | 1 - gcc/testsuite/gcc.dg/float-range-5.c | 1 - gcc/testsuite/gcc.dg/fold-overflow-1.c | 1 - gcc/testsuite/gcc.dg/format/ms_unnamed-1.c | 2 +- gcc/testsuite/gcc.dg/format/unnamed-1.c | 2 +- gcc/testsuite/gcc.dg/hex-round-1.c | 1 - gcc/testsuite/gcc.dg/hex-round-2.c | 1 - gcc/testsuite/gcc.dg/lower-subreg-1.c | 2 +- gcc/testsuite/gcc.dg/nrv3.c | 5 - gcc/testsuite/gcc.dg/pr15784-3.c | 1 - gcc/testsuite/gcc.dg/pr27095.c | 4 +- gcc/testsuite/gcc.dg/pr28243.c | 1 - gcc/testsuite/gcc.dg/pr28796-2.c | 1 - gcc/testsuite/gcc.dg/pr30551-3.c | 1 - gcc/testsuite/gcc.dg/pr30551-6.c | 1 - gcc/testsuite/gcc.dg/pr30551.c | 1 - gcc/testsuite/gcc.dg/pr70317.c | 2 +- gcc/testsuite/gcc.dg/sms-1.c | 2 +- gcc/testsuite/gcc.dg/sms-2.c | 2 +- gcc/testsuite/gcc.dg/sms-3.c | 2 +- gcc/testsuite/gcc.dg/sms-4.c | 2 +- gcc/testsuite/gcc.dg/sms-5.c | 1 - gcc/testsuite/gcc.dg/sms-6.c | 1 - gcc/testsuite/gcc.dg/sms-7.c | 1 - gcc/testsuite/gcc.dg/stack-usage-1.c | 2 - gcc/testsuite/gcc.dg/strlenopt-73.c | 2 +- gcc/testsuite/gcc.dg/titype-1.c | 2 +- gcc/testsuite/gcc.dg/tls/thr-cse-1.c | 3 +- gcc/testsuite/gcc.dg/torture/builtin-attr-1.c | 2 +- gcc/testsuite/gcc.dg/torture/builtin-complex-1.c | 6 - gcc/testsuite/gcc.dg/torture/builtin-cproj-1.c | 71 - gcc/testsuite/gcc.dg/torture/builtin-frexp-1.c | 15 - gcc/testsuite/gcc.dg/torture/builtin-ldexp-1.c | 12 - gcc/testsuite/gcc.dg/torture/builtin-logb-1.c | 12 - gcc/testsuite/gcc.dg/torture/builtin-math-2.c | 35 +- gcc/testsuite/gcc.dg/torture/builtin-math-5.c | 24 +- gcc/testsuite/gcc.dg/torture/builtin-modf-1.c | 34 - gcc/testsuite/gcc.dg/torture/fp-int-convert.h | 2 +- gcc/testsuite/gcc.dg/torture/pr25947-1.c | 1 - gcc/testsuite/gcc.dg/torture/type-generic-1.c | 1 - gcc/testsuite/gcc.dg/tree-ssa/20040204-1.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/ivopts-1.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/vector-6.c | 4 +- gcc/testsuite/gcc.dg/uninit-C-O0.c | 2 +- gcc/testsuite/gcc.dg/uninit-C.c | 2 +- .../spu/costmodel-fast-math-vect-pr29925.c | 39 - .../gcc.dg/vect/costmodel/spu/costmodel-vect-31a.c | 50 - .../gcc.dg/vect/costmodel/spu/costmodel-vect-31b.c | 49 - .../gcc.dg/vect/costmodel/spu/costmodel-vect-31c.c | 49 - .../gcc.dg/vect/costmodel/spu/costmodel-vect-31d.c | 50 - .../gcc.dg/vect/costmodel/spu/costmodel-vect-33.c | 42 - .../gcc.dg/vect/costmodel/spu/costmodel-vect-68a.c | 48 - .../gcc.dg/vect/costmodel/spu/costmodel-vect-68b.c | 48 - .../gcc.dg/vect/costmodel/spu/costmodel-vect-68c.c | 48 - .../gcc.dg/vect/costmodel/spu/costmodel-vect-68d.c | 49 - .../gcc.dg/vect/costmodel/spu/costmodel-vect-76a.c | 46 - .../gcc.dg/vect/costmodel/spu/costmodel-vect-76b.c | 46 - .../gcc.dg/vect/costmodel/spu/costmodel-vect-76c.c | 46 - .../vect/costmodel/spu/costmodel-vect-iv-9.c | 37 - .../vect/costmodel/spu/spu-costmodel-vect.exp | 69 - gcc/testsuite/gcc.dg/vect/no-math-errno-slp-32.c | 2 +- .../gcc.dg/vect/no-math-errno-vect-pow-1.c | 2 +- gcc/testsuite/gcc.dg/vect/vect-float-extend-1.c | 2 +- gcc/testsuite/gcc.dg/vect/vect-float-truncate-1.c | 2 +- gcc/testsuite/gcc.dg/vect/vect.exp | 3 - gcc/testsuite/gcc.target/spu/Wmain.c | 7 - gcc/testsuite/gcc.target/spu/abi.c | 474 -- gcc/testsuite/gcc.target/spu/compare-dp.c | 10 - gcc/testsuite/gcc.target/spu/cpat-1.c | 104 - gcc/testsuite/gcc.target/spu/cpat-2.c | 44 - gcc/testsuite/gcc.target/spu/cpat-3.c | 61 - gcc/testsuite/gcc.target/spu/cpat-4.c | 40 - gcc/testsuite/gcc.target/spu/dfcgt-nan.c | 31 - gcc/testsuite/gcc.target/spu/dfcmeq.c | 9 - gcc/testsuite/gcc.target/spu/dfcmgt.c | 10 - gcc/testsuite/gcc.target/spu/ea/cache1.c | 195 - gcc/testsuite/gcc.target/spu/ea/cast1.c | 43 - gcc/testsuite/gcc.target/spu/ea/cast2.c | 74 - gcc/testsuite/gcc.target/spu/ea/compile1.c | 109 - gcc/testsuite/gcc.target/spu/ea/compile2.c | 43 - gcc/testsuite/gcc.target/spu/ea/cppdefine.c | 36 - gcc/testsuite/gcc.target/spu/ea/ea.exp | 54 - gcc/testsuite/gcc.target/spu/ea/errors1.c | 67 - gcc/testsuite/gcc.target/spu/ea/errors2.c | 107 - gcc/testsuite/gcc.target/spu/ea/execute1.c | 41 - gcc/testsuite/gcc.target/spu/ea/execute2.c | 41 - gcc/testsuite/gcc.target/spu/ea/execute3.c | 39 - gcc/testsuite/gcc.target/spu/ea/ops1.c | 94 - gcc/testsuite/gcc.target/spu/ea/ops2.c | 94 - gcc/testsuite/gcc.target/spu/ea/options1.c | 22 - gcc/testsuite/gcc.target/spu/ea/pr41857.c | 29 - gcc/testsuite/gcc.target/spu/ea/test-sizes.c | 608 -- gcc/testsuite/gcc.target/spu/fixed-range-bad.c | 5 - gcc/testsuite/gcc.target/spu/fixed-range.c | 8 - gcc/testsuite/gcc.target/spu/intrinsics-1.c | 24 - gcc/testsuite/gcc.target/spu/intrinsics-2.c | 305 - gcc/testsuite/gcc.target/spu/intrinsics-3.c | 42 - gcc/testsuite/gcc.target/spu/intrinsics-sr.c | 496 -- gcc/testsuite/gcc.target/spu/muldivti3.c | 46 - gcc/testsuite/gcc.target/spu/pr40001.c | 17 - gcc/testsuite/gcc.target/spu/spu.exp | 41 - gcc/testsuite/gcc.target/spu/subti3.c | 45 - gcc/testsuite/gcc.target/spu/tag_manager.c | 312 - gcc/testsuite/gcc.target/spu/vector-ansi.c | 35 - gcc/testsuite/gcc.target/spu/vector.c | 32 - gcc/testsuite/gfortran.dg/bessel_6.f90 | 4 - gcc/testsuite/gfortran.dg/bessel_7.f90 | 5 +- gcc/testsuite/gfortran.dg/char4_iunit_1.f03 | 1 - gcc/testsuite/gfortran.dg/chmod_1.f90 | 2 +- gcc/testsuite/gfortran.dg/chmod_2.f90 | 2 +- gcc/testsuite/gfortran.dg/chmod_3.f90 | 2 +- gcc/testsuite/gfortran.dg/default_format_1.f90 | 2 +- .../gfortran.dg/default_format_denormal_1.f90 | 2 +- gcc/testsuite/gfortran.dg/erf_2.F90 | 4 - gcc/testsuite/gfortran.dg/erf_3.F90 | 5 +- gcc/testsuite/gfortran.dg/init_flag_10.f90 | 1 - gcc/testsuite/gfortran.dg/init_flag_3.f90 | 1 - gcc/testsuite/gfortran.dg/int_conv_2.f90 | 1 - .../gfortran.dg/integer_exponentiation_3.F90 | 2 - .../gfortran.dg/integer_exponentiation_5.F90 | 2 - gcc/testsuite/gfortran.dg/isnan_1.f90 | 1 - gcc/testsuite/gfortran.dg/isnan_2.f90 | 1 - gcc/testsuite/gfortran.dg/maxloc_2.f90 | 1 - gcc/testsuite/gfortran.dg/maxlocval_2.f90 | 1 - gcc/testsuite/gfortran.dg/maxlocval_4.f90 | 1 - gcc/testsuite/gfortran.dg/minloc_1.f90 | 1 - gcc/testsuite/gfortran.dg/minlocval_1.f90 | 1 - gcc/testsuite/gfortran.dg/minlocval_4.f90 | 1 - gcc/testsuite/gfortran.dg/module_nan.f90 | 1 - gcc/testsuite/gfortran.dg/namelist_42.f90 | 1 - gcc/testsuite/gfortran.dg/namelist_43.f90 | 1 - gcc/testsuite/gfortran.dg/nan_1.f90 | 1 - gcc/testsuite/gfortran.dg/nan_2.f90 | 1 - gcc/testsuite/gfortran.dg/nan_3.f90 | 1 - gcc/testsuite/gfortran.dg/nan_4.f90 | 1 - gcc/testsuite/gfortran.dg/nan_5.f90 | 1 - gcc/testsuite/gfortran.dg/nan_6.f90 | 1 - gcc/testsuite/gfortran.dg/nearest_1.f90 | 1 - gcc/testsuite/gfortran.dg/nearest_3.f90 | 1 - gcc/testsuite/gfortran.dg/open_errors.f90 | 2 +- gcc/testsuite/gfortran.dg/pr20257.f90 | 1 - gcc/testsuite/gfortran.dg/read_infnan_1.f90 | 1 - gcc/testsuite/gfortran.dg/real_const_3.f90 | 1 - gcc/testsuite/gfortran.dg/realloc_on_assign_2.f03 | 1 - gcc/testsuite/gfortran.dg/reassoc_4.f | 1 - gcc/testsuite/gfortran.dg/scalar_mask_2.f90 | 3 +- gcc/testsuite/gfortran.dg/scratch_1.f90 | 1 - gcc/testsuite/gfortran.dg/stat_1.f90 | 2 +- gcc/testsuite/gfortran.dg/stat_2.f90 | 2 +- gcc/testsuite/gfortran.dg/transfer_simplify_1.f90 | 1 - gcc/testsuite/gfortran.dg/typebound_operator_9.f03 | 1 - .../gfortran.fortran-torture/execute/getarg_1.x | 5 - .../execute/intrinsic_nearest.x | 4 - .../execute/intrinsic_set_exponent.x | 4 - .../gfortran.fortran-torture/execute/nan_inf_fmt.x | 4 - gcc/testsuite/lib/compat.exp | 10 - gcc/testsuite/lib/fortran-torture.exp | 2 - gcc/testsuite/lib/gcc-dg.exp | 8 - gcc/testsuite/lib/gfortran.exp | 7 - gcc/testsuite/lib/target-supports.exp | 61 +- gcc/testsuite/lib/target-utils.exp | 4 - 236 files changed, 235 insertions(+), 26282 deletions(-) delete mode 100644 gcc/common/config/spu/spu-common.c delete mode 100644 gcc/config/spu/constraints.md delete mode 100644 gcc/config/spu/predicates.md delete mode 100644 gcc/config/spu/spu-builtins.def delete mode 100644 gcc/config/spu/spu-builtins.md delete mode 100644 gcc/config/spu/spu-c.c delete mode 100644 gcc/config/spu/spu-elf.h delete mode 100644 gcc/config/spu/spu-modes.def delete mode 100644 gcc/config/spu/spu-protos.h delete mode 100644 gcc/config/spu/spu.c delete mode 100644 gcc/config/spu/spu.h delete mode 100644 gcc/config/spu/spu.md delete mode 100644 gcc/config/spu/spu.opt delete mode 100644 gcc/config/spu/spu_cache.h delete mode 100644 gcc/config/spu/spu_internals.h delete mode 100644 gcc/config/spu/spu_intrinsics.h delete mode 100644 gcc/config/spu/spu_mfcio.h delete mode 100644 gcc/config/spu/t-spu-elf delete mode 100644 gcc/config/spu/vec_types.h delete mode 100644 gcc/config/spu/vmx2spu.h delete mode 100644 gcc/testsuite/gcc.c-torture/execute/ieee/20010114-2.x delete mode 100644 gcc/testsuite/gcc.c-torture/execute/ieee/20030331-1.x delete mode 100644 gcc/testsuite/gcc.c-torture/execute/ieee/920518-1.x delete mode 100644 gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-1.x delete mode 100644 gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-4f.x delete mode 100644 gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-8f.x delete mode 100644 gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-fast-math-vect-pr29925.c delete mode 100644 gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-31a.c delete mode 100644 gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-31b.c delete mode 100644 gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-31c.c delete mode 100644 gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-31d.c delete mode 100644 gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-33.c delete mode 100644 gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-68a.c delete mode 100644 gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-68b.c delete mode 100644 gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-68c.c delete mode 100644 gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-68d.c delete mode 100644 gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-76a.c delete mode 100644 gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-76b.c delete mode 100644 gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-76c.c delete mode 100644 gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-iv-9.c delete mode 100644 gcc/testsuite/gcc.dg/vect/costmodel/spu/spu-costmodel-vect.exp delete mode 100644 gcc/testsuite/gcc.target/spu/Wmain.c delete mode 100644 gcc/testsuite/gcc.target/spu/abi.c delete mode 100644 gcc/testsuite/gcc.target/spu/compare-dp.c delete mode 100644 gcc/testsuite/gcc.target/spu/cpat-1.c delete mode 100644 gcc/testsuite/gcc.target/spu/cpat-2.c delete mode 100644 gcc/testsuite/gcc.target/spu/cpat-3.c delete mode 100644 gcc/testsuite/gcc.target/spu/cpat-4.c delete mode 100644 gcc/testsuite/gcc.target/spu/dfcgt-nan.c delete mode 100644 gcc/testsuite/gcc.target/spu/dfcmeq.c delete mode 100644 gcc/testsuite/gcc.target/spu/dfcmgt.c delete mode 100644 gcc/testsuite/gcc.target/spu/ea/cache1.c delete mode 100644 gcc/testsuite/gcc.target/spu/ea/cast1.c delete mode 100644 gcc/testsuite/gcc.target/spu/ea/cast2.c delete mode 100644 gcc/testsuite/gcc.target/spu/ea/compile1.c delete mode 100644 gcc/testsuite/gcc.target/spu/ea/compile2.c delete mode 100644 gcc/testsuite/gcc.target/spu/ea/cppdefine.c delete mode 100644 gcc/testsuite/gcc.target/spu/ea/ea.exp delete mode 100644 gcc/testsuite/gcc.target/spu/ea/errors1.c delete mode 100644 gcc/testsuite/gcc.target/spu/ea/errors2.c delete mode 100644 gcc/testsuite/gcc.target/spu/ea/execute1.c delete mode 100644 gcc/testsuite/gcc.target/spu/ea/execute2.c delete mode 100644 gcc/testsuite/gcc.target/spu/ea/execute3.c delete mode 100644 gcc/testsuite/gcc.target/spu/ea/ops1.c delete mode 100644 gcc/testsuite/gcc.target/spu/ea/ops2.c delete mode 100644 gcc/testsuite/gcc.target/spu/ea/options1.c delete mode 100644 gcc/testsuite/gcc.target/spu/ea/pr41857.c delete mode 100644 gcc/testsuite/gcc.target/spu/ea/test-sizes.c delete mode 100644 gcc/testsuite/gcc.target/spu/fixed-range-bad.c delete mode 100644 gcc/testsuite/gcc.target/spu/fixed-range.c delete mode 100644 gcc/testsuite/gcc.target/spu/intrinsics-1.c delete mode 100644 gcc/testsuite/gcc.target/spu/intrinsics-2.c delete mode 100644 gcc/testsuite/gcc.target/spu/intrinsics-3.c delete mode 100644 gcc/testsuite/gcc.target/spu/intrinsics-sr.c delete mode 100644 gcc/testsuite/gcc.target/spu/muldivti3.c delete mode 100644 gcc/testsuite/gcc.target/spu/pr40001.c delete mode 100644 gcc/testsuite/gcc.target/spu/spu.exp delete mode 100644 gcc/testsuite/gcc.target/spu/subti3.c delete mode 100644 gcc/testsuite/gcc.target/spu/tag_manager.c delete mode 100644 gcc/testsuite/gcc.target/spu/vector-ansi.c delete mode 100644 gcc/testsuite/gcc.target/spu/vector.c delete mode 100644 gcc/testsuite/gfortran.fortran-torture/execute/getarg_1.x (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9c88006..4996f8c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2019-09-03 Ulrich Weigand + + * config.gcc: Obsolete spu target. Remove references to spu. + * configure.ac: Remove references to spu. + * configure: Regenerate. + * config/spu/: Remove directory. + * common/config/spu/: Remove directory. + + * doc/extend.texi: Remove references to spu. + * doc/invoke.texi: Likewise. + * doc/md.texi: Likewise. + * doc/sourcebuild.texi: Likewise. + 2019-09-03 Bernd Edlinger PR middle-end/91603 diff --git a/gcc/common/config/spu/spu-common.c b/gcc/common/config/spu/spu-common.c deleted file mode 100644 index a1be3aa..0000000 --- a/gcc/common/config/spu/spu-common.c +++ /dev/null @@ -1,56 +0,0 @@ -/* Common hooks for SPU. - Copyright (C) 2006-2019 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - . */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" -#include "common/common-target.h" -#include "common/common-target-def.h" -#include "opts.h" -#include "flags.h" -#include "params.h" - -static void -spu_option_init_struct (struct gcc_options *opts) -{ - /* With so many registers this is better on by default. */ - opts->x_flag_rename_registers = 1; -} - -/* Implement TARGET_OPTION_DEFAULT_PARAMS. */ -static void -spu_option_default_params (void) -{ - /* Override some of the default param values. With so many registers - larger values are better for these params. */ - set_default_param_value (PARAM_MAX_PENDING_LIST_LENGTH, 128); -} - -#undef TARGET_DEFAULT_TARGET_FLAGS -#define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT) - -#undef TARGET_OPTION_INIT_STRUCT -#define TARGET_OPTION_INIT_STRUCT spu_option_init_struct - -#undef TARGET_OPTION_DEFAULT_PARAMS -#define TARGET_OPTION_DEFAULT_PARAMS spu_option_default_params - -#undef TARGET_EXCEPT_UNWIND_INFO -#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info - -struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/config.gcc b/gcc/config.gcc index 11a8ac7..94a3608 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -247,8 +247,7 @@ md_file= # Obsolete configurations. case ${target} in - spu*-*-* \ - | tile*-*-* \ + tile*-*-* \ ) if test "x$enable_obsolete" != xyes; then echo "*** Configuration ${target} is obsolete." >&2 @@ -280,6 +279,7 @@ case ${target} in | powerpc*-*-linux*paired* \ | powerpc*-*-*spe* \ | sparc-hal-solaris2* \ + | spu*-*-* \ | thumb-*-* \ | *-*-freebsd[12] | *-*-freebsd[1234].* \ | *-*-freebsd*aout* \ @@ -535,9 +535,6 @@ sparc*-*-*) d_target_objs="sparc-d.o" extra_headers="visintrin.h" ;; -spu*-*-*) - cpu_type=spu - ;; s390*-*-*) cpu_type=s390 d_target_objs="s390-d.o" @@ -3171,15 +3168,6 @@ sparc64-*-openbsd*) with_cpu=ultrasparc tmake_file="${tmake_file} sparc/t-sparc" ;; -spu-*-elf*) - tm_file="dbxelf.h elfos.h spu/spu-elf.h spu/spu.h newlib-stdint.h" - tmake_file="spu/t-spu-elf" - native_system_header_dir=/include - extra_headers="spu_intrinsics.h spu_internals.h vmx2spu.h spu_mfcio.h vec_types.h spu_cache.h" - extra_modes=spu/spu-modes.def - c_target_objs="${c_target_objs} spu-c.o" - cxx_target_objs="${cxx_target_objs} spu-c.o" - ;; tic6x-*-elf) tm_file="elfos.h ${tm_file} c6x/elf-common.h c6x/elf.h" tm_file="${tm_file} dbxelf.h tm-dwarf2.h newlib-stdint.h" @@ -4890,23 +4878,6 @@ case "${target}" in esac ;; - spu-*-*) - supported_defaults="arch tune" - - for which in arch tune; do - eval "val=\$with_$which" - case ${val} in - "" | cell | celledp) - # OK - ;; - *) - echo "Unknown cpu used in --with-$which=$val." 1>&2 - exit 1 - ;; - esac - done - ;; - tic6x-*-*) supported_defaults="arch" diff --git a/gcc/config/spu/constraints.md b/gcc/config/spu/constraints.md deleted file mode 100644 index 6c6897d..0000000 --- a/gcc/config/spu/constraints.md +++ /dev/null @@ -1,179 +0,0 @@ -;; Constraint definitions for SPU -;; Copyright (C) 2006-2019 Free Software Foundation, Inc. -;; -;; This file is free software; you can redistribute it and/or modify it under -;; the terms of the GNU General Public License as published by the Free -;; Software Foundation; either version 3 of the License, or (at your option) -;; any later version. - -;; This file is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -;; for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; . - - -;; ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz -;; GCC: ffffiiiiiiii x x x x xxxx xx -;; SPU: xxxx xxx xxxx xxxx x xxx xx x xxx xx -;; FREE: ffff i a a a a a aa aaa -;; x - used -;; a - available -;; i - available for integer immediates -;; f - available for floating point immediates - -;; For most immediate constraints we have 3 variations to deal with the -;; fact const_int has no mode. One variation treats const_int as 32 bit, -;; another treats it as 64 bit, and the third sign extends it to 128 bit. - -(define_constraint "A" - "An immediate which can be loaded with the il/ila/ilh/ilhu instructions. const_int is treated as a 32-bit value." - (ior (and (match_code "const_int,const_double,const_vector") - (match_test "immediate_load_p (op, SImode)")) - (match_code "symbol_ref,label_ref,high,const"))) - -(define_constraint "B" - "An immediate for arithmetic instructions (e.g., ai, ceqi). const_int is treated as a 32-bit value." - (and (match_code "const_int,const_double,const_vector") - (match_test "arith_immediate_p (op, SImode, -0x200, 0x1ff)"))) - -(define_constraint "C" - "An immediate for and/xor/or instructions. const_int is treated as a 32-bit value." - (and (match_code "const_int,const_double,const_vector") - (match_test "logical_immediate_p (op, SImode)"))) - -(define_constraint "D" - "An immediate for iohl instruction. const_int is treated as a 32-bit value." - (and (match_code "const_int,const_double,const_vector") - (match_test "iohl_immediate_p (op, SImode)"))) - -(define_constraint "U" - "An immediate which can be loaded with the il/ila/ilh/ilhu instructions. const_int is sign extended to 128 bit." - (and (match_code "const_int,const_double,const_vector") - (match_test "immediate_load_p (op, TImode)"))) - -(define_constraint "W" - "An immediate for shift and rotate instructions. const_int is treated as a 32-bit value." - (and (match_code "const_int,const_double,const_vector") - (match_test "arith_immediate_p (op, SImode, -0x80000000ll, 0x7fffffffll)"))) - -(define_constraint "Y" - "An immediate for and/xor/or instructions. const_int is sign extended as a 128 bit." - (and (match_code "const_int,const_double,const_vector") - (match_test "logical_immediate_p (op, TImode)"))) - -(define_constraint "Z" - "An immediate for iohl instruction. const_int is sign extended to 128 bit." - (and (match_code "const_int,const_double,const_vector") - (match_test "iohl_immediate_p (op, TImode)"))) - -(define_constraint "a" - "An immediate which can be loaded with the il/ila/ilh/ilhu instructions. const_int is treated as a 64-bit value." - (and (match_code "const_int") - (match_test "immediate_load_p (op, DImode)"))) - -(define_constraint "c" - "An immediate for and/xor/or instructions. const_int is treated as a 64-bit value." - (and (match_code "const_int") - (match_test "logical_immediate_p (op, DImode)"))) - -(define_constraint "d" - "An immediate for iohl instruction. const_int is treated as a 64-bit value." - (and (match_code "const_int") - (match_test "iohl_immediate_p (op, DImode)"))) - -(define_constraint "f" - "An immediate which can be loaded with fsmbi." - (and (match_code "const_int,const_double,const_vector") - (match_test "fsmbi_const_p (op)"))) - -(define_constraint "j" - "An immediate which can be loaded with one of the cbd/chd/cwd/cdd instructions. const_int is treated as a 32-bit value." - (and (match_code "const_int,const_double,const_vector") - (match_test "cpat_const_p (op, SImode)"))) - -(define_constraint "k" - "An immediate which can be loaded with one of the cbd/chd/cwd/cdd instructions. const_int is treated as a 64-bit value." - (and (match_code "const_int,const_double,const_vector") - (match_test "cpat_const_p (op, DImode)"))) - -(define_constraint "l" - "An immediate which can be loaded with one of the cbd/chd/cwd/cdd instructions." - (and (match_code "const_double,const_vector") - (match_test "cpat_const_p (op, TImode)"))) - - -;; Integer constraints - -(define_constraint "I" - "A constant in the range [-64, 63] for shift/rotate instructions." - (and (match_code "const_int") - (match_test "ival >= -0x40 && ival <= 0x3f"))) - -(define_constraint "J" - "An unsigned 7-bit constant for conversion/nop/channel instructions." - (and (match_code "const_int") - (match_test "ival >= 0 && ival <= 0x7f"))) - -(define_constraint "K" - "A signed 10-bit constant for most arithmetic instructions." - (and (match_code "const_int") - (match_test "ival >= -0x200 && ival <= 0x1ff"))) - -(define_constraint "M" - "A signed 16-bit immediate for @code{stop}." - (and (match_code "const_int") - (match_test "ival >= -0x8000ll && ival <= 0x7fffll"))) - -(define_constraint "N" - "An unsigned 16-bit constant for @code{iohl} and @code{fsmbi}." - (and (match_code "const_int") - (match_test "ival >= 0 && ival <= 0xffff"))) - -(define_constraint "O" - "An unsigned 7-bit constant whose 3 least significant bits are 0." - (and (match_code "const_int") - (match_test "(ival & 7) == 0"))) - -(define_constraint "P" - "An unsigned 3-bit constant for 16-byte rotates and shifts" - (and (match_code "const_int") - (match_test "ival >= 0 && ival <= 7"))) - - -;; Memory constraints - -(define_memory_constraint "R" - "Call operand, reg, for indirect calls" - (and (match_code "mem") - (match_test "GET_CODE(XEXP(op, 0)) == REG"))) - -(define_memory_constraint "S" - "Call operand, symbol, for relative calls." - (and (match_code "mem") - (match_test "!TARGET_LARGE_MEM - && ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF - || GET_CODE (XEXP (op, 0)) == LABEL_REF))"))) - -(define_memory_constraint "T" - "Call operand, const_int, for absolute calls." - (and (match_code "mem") - (match_test "GET_CODE (XEXP (op, 0)) == CONST_INT - && INTVAL (XEXP (op, 0)) >= 0 - && INTVAL (XEXP (op, 0)) <= 0x3ffff"))) - - -;; Floating-point constant constraints. - -(define_constraint "v" - "Floating point power of 2 with exponent in [0..127]" - (and (match_code "const_double,const_vector") - (match_test "exp2_immediate_p (op, VOIDmode, 0, 127)"))) - -(define_constraint "w" - "Floating point power of 2 with exponent in [-126..0]" - (and (match_code "const_double,const_vector") - (match_test "exp2_immediate_p (op, VOIDmode, -126, 0)"))) diff --git a/gcc/config/spu/predicates.md b/gcc/config/spu/predicates.md deleted file mode 100644 index 8d7767d..0000000 --- a/gcc/config/spu/predicates.md +++ /dev/null @@ -1,122 +0,0 @@ -;; Predicate definitions for CELL SPU -;; Copyright (C) 2006-2019 Free Software Foundation, Inc. -;; -;; This file is free software; you can redistribute it and/or modify it under -;; the terms of the GNU General Public License as published by the Free -;; Software Foundation; either version 3 of the License, or (at your option) -;; any later version. - -;; This file is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -;; for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; . - -;; Return 1 if operand is constant zero of its mode -(define_predicate "const_zero_operand" - (and (match_code "const_int,const,const_double,const_vector") - (match_test "op == CONST0_RTX (mode)"))) - -(define_predicate "const_one_operand" - (and (match_code "const_int,const,const_double,const_vector") - (match_test "op == CONST1_RTX (mode)"))) - -(define_predicate "spu_reg_operand" - (and (match_operand 0 "register_operand") - (ior (not (match_code "subreg")) - (match_test "valid_subreg (op)")))) - -(define_predicate "spu_nonimm_operand" - (and (match_operand 0 "nonimmediate_operand") - (ior (not (match_code "subreg")) - (match_test "valid_subreg (op)")))) - -(define_predicate "spu_nonmem_operand" - (and (match_operand 0 "nonmemory_operand") - (ior (not (match_code "subreg")) - (match_test "valid_subreg (op)")))) - -(define_predicate "spu_mov_operand" - (ior (match_operand 0 "memory_operand") - (match_operand 0 "spu_nonmem_operand"))) - -(define_predicate "spu_dest_operand" - (ior (match_operand 0 "memory_operand") - (match_operand 0 "spu_reg_operand"))) - -(define_predicate "call_operand" - (and (match_code "mem") - (match_test "(!TARGET_LARGE_MEM && satisfies_constraint_S (op)) - || (satisfies_constraint_R (op) - && REGNO (XEXP (op, 0)) != FRAME_POINTER_REGNUM - && REGNO (XEXP (op, 0)) != ARG_POINTER_REGNUM - && (REGNO (XEXP (op, 0)) < FIRST_PSEUDO_REGISTER - || REGNO (XEXP (op, 0)) > LAST_VIRTUAL_REGISTER))"))) - -(define_predicate "vec_imm_operand" - (and (match_code "const_int,const_double,const_vector") - (match_test "spu_legitimate_constant_p (mode, op)"))) - -(define_predicate "spu_arith_operand" - (match_code "reg,subreg,const_int,const_vector") - { - if (spu_reg_operand (op, mode)) - return 1; - if (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_VECTOR) - return arith_immediate_p (op, mode, -0x200, 0x1ff); - return 0; - }) - -(define_predicate "spu_logical_operand" - (match_code "reg,subreg,const_int,const_double,const_vector") - { - if (spu_reg_operand (op, mode)) - return 1; - if (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE - || GET_CODE (op) == CONST_VECTOR) - return logical_immediate_p (op, mode); - return 0; - }) - -(define_predicate "spu_ior_operand" - (match_code "reg,subreg,const_int,const_double,const_vector") - { - if (spu_reg_operand (op, mode)) - return 1; - if (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE - || GET_CODE (op) == CONST_VECTOR) - return logical_immediate_p (op, mode) - || iohl_immediate_p (op, mode); - return 0; - }) - -(define_predicate "imm_K_operand" - (and (match_code "const_int") - (match_test "arith_immediate_p (op, mode, -0x200, 0x1ff)"))) - -;; Return 1 if OP is a comparison operation that is valid for a branch insn. -;; We only check the opcode against the mode of the register value here. -(define_predicate "branch_comparison_operator" - (and (match_code "eq,ne") - (ior (match_test "GET_MODE (XEXP (op, 0)) == HImode") - (match_test "GET_MODE (XEXP (op, 0)) == SImode")))) - -(define_predicate "spu_inv_exp2_operand" - (and (match_code "const_double,const_vector") - (and (match_operand 0 "immediate_operand") - (match_test "exp2_immediate_p (op, mode, -126, 0)")))) - -(define_predicate "spu_exp2_operand" - (and (match_code "const_double,const_vector") - (and (match_operand 0 "immediate_operand") - (match_test "exp2_immediate_p (op, mode, 0, 127)")))) - -(define_predicate "shiftrt_operator" - (match_code "lshiftrt,ashiftrt")) - -(define_predicate "extend_operator" - (match_code "sign_extend,zero_extend")) - diff --git a/gcc/config/spu/spu-builtins.def b/gcc/config/spu/spu-builtins.def deleted file mode 100644 index 29b3639..0000000 --- a/gcc/config/spu/spu-builtins.def +++ /dev/null @@ -1,781 +0,0 @@ -/* Definitions of builtin functions for the Synergistic Processing Unit (SPU). */ -/* Copyright (C) 2006-2019 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - . */ - - -/* The first argument to these macros is the return type of the builtin, - * the rest are arguments of the builtin. */ -#define _A1(a) {a, SPU_BTI_END_OF_PARAMS} -#define _A2(a,b) {a, b, SPU_BTI_END_OF_PARAMS} -#define _A3(a,b,c) {a, b, c, SPU_BTI_END_OF_PARAMS} -#define _A4(a,b,c,d) {a, b, c, d, SPU_BTI_END_OF_PARAMS} - -/* definitions to support si intrinsic functions: (These and other builtin - * definitions must precede definitions of the overloaded generic intrinsics */ - -DEF_BUILTIN (SI_LQD, CODE_FOR_spu_lqd, "si_lqd", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10_4)) -DEF_BUILTIN (SI_LQX, CODE_FOR_spu_lqx, "si_lqx", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_LQA, CODE_FOR_spu_lqa, "si_lqa", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_U16_2)) -DEF_BUILTIN (SI_LQR, CODE_FOR_spu_lqr, "si_lqr", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_S16_2)) -DEF_BUILTIN (SI_STQD, CODE_FOR_spu_stqd, "si_stqd", B_INSN, _A4(SPU_BTI_VOID, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10_4)) -DEF_BUILTIN (SI_STQX, CODE_FOR_spu_stqx, "si_stqx", B_INSN, _A4(SPU_BTI_VOID, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_STQA, CODE_FOR_spu_stqa, "si_stqa", B_INSN, _A3(SPU_BTI_VOID, SPU_BTI_QUADWORD, SPU_BTI_U16_2)) -DEF_BUILTIN (SI_STQR, CODE_FOR_spu_stqr, "si_stqr", B_INSN, _A3(SPU_BTI_VOID, SPU_BTI_QUADWORD, SPU_BTI_S16_2)) -DEF_BUILTIN (SI_CBD, CODE_FOR_spu_cbx, "si_cbd", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S7)) -DEF_BUILTIN (SI_CBX, CODE_FOR_spu_cbx, "si_cbx", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_CHD, CODE_FOR_spu_chx, "si_chd", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S7)) -DEF_BUILTIN (SI_CHX, CODE_FOR_spu_chx, "si_chx", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_CWD, CODE_FOR_spu_cwx, "si_cwd", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S7)) -DEF_BUILTIN (SI_CWX, CODE_FOR_spu_cwx, "si_cwx", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_CDD, CODE_FOR_spu_cdx, "si_cdd", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S7)) -DEF_BUILTIN (SI_CDX, CODE_FOR_spu_cdx, "si_cdx", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_ILH, CODE_FOR_movv8hi, "si_ilh", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_16)) -DEF_BUILTIN (SI_ILHU, CODE_FOR_spu_ilhu, "si_ilhu", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_16)) -DEF_BUILTIN (SI_IL, CODE_FOR_movv4si, "si_il", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_S16)) -DEF_BUILTIN (SI_ILA, CODE_FOR_movv4si, "si_ila", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_U18)) -DEF_BUILTIN (SI_IOHL, CODE_FOR_iorv4si3, "si_iohl", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_U16)) -DEF_BUILTIN (SI_FSMBI, CODE_FOR_spu_fsmb, "si_fsmbi", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_16)) -DEF_BUILTIN (SI_AH, CODE_FOR_addv8hi3, "si_ah", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_AHI, CODE_FOR_addv8hi3, "si_ahi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10)) -DEF_BUILTIN (SI_A, CODE_FOR_addv4si3, "si_a", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_AI, CODE_FOR_addv4si3, "si_ai", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10)) -DEF_BUILTIN (SI_ADDX, CODE_FOR_addx_v4si, "si_addx", B_INSN, _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_CG, CODE_FOR_cg_v4si, "si_cg", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_CGX, CODE_FOR_cgx_v4si, "si_cgx", B_INSN, _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_SFH, CODE_FOR_spu_sfh, "si_sfh", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_SFHI, CODE_FOR_spu_sfh, "si_sfhi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10)) -DEF_BUILTIN (SI_SF, CODE_FOR_spu_sf, "si_sf", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_SFI, CODE_FOR_spu_sf, "si_sfi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10)) -DEF_BUILTIN (SI_SFX, CODE_FOR_spu_sfx, "si_sfx", B_INSN, _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_BG, CODE_FOR_spu_bg, "si_bg", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_BGX, CODE_FOR_spu_bgx, "si_bgx", B_INSN, _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_MPY, CODE_FOR_vec_widen_smult_odd_v8hi, "si_mpy", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_MPYU, CODE_FOR_vec_widen_umult_odd_v8hi, "si_mpyu", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_MPYI, CODE_FOR_vec_widen_smult_odd_v8hi, "si_mpyi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10)) -DEF_BUILTIN (SI_MPYUI, CODE_FOR_vec_widen_umult_odd_v8hi, "si_mpyui", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10)) -DEF_BUILTIN (SI_MPYA, CODE_FOR_spu_mpya, "si_mpya", B_INSN, _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_MPYH, CODE_FOR_spu_mpyh, "si_mpyh", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_MPYS, CODE_FOR_spu_mpys, "si_mpys", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_MPYHH, CODE_FOR_vec_widen_smult_even_v8hi, "si_mpyhh", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_MPYHHU, CODE_FOR_vec_widen_umult_even_v8hi, "si_mpyhhu", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_MPYHHA, CODE_FOR_spu_mpyhha, "si_mpyhha", B_INSN, _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_MPYHHAU, CODE_FOR_spu_mpyhhau, "si_mpyhhau", B_INSN, _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_CLZ, CODE_FOR_clzv4si2, "si_clz", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_CNTB, CODE_FOR_cntb_v16qi, "si_cntb", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_FSMB, CODE_FOR_spu_fsmb, "si_fsmb", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_FSMH, CODE_FOR_spu_fsmh, "si_fsmh", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_FSM, CODE_FOR_spu_fsm, "si_fsm", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_GBB, CODE_FOR_spu_gbb, "si_gbb", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_GBH, CODE_FOR_spu_gbh, "si_gbh", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_GB, CODE_FOR_spu_gb, "si_gb", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_AVGB, CODE_FOR_spu_avgb, "si_avgb", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_ABSDB, CODE_FOR_spu_absdb, "si_absdb", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_SUMB, CODE_FOR_spu_sumb, "si_sumb", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_XSBH, CODE_FOR_spu_xsbh, "si_xsbh", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_XSHW, CODE_FOR_spu_xshw, "si_xshw", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_XSWD, CODE_FOR_spu_xswd, "si_xswd", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_AND, CODE_FOR_andv16qi3, "si_and", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_ANDC, CODE_FOR_andc_v16qi, "si_andc", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_ANDBI, CODE_FOR_andv16qi3, "si_andbi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10)) -DEF_BUILTIN (SI_ANDHI, CODE_FOR_andv8hi3, "si_andhi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10)) -DEF_BUILTIN (SI_ANDI, CODE_FOR_andv4si3, "si_andi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10)) -DEF_BUILTIN (SI_OR, CODE_FOR_iorv16qi3, "si_or", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_ORC, CODE_FOR_orc_v16qi, "si_orc", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_ORBI, CODE_FOR_iorv16qi3, "si_orbi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10)) -DEF_BUILTIN (SI_ORHI, CODE_FOR_iorv8hi3, "si_orhi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10)) -DEF_BUILTIN (SI_ORI, CODE_FOR_iorv4si3, "si_ori", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10)) -DEF_BUILTIN (SI_ORX, CODE_FOR_spu_orx, "si_orx", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_XOR, CODE_FOR_xorv16qi3, "si_xor", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_XORBI, CODE_FOR_xorv16qi3, "si_xorbi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10)) -DEF_BUILTIN (SI_XORHI, CODE_FOR_xorv8hi3, "si_xorhi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10)) -DEF_BUILTIN (SI_XORI, CODE_FOR_xorv4si3, "si_xori", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10)) -DEF_BUILTIN (SI_NAND, CODE_FOR_nand_v16qi, "si_nand", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_NOR, CODE_FOR_nor_v16qi, "si_nor", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_EQV, CODE_FOR_eqv_v16qi, "si_eqv", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_SELB, CODE_FOR_selb, "si_selb", B_INSN, _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_SHUFB, CODE_FOR_shufb, "si_shufb", B_INSN, _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_SHLH, CODE_FOR_vashlv8hi3, "si_shlh", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_SHLHI, CODE_FOR_vashlv8hi3, "si_shlhi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_7)) -DEF_BUILTIN (SI_SHL, CODE_FOR_vashlv4si3, "si_shl", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_SHLI, CODE_FOR_vashlv4si3, "si_shli", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_7)) -DEF_BUILTIN (SI_SHLQBI, CODE_FOR_shlqbi_ti, "si_shlqbi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_SHLQBII, CODE_FOR_shlqbi_ti, "si_shlqbii", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_7)) -DEF_BUILTIN (SI_SHLQBY, CODE_FOR_shlqby_ti, "si_shlqby", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_SHLQBYI, CODE_FOR_shlqby_ti, "si_shlqbyi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_7)) -DEF_BUILTIN (SI_SHLQBYBI, CODE_FOR_shlqbybi_ti, "si_shlqbybi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_ROTH, CODE_FOR_vrotlv8hi3, "si_roth", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_ROTHI, CODE_FOR_vrotlv8hi3, "si_rothi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_7)) -DEF_BUILTIN (SI_ROT, CODE_FOR_vrotlv4si3, "si_rot", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_ROTI, CODE_FOR_vrotlv4si3, "si_roti", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_7)) -DEF_BUILTIN (SI_ROTQBY, CODE_FOR_rotqby_ti, "si_rotqby", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_ROTQBYI, CODE_FOR_rotqby_ti, "si_rotqbyi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_7)) -DEF_BUILTIN (SI_ROTQBYBI, CODE_FOR_rotqbybi_ti, "si_rotqbybi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_ROTQBI, CODE_FOR_rotqbi_ti, "si_rotqbi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_ROTQBII, CODE_FOR_rotqbi_ti, "si_rotqbii", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_7)) -DEF_BUILTIN (SI_ROTHM, CODE_FOR_rotm_v8hi, "si_rothm", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_ROTHMI, CODE_FOR_rotm_v8hi, "si_rothmi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_7)) -DEF_BUILTIN (SI_ROTM, CODE_FOR_rotm_v4si, "si_rotm", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_ROTMI, CODE_FOR_rotm_v4si, "si_rotmi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_7)) -DEF_BUILTIN (SI_ROTQMBY, CODE_FOR_rotqmby_ti, "si_rotqmby", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_ROTQMBYI, CODE_FOR_rotqmby_ti, "si_rotqmbyi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_7)) -DEF_BUILTIN (SI_ROTQMBI, CODE_FOR_rotqmbi_ti, "si_rotqmbi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_ROTQMBII, CODE_FOR_rotqmbi_ti, "si_rotqmbii", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_7)) -DEF_BUILTIN (SI_ROTQMBYBI, CODE_FOR_rotqmbybi_ti, "si_rotqmbybi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_ROTMAH, CODE_FOR_rotma_v8hi, "si_rotmah", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_ROTMAHI, CODE_FOR_rotma_v8hi, "si_rotmahi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_7)) -DEF_BUILTIN (SI_ROTMA, CODE_FOR_rotma_v4si, "si_rotma", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_ROTMAI, CODE_FOR_rotma_v4si, "si_rotmai", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_7)) -DEF_BUILTIN (SI_HEQ, CODE_FOR_spu_heq, "si_heq", B_INSN, _A3(SPU_BTI_VOID, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_HEQI, CODE_FOR_spu_heq, "si_heqi", B_INSN, _A3(SPU_BTI_VOID, SPU_BTI_QUADWORD, SPU_BTI_S10)) -DEF_BUILTIN (SI_HGT, CODE_FOR_spu_hgt, "si_hgt", B_INSN, _A3(SPU_BTI_VOID, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_HGTI, CODE_FOR_spu_hgt, "si_hgti", B_INSN, _A3(SPU_BTI_VOID, SPU_BTI_QUADWORD, SPU_BTI_S10)) -DEF_BUILTIN (SI_HLGT, CODE_FOR_spu_hlgt, "si_hlgt", B_INSN, _A3(SPU_BTI_VOID, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_HLGTI, CODE_FOR_spu_hlgt, "si_hlgti", B_INSN, _A3(SPU_BTI_VOID, SPU_BTI_QUADWORD, SPU_BTI_S10)) -DEF_BUILTIN (SI_CEQB, CODE_FOR_ceq_v16qi, "si_ceqb", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_CEQBI, CODE_FOR_ceq_v16qi, "si_ceqbi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10)) -DEF_BUILTIN (SI_CEQH, CODE_FOR_ceq_v8hi, "si_ceqh", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_CEQHI, CODE_FOR_ceq_v8hi, "si_ceqhi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10)) -DEF_BUILTIN (SI_CEQ, CODE_FOR_ceq_v4si, "si_ceq", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_CEQI, CODE_FOR_ceq_v4si, "si_ceqi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10)) -DEF_BUILTIN (SI_CGTB, CODE_FOR_cgt_v16qi, "si_cgtb", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_CGTBI, CODE_FOR_cgt_v16qi, "si_cgtbi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10)) -DEF_BUILTIN (SI_CGTH, CODE_FOR_cgt_v8hi, "si_cgth", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_CGTHI, CODE_FOR_cgt_v8hi, "si_cgthi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10)) -DEF_BUILTIN (SI_CGT, CODE_FOR_cgt_v4si, "si_cgt", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_CGTI, CODE_FOR_cgt_v4si, "si_cgti", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10)) -DEF_BUILTIN (SI_CLGTB, CODE_FOR_clgt_v16qi, "si_clgtb", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_CLGTBI, CODE_FOR_clgt_v16qi, "si_clgtbi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10)) -DEF_BUILTIN (SI_CLGTH, CODE_FOR_clgt_v8hi, "si_clgth", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_CLGTHI, CODE_FOR_clgt_v8hi, "si_clgthi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10)) -DEF_BUILTIN (SI_CLGT, CODE_FOR_clgt_v4si, "si_clgt", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_CLGTI, CODE_FOR_clgt_v4si, "si_clgti", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10)) -DEF_BUILTIN (SI_BISLED, CODE_FOR_spu_bisled, "si_bisled", B_BISLED, _A3(SPU_BTI_VOID, SPU_BTI_QUADWORD, SPU_BTI_PTR)) -DEF_BUILTIN (SI_BISLEDD, CODE_FOR_spu_bisledd, "si_bisledd", B_BISLED, _A3(SPU_BTI_VOID, SPU_BTI_QUADWORD, SPU_BTI_PTR)) -DEF_BUILTIN (SI_BISLEDE, CODE_FOR_spu_bislede, "si_bislede", B_BISLED, _A3(SPU_BTI_VOID, SPU_BTI_QUADWORD, SPU_BTI_PTR)) -DEF_BUILTIN (SI_FA, CODE_FOR_addv4sf3, "si_fa", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_DFA, CODE_FOR_addv2df3, "si_dfa", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_FS, CODE_FOR_subv4sf3, "si_fs", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_DFS, CODE_FOR_subv2df3, "si_dfs", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_FM, CODE_FOR_mulv4sf3, "si_fm", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_DFM, CODE_FOR_mulv2df3, "si_dfm", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_FMA, CODE_FOR_fmav4sf4, "si_fma", B_INSN, _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_DFMA, CODE_FOR_fmav2df4, "si_dfma", B_INSN, _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_DFNMA, CODE_FOR_nfmav2df4, "si_dfnma", B_INSN, _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_FNMS, CODE_FOR_fnmav4sf4, "si_fnms", B_INSN, _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_DFNMS, CODE_FOR_nfmsv2df4, "si_dfnms", B_INSN, _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_FMS, CODE_FOR_fmsv4sf4, "si_fms", B_INSN, _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_DFMS, CODE_FOR_fmsv2df4, "si_dfms", B_INSN, _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_FREST, CODE_FOR_frest_v4sf, "si_frest", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_FRSQEST, CODE_FOR_frsqest_v4sf, "si_frsqest", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_FI, CODE_FOR_fi_v4sf, "si_fi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_CSFLT, CODE_FOR_spu_csflt, "si_csflt", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_U7)) -DEF_BUILTIN (SI_CFLTS, CODE_FOR_spu_cflts, "si_cflts", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_U7)) -DEF_BUILTIN (SI_CUFLT, CODE_FOR_spu_cuflt, "si_cuflt", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_U7)) -DEF_BUILTIN (SI_CFLTU, CODE_FOR_spu_cfltu, "si_cfltu", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_U7)) -DEF_BUILTIN (SI_FRDS, CODE_FOR_spu_frds, "si_frds", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_FESD, CODE_FOR_spu_fesd, "si_fesd", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_FCEQ, CODE_FOR_ceq_v4sf, "si_fceq", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_DFCEQ, CODE_FOR_ceq_v2df, "si_dfceq", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_FCMEQ, CODE_FOR_cmeq_v4sf, "si_fcmeq", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_DFCMEQ, CODE_FOR_cmeq_v2df, "si_dfcmeq", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_FCGT, CODE_FOR_cgt_v4sf, "si_fcgt", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_DFCGT, CODE_FOR_cgt_v2df, "si_dfcgt", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_FCMGT, CODE_FOR_cmgt_v4sf, "si_fcmgt", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_DFCMGT, CODE_FOR_cmgt_v2df, "si_dfcmgt", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_DFTSV, CODE_FOR_dftsv, "si_dftsv", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_U7)) -DEF_BUILTIN (SI_STOP, CODE_FOR_spu_stop, "si_stop", B_INSN, _A2(SPU_BTI_VOID, SPU_BTI_U14)) -DEF_BUILTIN (SI_STOPD, CODE_FOR_spu_stopd, "si_stopd", B_INSN, _A4(SPU_BTI_VOID, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_LNOP, CODE_FOR_lnop, "si_lnop", B_INSN, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SI_NOP, CODE_FOR_nop, "si_nop", B_INSN, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SI_SYNC, CODE_FOR_sync, "si_sync", B_INSN, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SI_SYNCC, CODE_FOR_syncc, "si_syncc", B_INSN, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SI_DSYNC, CODE_FOR_dsync, "si_dsync", B_INSN, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SI_MFSPR, CODE_FOR_spu_mfspr, "si_mfspr", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_U7)) -DEF_BUILTIN (SI_MTSPR, CODE_FOR_spu_mtspr, "si_mtspr", B_INSN, _A3(SPU_BTI_VOID, SPU_BTI_U7, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_FSCRRD, CODE_FOR_spu_fscrrd, "si_fscrrd", B_INSN, _A1(SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_FSCRWR, CODE_FOR_spu_fscrwr, "si_fscrwr", B_INSN, _A2(SPU_BTI_VOID, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_RDCH, CODE_FOR_spu_rdch, "si_rdch", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_U7)) -DEF_BUILTIN (SI_RCHCNT, CODE_FOR_spu_rchcnt, "si_rchcnt", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_U7)) -DEF_BUILTIN (SI_WRCH, CODE_FOR_spu_wrch, "si_wrch", B_INSN, _A3(SPU_BTI_VOID, SPU_BTI_U7, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_TO_CHAR, CODE_FOR_spu_convert, "si_to_char", B_INSN, _A2(SPU_BTI_INTQI, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_TO_UCHAR, CODE_FOR_spu_convert, "si_to_uchar", B_INSN, _A2(SPU_BTI_UINTQI, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_TO_SHORT, CODE_FOR_spu_convert, "si_to_short", B_INSN, _A2(SPU_BTI_INTHI, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_TO_USHORT, CODE_FOR_spu_convert, "si_to_ushort", B_INSN, _A2(SPU_BTI_UINTHI, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_TO_INT, CODE_FOR_spu_convert, "si_to_int", B_INSN, _A2(SPU_BTI_INTSI, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_TO_UINT, CODE_FOR_spu_convert, "si_to_uint", B_INSN, _A2(SPU_BTI_UINTSI, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_TO_LONG, CODE_FOR_spu_convert, "si_to_long", B_INSN, _A2(SPU_BTI_INTDI, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_TO_ULONG, CODE_FOR_spu_convert, "si_to_ulong", B_INSN, _A2(SPU_BTI_UINTDI, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_TO_FLOAT, CODE_FOR_spu_convert, "si_to_float", B_INSN, _A2(SPU_BTI_FLOAT, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_TO_DOUBLE, CODE_FOR_spu_convert, "si_to_double", B_INSN, _A2(SPU_BTI_DOUBLE, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_TO_PTR, CODE_FOR_spu_convert, "si_to_ptr", B_INSN, _A2(SPU_BTI_PTR, SPU_BTI_QUADWORD)) -DEF_BUILTIN (SI_FROM_CHAR, CODE_FOR_spu_convert, "si_from_char", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_INTQI)) -DEF_BUILTIN (SI_FROM_UCHAR, CODE_FOR_spu_convert, "si_from_uchar", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_UINTQI)) -DEF_BUILTIN (SI_FROM_SHORT, CODE_FOR_spu_convert, "si_from_short", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_INTHI)) -DEF_BUILTIN (SI_FROM_USHORT, CODE_FOR_spu_convert, "si_from_ushort", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_UINTHI)) -DEF_BUILTIN (SI_FROM_INT, CODE_FOR_spu_convert, "si_from_int", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_INTSI)) -DEF_BUILTIN (SI_FROM_UINT, CODE_FOR_spu_convert, "si_from_uint", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_UINTSI)) -DEF_BUILTIN (SI_FROM_LONG, CODE_FOR_spu_convert, "si_from_long", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_INTDI)) -DEF_BUILTIN (SI_FROM_ULONG, CODE_FOR_spu_convert, "si_from_ulong", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_UINTDI)) -DEF_BUILTIN (SI_FROM_FLOAT, CODE_FOR_spu_convert, "si_from_float", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_FLOAT)) -DEF_BUILTIN (SI_FROM_DOUBLE, CODE_FOR_spu_convert, "si_from_double", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_DOUBLE)) -DEF_BUILTIN (SI_FROM_PTR, CODE_FOR_spu_convert, "si_from_ptr", B_INSN, _A2(SPU_BTI_QUADWORD, SPU_BTI_PTR)) - -/* definitions to support generic builtin functions: */ - -DEF_BUILTIN (SPU_CONVTS, CODE_FOR_spu_cflts, "spu_convts", B_INSN, _A3(SPU_BTI_V4SI, SPU_BTI_V4SF, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_CONVTU, CODE_FOR_spu_cfltu, "spu_convtu", B_INSN, _A3(SPU_BTI_UV4SI, SPU_BTI_V4SF, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_ROUNDTF, CODE_FOR_spu_frds, "spu_roundtf", B_INSN, _A2(SPU_BTI_V4SF, SPU_BTI_V2DF)) -DEF_BUILTIN (SPU_MULH, CODE_FOR_spu_mpyh, "spu_mulh", B_INSN, _A3(SPU_BTI_V4SI, SPU_BTI_V8HI, SPU_BTI_V8HI)) -DEF_BUILTIN (SPU_MULSR, CODE_FOR_spu_mpys, "spu_mulsr", B_INSN, _A3(SPU_BTI_V4SI, SPU_BTI_V8HI, SPU_BTI_V8HI)) -DEF_BUILTIN (SPU_FREST, CODE_FOR_frest_v4sf, "spu_frest", B_INSN, _A2(SPU_BTI_V4SF, SPU_BTI_V4SF)) -DEF_BUILTIN (SPU_FRSQEST, CODE_FOR_frsqest_v4sf, "spu_frsqest", B_INSN, _A2(SPU_BTI_V4SF, SPU_BTI_V4SF)) -DEF_BUILTIN (SPU_NMADD, CODE_FOR_nfmav2df4, "spu_nmadd", B_INSN, _A4(SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_V2DF)) -DEF_BUILTIN (SPU_ABSD, CODE_FOR_spu_absdb, "spu_absd", B_INSN, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI)) -DEF_BUILTIN (SPU_AVG, CODE_FOR_spu_avgb, "spu_avg", B_INSN, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI)) -DEF_BUILTIN (SPU_SUMB, CODE_FOR_spu_sumb, "spu_sumb", B_INSN, _A3(SPU_BTI_UV8HI, SPU_BTI_UV16QI, SPU_BTI_UV16QI)) -DEF_BUILTIN (SPU_BISLED, CODE_FOR_spu_bisled, "spu_bisled", B_BISLED, _A3(SPU_BTI_VOID, SPU_BTI_PTR, SPU_BTI_PTR)) -DEF_BUILTIN (SPU_BISLED_D, CODE_FOR_spu_bisledd, "spu_bisled_d", B_BISLED, _A3(SPU_BTI_VOID, SPU_BTI_PTR, SPU_BTI_PTR)) -DEF_BUILTIN (SPU_BISLED_E, CODE_FOR_spu_bislede, "spu_bisled_e", B_BISLED, _A3(SPU_BTI_VOID, SPU_BTI_PTR, SPU_BTI_PTR)) -DEF_BUILTIN (SPU_IDISABLE, CODE_FOR_spu_idisable, "spu_idisable", B_INSN, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_IENABLE, CODE_FOR_spu_ienable, "spu_ienable", B_INSN, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_MASK_FOR_LOAD, CODE_FOR_spu_lvsr, "spu_lvsr", B_INSN, _A2(SPU_BTI_V16QI, SPU_BTI_PTR)) -DEF_BUILTIN (SPU_TESTSV, CODE_FOR_dftsv, "spu_testsv", B_INSN, _A3(SPU_BTI_UV2DI, SPU_BTI_V2DF, SPU_BTI_U7)) - -/* definitions to support overloaded generic builtin functions: */ - -DEF_BUILTIN (SPU_CONVTF, CODE_FOR_nothing, "spu_convtf", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_CONVTF_0, CODE_FOR_spu_cuflt, "spu_convtf_0", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_UV4SI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_CONVTF_1, CODE_FOR_spu_csflt, "spu_convtf_1", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_V4SI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_EXTEND, CODE_FOR_nothing, "spu_extend", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_EXTEND_0, CODE_FOR_spu_xsbh, "spu_extend_0", B_INTERNAL, _A2(SPU_BTI_V8HI, SPU_BTI_V16QI)) -DEF_BUILTIN (SPU_EXTEND_1, CODE_FOR_spu_xshw, "spu_extend_1", B_INTERNAL, _A2(SPU_BTI_V4SI, SPU_BTI_V8HI)) -DEF_BUILTIN (SPU_EXTEND_2, CODE_FOR_spu_xswd, "spu_extend_2", B_INTERNAL, _A2(SPU_BTI_V2DI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_EXTEND_3, CODE_FOR_spu_fesd, "spu_extend_3", B_INTERNAL, _A2(SPU_BTI_V2DF, SPU_BTI_V4SF)) -DEF_BUILTIN (SPU_ADD, CODE_FOR_nothing, "spu_add", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_ADD_0, CODE_FOR_addv4si3, "spu_add_0", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_ADD_1, CODE_FOR_addv4si3, "spu_add_1", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_ADD_2, CODE_FOR_addv8hi3, "spu_add_2", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UV8HI)) -DEF_BUILTIN (SPU_ADD_3, CODE_FOR_addv8hi3, "spu_add_3", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_V8HI)) -DEF_BUILTIN (SPU_ADD_4, CODE_FOR_addv4sf3, "spu_add_4", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_V4SF)) -DEF_BUILTIN (SPU_ADD_5, CODE_FOR_addv2df3, "spu_add_5", B_INTERNAL, _A3(SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_V2DF)) -DEF_BUILTIN (SPU_ADD_6, CODE_FOR_addv8hi3, "spu_add_6", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UINTHI)) -DEF_BUILTIN (SPU_ADD_7, CODE_FOR_addv8hi3, "spu_add_7", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_INTHI)) -DEF_BUILTIN (SPU_ADD_8, CODE_FOR_addv4si3, "spu_add_8", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_ADD_9, CODE_FOR_addv4si3, "spu_add_9", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_ADDX, CODE_FOR_nothing, "spu_addx", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_ADDX_0, CODE_FOR_addx_v4si, "spu_addx_0", B_INTERNAL, _A4(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_ADDX_1, CODE_FOR_addx_v4si, "spu_addx_1", B_INTERNAL, _A4(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_GENC, CODE_FOR_nothing, "spu_genc", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_GENC_0, CODE_FOR_cg_v4si, "spu_genc_0", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_GENC_1, CODE_FOR_cg_v4si, "spu_genc_1", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_GENCX, CODE_FOR_nothing, "spu_gencx", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_GENCX_0, CODE_FOR_cgx_v4si, "spu_gencx_0", B_INTERNAL, _A4(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_GENCX_1, CODE_FOR_cgx_v4si, "spu_gencx_1", B_INTERNAL, _A4(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_MADD, CODE_FOR_nothing, "spu_madd", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_MADD_0, CODE_FOR_spu_mpya, "spu_madd_0", B_INTERNAL, _A4(SPU_BTI_V4SI, SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_MADD_1, CODE_FOR_fmav4sf4, "spu_madd_1", B_INTERNAL, _A4(SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_V4SF)) -DEF_BUILTIN (SPU_MADD_2, CODE_FOR_fmav2df4, "spu_madd_2", B_INTERNAL, _A4(SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_V2DF)) -DEF_BUILTIN (SPU_MSUB, CODE_FOR_nothing, "spu_msub", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_MSUB_0, CODE_FOR_fmsv4sf4, "spu_msub_0", B_INTERNAL, _A4(SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_V4SF)) -DEF_BUILTIN (SPU_MSUB_1, CODE_FOR_fmsv2df4, "spu_msub_1", B_INTERNAL, _A4(SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_V2DF)) -DEF_BUILTIN (SPU_MHHADD, CODE_FOR_nothing, "spu_mhhadd", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_MHHADD_0, CODE_FOR_spu_mpyhhau, "spu_mhhadd_0", B_INTERNAL, _A4(SPU_BTI_UV4SI, SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_MHHADD_1, CODE_FOR_spu_mpyhha, "spu_mhhadd_1", B_INTERNAL, _A4(SPU_BTI_V4SI, SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_MULE, CODE_FOR_nothing, "spu_mule", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_MULE_0, CODE_FOR_vec_widen_umult_even_v8hi, "spu_mule_0", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV8HI, SPU_BTI_UV8HI)) -DEF_BUILTIN (SPU_MULE_1, CODE_FOR_vec_widen_smult_even_v8hi, "spu_mule_1", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V8HI, SPU_BTI_V8HI)) -DEF_BUILTIN (SPU_MUL, CODE_FOR_nothing, "spu_mul", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_MUL_0, CODE_FOR_mulv4sf3, "spu_mul_0", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_V4SF)) -DEF_BUILTIN (SPU_MUL_1, CODE_FOR_mulv2df3, "spu_mul_1", B_INTERNAL, _A3(SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_V2DF)) -DEF_BUILTIN (SPU_MULO, CODE_FOR_nothing, "spu_mulo", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_MULO_0, CODE_FOR_vec_widen_smult_odd_v8hi, "spu_mulo_0", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V8HI, SPU_BTI_V8HI)) -DEF_BUILTIN (SPU_MULO_1, CODE_FOR_vec_widen_umult_odd_v8hi, "spu_mulo_1", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV8HI, SPU_BTI_UV8HI)) -DEF_BUILTIN (SPU_MULO_2, CODE_FOR_vec_widen_smult_odd_v8hi, "spu_mulo_2", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V8HI, SPU_BTI_INTHI)) -DEF_BUILTIN (SPU_MULO_3, CODE_FOR_vec_widen_umult_odd_v8hi, "spu_mulo_3", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV8HI, SPU_BTI_UINTHI)) -DEF_BUILTIN (SPU_NMSUB, CODE_FOR_nothing, "spu_nmsub", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_NMSUB_0, CODE_FOR_fnmav4sf4, "spu_nmsub_0", B_INTERNAL, _A4(SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_V4SF)) -DEF_BUILTIN (SPU_NMSUB_1, CODE_FOR_nfmsv2df4, "spu_nmsub_1", B_INTERNAL, _A4(SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_V2DF)) -DEF_BUILTIN (SPU_SUB, CODE_FOR_nothing, "spu_sub", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_SUB_0, CODE_FOR_subv8hi3, "spu_sub_0", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UV8HI)) -DEF_BUILTIN (SPU_SUB_1, CODE_FOR_subv8hi3, "spu_sub_1", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_V8HI)) -DEF_BUILTIN (SPU_SUB_2, CODE_FOR_subv4si3, "spu_sub_2", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_SUB_3, CODE_FOR_subv4si3, "spu_sub_3", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_SUB_4, CODE_FOR_subv4sf3, "spu_sub_4", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_V4SF)) -DEF_BUILTIN (SPU_SUB_5, CODE_FOR_subv2df3, "spu_sub_5", B_INTERNAL, _A3(SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_V2DF)) -DEF_BUILTIN (SPU_SUB_6, CODE_FOR_subv8hi3, "spu_sub_6", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UINTHI, SPU_BTI_UV8HI)) -DEF_BUILTIN (SPU_SUB_7, CODE_FOR_subv8hi3, "spu_sub_7", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_INTHI, SPU_BTI_V8HI)) -DEF_BUILTIN (SPU_SUB_8, CODE_FOR_subv4si3, "spu_sub_8", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UINTSI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_SUB_9, CODE_FOR_subv4si3, "spu_sub_9", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_INTSI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_SUBX, CODE_FOR_nothing, "spu_subx", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_SUBX_0, CODE_FOR_sfx_v4si, "spu_subx_0", B_INTERNAL, _A4(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_SUBX_1, CODE_FOR_sfx_v4si, "spu_subx_1", B_INTERNAL, _A4(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_GENB, CODE_FOR_nothing, "spu_genb", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_GENB_0, CODE_FOR_bg_v4si, "spu_genb_0", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_GENB_1, CODE_FOR_bg_v4si, "spu_genb_1", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_GENBX, CODE_FOR_nothing, "spu_genbx", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_GENBX_0, CODE_FOR_bgx_v4si, "spu_genbx_0", B_INTERNAL, _A4(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_GENBX_1, CODE_FOR_bgx_v4si, "spu_genbx_1", B_INTERNAL, _A4(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_CMPEQ, CODE_FOR_nothing, "spu_cmpeq", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_CMPEQ_0, CODE_FOR_ceq_v16qi, "spu_cmpeq_0", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI)) -DEF_BUILTIN (SPU_CMPEQ_1, CODE_FOR_ceq_v16qi, "spu_cmpeq_1", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_V16QI, SPU_BTI_V16QI)) -DEF_BUILTIN (SPU_CMPEQ_2, CODE_FOR_ceq_v8hi, "spu_cmpeq_2", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UV8HI)) -DEF_BUILTIN (SPU_CMPEQ_3, CODE_FOR_ceq_v8hi, "spu_cmpeq_3", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_V8HI, SPU_BTI_V8HI)) -DEF_BUILTIN (SPU_CMPEQ_4, CODE_FOR_ceq_v4si, "spu_cmpeq_4", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_CMPEQ_5, CODE_FOR_ceq_v4si, "spu_cmpeq_5", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_V4SI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_CMPEQ_6, CODE_FOR_ceq_v4sf, "spu_cmpeq_6", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_V4SF, SPU_BTI_V4SF)) -DEF_BUILTIN (SPU_CMPEQ_7, CODE_FOR_ceq_v16qi, "spu_cmpeq_7", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UINTQI)) -DEF_BUILTIN (SPU_CMPEQ_8, CODE_FOR_ceq_v16qi, "spu_cmpeq_8", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_V16QI, SPU_BTI_INTQI)) -DEF_BUILTIN (SPU_CMPEQ_9, CODE_FOR_ceq_v8hi, "spu_cmpeq_9", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UINTHI)) -DEF_BUILTIN (SPU_CMPEQ_10, CODE_FOR_ceq_v8hi, "spu_cmpeq_10", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_V8HI, SPU_BTI_INTHI)) -DEF_BUILTIN (SPU_CMPEQ_11, CODE_FOR_ceq_v4si, "spu_cmpeq_11", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_CMPEQ_12, CODE_FOR_ceq_v4si, "spu_cmpeq_12", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_V4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_CMPEQ_13, CODE_FOR_ceq_v2df, "spu_cmpeq_13", B_INTERNAL, _A3(SPU_BTI_UV2DI, SPU_BTI_V2DF, SPU_BTI_V2DF)) -DEF_BUILTIN (SPU_CMPABSEQ, CODE_FOR_nothing, "spu_cmpabseq", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_CMPABSEQ_0, CODE_FOR_cmeq_v4sf, "spu_cmpabseq_0", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_V4SF, SPU_BTI_V4SF)) -DEF_BUILTIN (SPU_CMPABSEQ_1, CODE_FOR_cmeq_v2df, "spu_cmpabseq_1", B_INTERNAL, _A3(SPU_BTI_UV2DI, SPU_BTI_V2DF, SPU_BTI_V2DF)) -DEF_BUILTIN (SPU_CMPGT, CODE_FOR_nothing, "spu_cmpgt", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_CMPGT_0, CODE_FOR_clgt_v16qi, "spu_cmpgt_0", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI)) -DEF_BUILTIN (SPU_CMPGT_1, CODE_FOR_cgt_v16qi, "spu_cmpgt_1", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_V16QI, SPU_BTI_V16QI)) -DEF_BUILTIN (SPU_CMPGT_2, CODE_FOR_clgt_v8hi, "spu_cmpgt_2", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UV8HI)) -DEF_BUILTIN (SPU_CMPGT_3, CODE_FOR_cgt_v8hi, "spu_cmpgt_3", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_V8HI, SPU_BTI_V8HI)) -DEF_BUILTIN (SPU_CMPGT_4, CODE_FOR_clgt_v4si, "spu_cmpgt_4", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_CMPGT_5, CODE_FOR_cgt_v4si, "spu_cmpgt_5", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_V4SI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_CMPGT_6, CODE_FOR_cgt_v4sf, "spu_cmpgt_6", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_V4SF, SPU_BTI_V4SF)) -DEF_BUILTIN (SPU_CMPGT_7, CODE_FOR_clgt_v16qi, "spu_cmpgt_7", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UINTQI)) -DEF_BUILTIN (SPU_CMPGT_8, CODE_FOR_cgt_v16qi, "spu_cmpgt_8", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_V16QI, SPU_BTI_INTQI)) -DEF_BUILTIN (SPU_CMPGT_9, CODE_FOR_clgt_v8hi, "spu_cmpgt_9", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UINTHI)) -DEF_BUILTIN (SPU_CMPGT_10, CODE_FOR_cgt_v8hi, "spu_cmpgt_10", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_V8HI, SPU_BTI_INTHI)) -DEF_BUILTIN (SPU_CMPGT_11, CODE_FOR_cgt_v4si, "spu_cmpgt_11", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_V4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_CMPGT_12, CODE_FOR_clgt_v4si, "spu_cmpgt_12", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_CMPGT_13, CODE_FOR_cgt_v2df, "spu_cmpgt_13", B_INTERNAL, _A3(SPU_BTI_UV2DI, SPU_BTI_V2DF, SPU_BTI_V2DF)) -DEF_BUILTIN (SPU_CMPABSGT, CODE_FOR_nothing, "spu_cmpabsgt", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_CMPABSGT_0, CODE_FOR_cmgt_v4sf, "spu_cmpabsgt_0", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_V4SF, SPU_BTI_V4SF)) -DEF_BUILTIN (SPU_CMPABSGT_1, CODE_FOR_cmgt_v2df, "spu_cmpabsgt_1", B_INTERNAL, _A3(SPU_BTI_UV2DI, SPU_BTI_V2DF, SPU_BTI_V2DF)) -DEF_BUILTIN (SPU_HCMPEQ, CODE_FOR_nothing, "spu_hcmpeq", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_HCMPEQ_0, CODE_FOR_spu_heq, "spu_hcmpeq_0", B_INTERNAL, _A3(SPU_BTI_VOID, SPU_BTI_INTSI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_HCMPEQ_1, CODE_FOR_spu_heq, "spu_hcmpeq_1", B_INTERNAL, _A3(SPU_BTI_VOID, SPU_BTI_UINTSI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_HCMPGT, CODE_FOR_nothing, "spu_hcmpgt", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_HCMPGT_0, CODE_FOR_spu_hgt, "spu_hcmpgt_0", B_INTERNAL, _A3(SPU_BTI_VOID, SPU_BTI_INTSI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_HCMPGT_1, CODE_FOR_spu_hlgt, "spu_hcmpgt_1", B_INTERNAL, _A3(SPU_BTI_VOID, SPU_BTI_UINTSI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_CNTB, CODE_FOR_nothing, "spu_cntb", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_CNTB_0, CODE_FOR_cntb_v16qi, "spu_cntb_0", B_INTERNAL, _A2(SPU_BTI_UV16QI, SPU_BTI_V16QI)) -DEF_BUILTIN (SPU_CNTB_1, CODE_FOR_cntb_v16qi, "spu_cntb_1", B_INTERNAL, _A2(SPU_BTI_UV16QI, SPU_BTI_UV16QI)) -DEF_BUILTIN (SPU_CNTLZ, CODE_FOR_nothing, "spu_cntlz", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_CNTLZ_0, CODE_FOR_clzv4si2, "spu_cntlz_0", B_INTERNAL, _A2(SPU_BTI_UV4SI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_CNTLZ_1, CODE_FOR_clzv4si2, "spu_cntlz_1", B_INTERNAL, _A2(SPU_BTI_UV4SI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_CNTLZ_2, CODE_FOR_clzv4si2, "spu_cntlz_2", B_INTERNAL, _A2(SPU_BTI_UV4SI, SPU_BTI_V4SF)) -DEF_BUILTIN (SPU_GATHER, CODE_FOR_nothing, "spu_gather", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_GATHER_0, CODE_FOR_spu_gb, "spu_gather_0", B_INTERNAL, _A2(SPU_BTI_UV4SI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_GATHER_1, CODE_FOR_spu_gb, "spu_gather_1", B_INTERNAL, _A2(SPU_BTI_UV4SI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_GATHER_2, CODE_FOR_spu_gbh, "spu_gather_2", B_INTERNAL, _A2(SPU_BTI_UV4SI, SPU_BTI_V8HI)) -DEF_BUILTIN (SPU_GATHER_3, CODE_FOR_spu_gbh, "spu_gather_3", B_INTERNAL, _A2(SPU_BTI_UV4SI, SPU_BTI_UV8HI)) -DEF_BUILTIN (SPU_GATHER_4, CODE_FOR_spu_gbb, "spu_gather_4", B_INTERNAL, _A2(SPU_BTI_UV4SI, SPU_BTI_V16QI)) -DEF_BUILTIN (SPU_GATHER_5, CODE_FOR_spu_gbb, "spu_gather_5", B_INTERNAL, _A2(SPU_BTI_UV4SI, SPU_BTI_UV16QI)) -DEF_BUILTIN (SPU_GATHER_6, CODE_FOR_spu_gb, "spu_gather_6", B_INTERNAL, _A2(SPU_BTI_UV4SI, SPU_BTI_V4SF)) -DEF_BUILTIN (SPU_MASKB, CODE_FOR_nothing, "spu_maskb", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_MASKB_0, CODE_FOR_spu_fsmb, "spu_maskb_0", B_INTERNAL, _A2(SPU_BTI_UV16QI, SPU_BTI_UINTHI)) -DEF_BUILTIN (SPU_MASKB_1, CODE_FOR_spu_fsmb, "spu_maskb_1", B_INTERNAL, _A2(SPU_BTI_UV16QI, SPU_BTI_INTHI)) -DEF_BUILTIN (SPU_MASKB_2, CODE_FOR_spu_fsmb, "spu_maskb_2", B_INTERNAL, _A2(SPU_BTI_UV16QI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_MASKB_3, CODE_FOR_spu_fsmb, "spu_maskb_3", B_INTERNAL, _A2(SPU_BTI_UV16QI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_MASKH, CODE_FOR_nothing, "spu_maskh", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_MASKH_0, CODE_FOR_spu_fsmh, "spu_maskh_0", B_INTERNAL, _A2(SPU_BTI_UV8HI, SPU_BTI_UINTQI)) -DEF_BUILTIN (SPU_MASKH_1, CODE_FOR_spu_fsmh, "spu_maskh_1", B_INTERNAL, _A2(SPU_BTI_UV8HI, SPU_BTI_INTQI)) -DEF_BUILTIN (SPU_MASKH_2, CODE_FOR_spu_fsmh, "spu_maskh_2", B_INTERNAL, _A2(SPU_BTI_UV8HI, SPU_BTI_UINTHI)) -DEF_BUILTIN (SPU_MASKH_3, CODE_FOR_spu_fsmh, "spu_maskh_3", B_INTERNAL, _A2(SPU_BTI_UV8HI, SPU_BTI_INTHI)) -DEF_BUILTIN (SPU_MASKH_4, CODE_FOR_spu_fsmh, "spu_maskh_4", B_INTERNAL, _A2(SPU_BTI_UV8HI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_MASKH_5, CODE_FOR_spu_fsmh, "spu_maskh_5", B_INTERNAL, _A2(SPU_BTI_UV8HI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_MASKW, CODE_FOR_nothing, "spu_maskw", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_MASKW_0, CODE_FOR_spu_fsm, "spu_maskw_0", B_INTERNAL, _A2(SPU_BTI_UV4SI, SPU_BTI_UINTQI)) -DEF_BUILTIN (SPU_MASKW_1, CODE_FOR_spu_fsm, "spu_maskw_1", B_INTERNAL, _A2(SPU_BTI_UV4SI, SPU_BTI_INTQI)) -DEF_BUILTIN (SPU_MASKW_2, CODE_FOR_spu_fsm, "spu_maskw_2", B_INTERNAL, _A2(SPU_BTI_UV4SI, SPU_BTI_UINTHI)) -DEF_BUILTIN (SPU_MASKW_3, CODE_FOR_spu_fsm, "spu_maskw_3", B_INTERNAL, _A2(SPU_BTI_UV4SI, SPU_BTI_INTHI)) -DEF_BUILTIN (SPU_MASKW_4, CODE_FOR_spu_fsm, "spu_maskw_4", B_INTERNAL, _A2(SPU_BTI_UV4SI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_MASKW_5, CODE_FOR_spu_fsm, "spu_maskw_5", B_INTERNAL, _A2(SPU_BTI_UV4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_SEL, CODE_FOR_nothing, "spu_sel", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_SEL_0, CODE_FOR_selb, "spu_sel_0", B_INTERNAL, _A4(SPU_BTI_V2DI, SPU_BTI_V2DI, SPU_BTI_V2DI, SPU_BTI_UV2DI)) -DEF_BUILTIN (SPU_SEL_1, CODE_FOR_selb, "spu_sel_1", B_INTERNAL, _A4(SPU_BTI_UV2DI, SPU_BTI_UV2DI, SPU_BTI_UV2DI, SPU_BTI_UV2DI)) -DEF_BUILTIN (SPU_SEL_2, CODE_FOR_selb, "spu_sel_2", B_INTERNAL, _A4(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_SEL_3, CODE_FOR_selb, "spu_sel_3", B_INTERNAL, _A4(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_SEL_4, CODE_FOR_selb, "spu_sel_4", B_INTERNAL, _A4(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_UV8HI)) -DEF_BUILTIN (SPU_SEL_5, CODE_FOR_selb, "spu_sel_5", B_INTERNAL, _A4(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UV8HI)) -DEF_BUILTIN (SPU_SEL_6, CODE_FOR_selb, "spu_sel_6", B_INTERNAL, _A4(SPU_BTI_V16QI, SPU_BTI_V16QI, SPU_BTI_V16QI, SPU_BTI_UV16QI)) -DEF_BUILTIN (SPU_SEL_7, CODE_FOR_selb, "spu_sel_7", B_INTERNAL, _A4(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI)) -DEF_BUILTIN (SPU_SEL_8, CODE_FOR_selb, "spu_sel_8", B_INTERNAL, _A4(SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_SEL_9, CODE_FOR_selb, "spu_sel_9", B_INTERNAL, _A4(SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_UV2DI)) -DEF_BUILTIN (SPU_SHUFFLE, CODE_FOR_nothing, "spu_shuffle", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_SHUFFLE_0, CODE_FOR_shufb, "spu_shuffle_0", B_INTERNAL, _A4(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI)) -DEF_BUILTIN (SPU_SHUFFLE_1, CODE_FOR_shufb, "spu_shuffle_1", B_INTERNAL, _A4(SPU_BTI_V16QI, SPU_BTI_V16QI, SPU_BTI_V16QI, SPU_BTI_UV16QI)) -DEF_BUILTIN (SPU_SHUFFLE_2, CODE_FOR_shufb, "spu_shuffle_2", B_INTERNAL, _A4(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UV16QI)) -DEF_BUILTIN (SPU_SHUFFLE_3, CODE_FOR_shufb, "spu_shuffle_3", B_INTERNAL, _A4(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_UV16QI)) -DEF_BUILTIN (SPU_SHUFFLE_4, CODE_FOR_shufb, "spu_shuffle_4", B_INTERNAL, _A4(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UV16QI)) -DEF_BUILTIN (SPU_SHUFFLE_5, CODE_FOR_shufb, "spu_shuffle_5", B_INTERNAL, _A4(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_UV16QI)) -DEF_BUILTIN (SPU_SHUFFLE_6, CODE_FOR_shufb, "spu_shuffle_6", B_INTERNAL, _A4(SPU_BTI_UV2DI, SPU_BTI_UV2DI, SPU_BTI_UV2DI, SPU_BTI_UV16QI)) -DEF_BUILTIN (SPU_SHUFFLE_7, CODE_FOR_shufb, "spu_shuffle_7", B_INTERNAL, _A4(SPU_BTI_V2DI, SPU_BTI_V2DI, SPU_BTI_V2DI, SPU_BTI_UV16QI)) -DEF_BUILTIN (SPU_SHUFFLE_8, CODE_FOR_shufb, "spu_shuffle_8", B_INTERNAL, _A4(SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_UV16QI)) -DEF_BUILTIN (SPU_SHUFFLE_9, CODE_FOR_shufb, "spu_shuffle_9", B_INTERNAL, _A4(SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_UV16QI)) -DEF_BUILTIN (SPU_AND, CODE_FOR_nothing, "spu_and", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_AND_0, CODE_FOR_andv16qi3, "spu_and_0", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI)) -DEF_BUILTIN (SPU_AND_1, CODE_FOR_andv16qi3, "spu_and_1", B_INTERNAL, _A3(SPU_BTI_V16QI, SPU_BTI_V16QI, SPU_BTI_V16QI)) -DEF_BUILTIN (SPU_AND_2, CODE_FOR_andv8hi3, "spu_and_2", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UV8HI)) -DEF_BUILTIN (SPU_AND_3, CODE_FOR_andv8hi3, "spu_and_3", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_V8HI)) -DEF_BUILTIN (SPU_AND_4, CODE_FOR_andv4si3, "spu_and_4", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_AND_5, CODE_FOR_andv4si3, "spu_and_5", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_AND_6, CODE_FOR_andv2di3, "spu_and_6", B_INTERNAL, _A3(SPU_BTI_UV2DI, SPU_BTI_UV2DI, SPU_BTI_UV2DI)) -DEF_BUILTIN (SPU_AND_7, CODE_FOR_andv2di3, "spu_and_7", B_INTERNAL, _A3(SPU_BTI_V2DI, SPU_BTI_V2DI, SPU_BTI_V2DI)) -DEF_BUILTIN (SPU_AND_8, CODE_FOR_andv4si3, "spu_and_8", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_V4SF)) -DEF_BUILTIN (SPU_AND_9, CODE_FOR_andv2di3, "spu_and_9", B_INTERNAL, _A3(SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_V2DF)) -DEF_BUILTIN (SPU_AND_10, CODE_FOR_andv16qi3, "spu_and_10", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UINTQI)) -DEF_BUILTIN (SPU_AND_11, CODE_FOR_andv16qi3, "spu_and_11", B_INTERNAL, _A3(SPU_BTI_V16QI, SPU_BTI_V16QI, SPU_BTI_INTQI)) -DEF_BUILTIN (SPU_AND_12, CODE_FOR_andv8hi3, "spu_and_12", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UINTHI)) -DEF_BUILTIN (SPU_AND_13, CODE_FOR_andv8hi3, "spu_and_13", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_INTHI)) -DEF_BUILTIN (SPU_AND_14, CODE_FOR_andv4si3, "spu_and_14", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_AND_15, CODE_FOR_andv4si3, "spu_and_15", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_ANDC, CODE_FOR_nothing, "spu_andc", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_ANDC_0, CODE_FOR_andc_v2di, "spu_andc_0", B_INTERNAL, _A3(SPU_BTI_V2DI, SPU_BTI_V2DI, SPU_BTI_V2DI)) -DEF_BUILTIN (SPU_ANDC_1, CODE_FOR_andc_v2di, "spu_andc_1", B_INTERNAL, _A3(SPU_BTI_UV2DI, SPU_BTI_UV2DI, SPU_BTI_UV2DI)) -DEF_BUILTIN (SPU_ANDC_2, CODE_FOR_andc_v4si, "spu_andc_2", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_ANDC_3, CODE_FOR_andc_v4si, "spu_andc_3", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_ANDC_4, CODE_FOR_andc_v8hi, "spu_andc_4", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_V8HI)) -DEF_BUILTIN (SPU_ANDC_5, CODE_FOR_andc_v8hi, "spu_andc_5", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UV8HI)) -DEF_BUILTIN (SPU_ANDC_6, CODE_FOR_andc_v16qi, "spu_andc_6", B_INTERNAL, _A3(SPU_BTI_V16QI, SPU_BTI_V16QI, SPU_BTI_V16QI)) -DEF_BUILTIN (SPU_ANDC_7, CODE_FOR_andc_v16qi, "spu_andc_7", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI)) -DEF_BUILTIN (SPU_ANDC_8, CODE_FOR_andc_v4si, "spu_andc_8", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_V4SF)) -DEF_BUILTIN (SPU_ANDC_9, CODE_FOR_andc_v2di, "spu_andc_9", B_INTERNAL, _A3(SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_V2DF)) -DEF_BUILTIN (SPU_EQV, CODE_FOR_nothing, "spu_eqv", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_EQV_0, CODE_FOR_eqv_v2di, "spu_eqv_0", B_INTERNAL, _A3(SPU_BTI_V2DI, SPU_BTI_V2DI, SPU_BTI_V2DI)) -DEF_BUILTIN (SPU_EQV_1, CODE_FOR_eqv_v2di, "spu_eqv_1", B_INTERNAL, _A3(SPU_BTI_UV2DI, SPU_BTI_UV2DI, SPU_BTI_UV2DI)) -DEF_BUILTIN (SPU_EQV_2, CODE_FOR_eqv_v4si, "spu_eqv_2", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_EQV_3, CODE_FOR_eqv_v4si, "spu_eqv_3", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_EQV_4, CODE_FOR_eqv_v8hi, "spu_eqv_4", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_V8HI)) -DEF_BUILTIN (SPU_EQV_5, CODE_FOR_eqv_v8hi, "spu_eqv_5", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UV8HI)) -DEF_BUILTIN (SPU_EQV_6, CODE_FOR_eqv_v16qi, "spu_eqv_6", B_INTERNAL, _A3(SPU_BTI_V16QI, SPU_BTI_V16QI, SPU_BTI_V16QI)) -DEF_BUILTIN (SPU_EQV_7, CODE_FOR_eqv_v16qi, "spu_eqv_7", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI)) -DEF_BUILTIN (SPU_EQV_8, CODE_FOR_eqv_v4si, "spu_eqv_8", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_V4SF)) -DEF_BUILTIN (SPU_EQV_9, CODE_FOR_eqv_v2di, "spu_eqv_9", B_INTERNAL, _A3(SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_V2DF)) -DEF_BUILTIN (SPU_NAND, CODE_FOR_nothing, "spu_nand", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_NAND_0, CODE_FOR_nand_v2di, "spu_nand_0", B_INTERNAL, _A3(SPU_BTI_V2DI, SPU_BTI_V2DI, SPU_BTI_V2DI)) -DEF_BUILTIN (SPU_NAND_1, CODE_FOR_nand_v2di, "spu_nand_1", B_INTERNAL, _A3(SPU_BTI_UV2DI, SPU_BTI_UV2DI, SPU_BTI_UV2DI)) -DEF_BUILTIN (SPU_NAND_2, CODE_FOR_nand_v4si, "spu_nand_2", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_NAND_3, CODE_FOR_nand_v4si, "spu_nand_3", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_NAND_4, CODE_FOR_nand_v8hi, "spu_nand_4", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_V8HI)) -DEF_BUILTIN (SPU_NAND_5, CODE_FOR_nand_v8hi, "spu_nand_5", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UV8HI)) -DEF_BUILTIN (SPU_NAND_6, CODE_FOR_nand_v16qi, "spu_nand_6", B_INTERNAL, _A3(SPU_BTI_V16QI, SPU_BTI_V16QI, SPU_BTI_V16QI)) -DEF_BUILTIN (SPU_NAND_7, CODE_FOR_nand_v16qi, "spu_nand_7", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI)) -DEF_BUILTIN (SPU_NAND_8, CODE_FOR_nand_v4si, "spu_nand_8", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_V4SF)) -DEF_BUILTIN (SPU_NAND_9, CODE_FOR_nand_v2di, "spu_nand_9", B_INTERNAL, _A3(SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_V2DF)) -DEF_BUILTIN (SPU_NOR, CODE_FOR_nothing, "spu_nor", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_NOR_0, CODE_FOR_nor_v2di, "spu_nor_0", B_INTERNAL, _A3(SPU_BTI_V2DI, SPU_BTI_V2DI, SPU_BTI_V2DI)) -DEF_BUILTIN (SPU_NOR_1, CODE_FOR_nor_v2di, "spu_nor_1", B_INTERNAL, _A3(SPU_BTI_UV2DI, SPU_BTI_UV2DI, SPU_BTI_UV2DI)) -DEF_BUILTIN (SPU_NOR_2, CODE_FOR_nor_v4si, "spu_nor_2", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_NOR_3, CODE_FOR_nor_v4si, "spu_nor_3", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_NOR_4, CODE_FOR_nor_v8hi, "spu_nor_4", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_V8HI)) -DEF_BUILTIN (SPU_NOR_5, CODE_FOR_nor_v8hi, "spu_nor_5", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UV8HI)) -DEF_BUILTIN (SPU_NOR_6, CODE_FOR_nor_v16qi, "spu_nor_6", B_INTERNAL, _A3(SPU_BTI_V16QI, SPU_BTI_V16QI, SPU_BTI_V16QI)) -DEF_BUILTIN (SPU_NOR_7, CODE_FOR_nor_v16qi, "spu_nor_7", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI)) -DEF_BUILTIN (SPU_NOR_8, CODE_FOR_nor_v4si, "spu_nor_8", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_V4SF)) -DEF_BUILTIN (SPU_NOR_9, CODE_FOR_nor_v2di, "spu_nor_9", B_INTERNAL, _A3(SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_V2DF)) -DEF_BUILTIN (SPU_OR, CODE_FOR_nothing, "spu_or", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_OR_0, CODE_FOR_iorv16qi3, "spu_or_0", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI)) -DEF_BUILTIN (SPU_OR_1, CODE_FOR_iorv16qi3, "spu_or_1", B_INTERNAL, _A3(SPU_BTI_V16QI, SPU_BTI_V16QI, SPU_BTI_V16QI)) -DEF_BUILTIN (SPU_OR_2, CODE_FOR_iorv8hi3, "spu_or_2", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UV8HI)) -DEF_BUILTIN (SPU_OR_3, CODE_FOR_iorv8hi3, "spu_or_3", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_V8HI)) -DEF_BUILTIN (SPU_OR_4, CODE_FOR_iorv4si3, "spu_or_4", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_OR_5, CODE_FOR_iorv4si3, "spu_or_5", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_OR_6, CODE_FOR_iorv2di3, "spu_or_6", B_INTERNAL, _A3(SPU_BTI_UV2DI, SPU_BTI_UV2DI, SPU_BTI_UV2DI)) -DEF_BUILTIN (SPU_OR_7, CODE_FOR_iorv2di3, "spu_or_7", B_INTERNAL, _A3(SPU_BTI_V2DI, SPU_BTI_V2DI, SPU_BTI_V2DI)) -DEF_BUILTIN (SPU_OR_8, CODE_FOR_iorv4si3, "spu_or_8", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_V4SF)) -DEF_BUILTIN (SPU_OR_9, CODE_FOR_iorv2di3, "spu_or_9", B_INTERNAL, _A3(SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_V2DF)) -DEF_BUILTIN (SPU_OR_10, CODE_FOR_iorv16qi3, "spu_or_10", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UINTQI)) -DEF_BUILTIN (SPU_OR_11, CODE_FOR_iorv16qi3, "spu_or_11", B_INTERNAL, _A3(SPU_BTI_V16QI, SPU_BTI_V16QI, SPU_BTI_INTQI)) -DEF_BUILTIN (SPU_OR_12, CODE_FOR_iorv8hi3, "spu_or_12", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UINTHI)) -DEF_BUILTIN (SPU_OR_13, CODE_FOR_iorv8hi3, "spu_or_13", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_INTHI)) -DEF_BUILTIN (SPU_OR_14, CODE_FOR_iorv4si3, "spu_or_14", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_OR_15, CODE_FOR_iorv4si3, "spu_or_15", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_ORC, CODE_FOR_nothing, "spu_orc", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_ORC_0, CODE_FOR_orc_v2di, "spu_orc_0", B_INTERNAL, _A3(SPU_BTI_V2DI, SPU_BTI_V2DI, SPU_BTI_V2DI)) -DEF_BUILTIN (SPU_ORC_1, CODE_FOR_orc_v2di, "spu_orc_1", B_INTERNAL, _A3(SPU_BTI_UV2DI, SPU_BTI_UV2DI, SPU_BTI_UV2DI)) -DEF_BUILTIN (SPU_ORC_2, CODE_FOR_orc_v4si, "spu_orc_2", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_ORC_3, CODE_FOR_orc_v4si, "spu_orc_3", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_ORC_4, CODE_FOR_orc_v8hi, "spu_orc_4", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_V8HI)) -DEF_BUILTIN (SPU_ORC_5, CODE_FOR_orc_v8hi, "spu_orc_5", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UV8HI)) -DEF_BUILTIN (SPU_ORC_6, CODE_FOR_orc_v16qi, "spu_orc_6", B_INTERNAL, _A3(SPU_BTI_V16QI, SPU_BTI_V16QI, SPU_BTI_V16QI)) -DEF_BUILTIN (SPU_ORC_7, CODE_FOR_orc_v16qi, "spu_orc_7", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI)) -DEF_BUILTIN (SPU_ORC_8, CODE_FOR_orc_v4si, "spu_orc_8", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_V4SF)) -DEF_BUILTIN (SPU_ORC_9, CODE_FOR_orc_v2di, "spu_orc_9", B_INTERNAL, _A3(SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_V2DF)) -DEF_BUILTIN (SPU_ORX, CODE_FOR_nothing, "spu_orx", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_ORX_0, CODE_FOR_spu_orx, "spu_orx_0", B_INTERNAL, _A2(SPU_BTI_V4SI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_ORX_1, CODE_FOR_spu_orx, "spu_orx_1", B_INTERNAL, _A2(SPU_BTI_UV4SI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_XOR, CODE_FOR_nothing, "spu_xor", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_XOR_0, CODE_FOR_xorv16qi3, "spu_xor_0", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI)) -DEF_BUILTIN (SPU_XOR_1, CODE_FOR_xorv16qi3, "spu_xor_1", B_INTERNAL, _A3(SPU_BTI_V16QI, SPU_BTI_V16QI, SPU_BTI_V16QI)) -DEF_BUILTIN (SPU_XOR_2, CODE_FOR_xorv8hi3, "spu_xor_2", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UV8HI)) -DEF_BUILTIN (SPU_XOR_3, CODE_FOR_xorv8hi3, "spu_xor_3", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_V8HI)) -DEF_BUILTIN (SPU_XOR_4, CODE_FOR_xorv4si3, "spu_xor_4", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_XOR_5, CODE_FOR_xorv4si3, "spu_xor_5", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_XOR_6, CODE_FOR_xorv2di3, "spu_xor_6", B_INTERNAL, _A3(SPU_BTI_UV2DI, SPU_BTI_UV2DI, SPU_BTI_UV2DI)) -DEF_BUILTIN (SPU_XOR_7, CODE_FOR_xorv2di3, "spu_xor_7", B_INTERNAL, _A3(SPU_BTI_V2DI, SPU_BTI_V2DI, SPU_BTI_V2DI)) -DEF_BUILTIN (SPU_XOR_8, CODE_FOR_xorv4si3, "spu_xor_8", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_V4SF)) -DEF_BUILTIN (SPU_XOR_9, CODE_FOR_xorv2di3, "spu_xor_9", B_INTERNAL, _A3(SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_V2DF)) -DEF_BUILTIN (SPU_XOR_10, CODE_FOR_xorv16qi3, "spu_xor_10", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UINTQI)) -DEF_BUILTIN (SPU_XOR_11, CODE_FOR_xorv16qi3, "spu_xor_11", B_INTERNAL, _A3(SPU_BTI_V16QI, SPU_BTI_V16QI, SPU_BTI_INTQI)) -DEF_BUILTIN (SPU_XOR_12, CODE_FOR_xorv8hi3, "spu_xor_12", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UINTHI)) -DEF_BUILTIN (SPU_XOR_13, CODE_FOR_xorv8hi3, "spu_xor_13", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_INTHI)) -DEF_BUILTIN (SPU_XOR_14, CODE_FOR_xorv4si3, "spu_xor_14", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_XOR_15, CODE_FOR_xorv4si3, "spu_xor_15", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RL, CODE_FOR_nothing, "spu_rl", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_RL_0, CODE_FOR_vrotlv8hi3, "spu_rl_0", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_V8HI)) -DEF_BUILTIN (SPU_RL_1, CODE_FOR_vrotlv8hi3, "spu_rl_1", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_V8HI)) -DEF_BUILTIN (SPU_RL_2, CODE_FOR_vrotlv4si3, "spu_rl_2", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_RL_3, CODE_FOR_vrotlv4si3, "spu_rl_3", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_RL_4, CODE_FOR_vrotlv8hi3, "spu_rl_4", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_INTHI)) -DEF_BUILTIN (SPU_RL_5, CODE_FOR_vrotlv8hi3, "spu_rl_5", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_INTHI)) -DEF_BUILTIN (SPU_RL_6, CODE_FOR_vrotlv4si3, "spu_rl_6", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RL_7, CODE_FOR_vrotlv4si3, "spu_rl_7", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQW, CODE_FOR_nothing, "spu_rlqw", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_RLQW_0, CODE_FOR_rotqbi_ti, "spu_rlqw_0", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQW_1, CODE_FOR_rotqbi_ti, "spu_rlqw_1", B_INTERNAL, _A3(SPU_BTI_V16QI, SPU_BTI_V16QI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQW_2, CODE_FOR_rotqbi_ti, "spu_rlqw_2", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQW_3, CODE_FOR_rotqbi_ti, "spu_rlqw_3", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQW_4, CODE_FOR_rotqbi_ti, "spu_rlqw_4", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQW_5, CODE_FOR_rotqbi_ti, "spu_rlqw_5", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQW_6, CODE_FOR_rotqbi_ti, "spu_rlqw_6", B_INTERNAL, _A3(SPU_BTI_UV2DI, SPU_BTI_UV2DI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQW_7, CODE_FOR_rotqbi_ti, "spu_rlqw_7", B_INTERNAL, _A3(SPU_BTI_V2DI, SPU_BTI_V2DI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQW_8, CODE_FOR_rotqbi_ti, "spu_rlqw_8", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQW_9, CODE_FOR_rotqbi_ti, "spu_rlqw_9", B_INTERNAL, _A3(SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQWBYTE, CODE_FOR_nothing, "spu_rlqwbyte", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_RLQWBYTE_0, CODE_FOR_rotqby_ti, "spu_rlqwbyte_0", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQWBYTE_1, CODE_FOR_rotqby_ti, "spu_rlqwbyte_1", B_INTERNAL, _A3(SPU_BTI_V16QI, SPU_BTI_V16QI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQWBYTE_2, CODE_FOR_rotqby_ti, "spu_rlqwbyte_2", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQWBYTE_3, CODE_FOR_rotqby_ti, "spu_rlqwbyte_3", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQWBYTE_4, CODE_FOR_rotqby_ti, "spu_rlqwbyte_4", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQWBYTE_5, CODE_FOR_rotqby_ti, "spu_rlqwbyte_5", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQWBYTE_6, CODE_FOR_rotqby_ti, "spu_rlqwbyte_6", B_INTERNAL, _A3(SPU_BTI_UV2DI, SPU_BTI_UV2DI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQWBYTE_7, CODE_FOR_rotqby_ti, "spu_rlqwbyte_7", B_INTERNAL, _A3(SPU_BTI_V2DI, SPU_BTI_V2DI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQWBYTE_8, CODE_FOR_rotqby_ti, "spu_rlqwbyte_8", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQWBYTE_9, CODE_FOR_rotqby_ti, "spu_rlqwbyte_9", B_INTERNAL, _A3(SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQWBYTEBC, CODE_FOR_nothing, "spu_rlqwbytebc", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_RLQWBYTEBC_0, CODE_FOR_rotqbybi_ti, "spu_rlqwbytebc_0", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQWBYTEBC_1, CODE_FOR_rotqbybi_ti, "spu_rlqwbytebc_1", B_INTERNAL, _A3(SPU_BTI_V16QI, SPU_BTI_V16QI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQWBYTEBC_2, CODE_FOR_rotqbybi_ti, "spu_rlqwbytebc_2", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQWBYTEBC_3, CODE_FOR_rotqbybi_ti, "spu_rlqwbytebc_3", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQWBYTEBC_4, CODE_FOR_rotqbybi_ti, "spu_rlqwbytebc_4", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQWBYTEBC_5, CODE_FOR_rotqbybi_ti, "spu_rlqwbytebc_5", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQWBYTEBC_6, CODE_FOR_rotqbybi_ti, "spu_rlqwbytebc_6", B_INTERNAL, _A3(SPU_BTI_UV2DI, SPU_BTI_UV2DI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQWBYTEBC_7, CODE_FOR_rotqbybi_ti, "spu_rlqwbytebc_7", B_INTERNAL, _A3(SPU_BTI_V2DI, SPU_BTI_V2DI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQWBYTEBC_8, CODE_FOR_rotqbybi_ti, "spu_rlqwbytebc_8", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLQWBYTEBC_9, CODE_FOR_rotqbybi_ti, "spu_rlqwbytebc_9", B_INTERNAL, _A3(SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASK, CODE_FOR_nothing, "spu_rlmask", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_RLMASK_0, CODE_FOR_rotm_v8hi, "spu_rlmask_0", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_V8HI)) -DEF_BUILTIN (SPU_RLMASK_1, CODE_FOR_rotm_v8hi, "spu_rlmask_1", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_V8HI)) -DEF_BUILTIN (SPU_RLMASK_2, CODE_FOR_rotm_v4si, "spu_rlmask_2", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_RLMASK_3, CODE_FOR_rotm_v4si, "spu_rlmask_3", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_RLMASK_4, CODE_FOR_rotm_v8hi, "spu_rlmask_4", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASK_5, CODE_FOR_rotm_v8hi, "spu_rlmask_5", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASK_6, CODE_FOR_rotm_v4si, "spu_rlmask_6", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASK_7, CODE_FOR_rotm_v4si, "spu_rlmask_7", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKA, CODE_FOR_nothing, "spu_rlmaska", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_RLMASKA_0, CODE_FOR_rotma_v8hi, "spu_rlmaska_0", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_V8HI)) -DEF_BUILTIN (SPU_RLMASKA_1, CODE_FOR_rotma_v8hi, "spu_rlmaska_1", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_V8HI)) -DEF_BUILTIN (SPU_RLMASKA_2, CODE_FOR_rotma_v4si, "spu_rlmaska_2", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_RLMASKA_3, CODE_FOR_rotma_v4si, "spu_rlmaska_3", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_V4SI)) -DEF_BUILTIN (SPU_RLMASKA_4, CODE_FOR_rotma_v8hi, "spu_rlmaska_4", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKA_5, CODE_FOR_rotma_v8hi, "spu_rlmaska_5", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKA_6, CODE_FOR_rotma_v4si, "spu_rlmaska_6", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKA_7, CODE_FOR_rotma_v4si, "spu_rlmaska_7", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQW, CODE_FOR_nothing, "spu_rlmaskqw", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_RLMASKQW_0, CODE_FOR_rotqmbi_ti, "spu_rlmaskqw_0", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQW_1, CODE_FOR_rotqmbi_ti, "spu_rlmaskqw_1", B_INTERNAL, _A3(SPU_BTI_V16QI, SPU_BTI_V16QI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQW_2, CODE_FOR_rotqmbi_ti, "spu_rlmaskqw_2", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQW_3, CODE_FOR_rotqmbi_ti, "spu_rlmaskqw_3", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQW_4, CODE_FOR_rotqmbi_ti, "spu_rlmaskqw_4", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQW_5, CODE_FOR_rotqmbi_ti, "spu_rlmaskqw_5", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQW_6, CODE_FOR_rotqmbi_ti, "spu_rlmaskqw_6", B_INTERNAL, _A3(SPU_BTI_UV2DI, SPU_BTI_UV2DI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQW_7, CODE_FOR_rotqmbi_ti, "spu_rlmaskqw_7", B_INTERNAL, _A3(SPU_BTI_V2DI, SPU_BTI_V2DI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQW_8, CODE_FOR_rotqmbi_ti, "spu_rlmaskqw_8", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQW_9, CODE_FOR_rotqmbi_ti, "spu_rlmaskqw_9", B_INTERNAL, _A3(SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQWBYTE, CODE_FOR_nothing, "spu_rlmaskqwbyte", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_RLMASKQWBYTE_0, CODE_FOR_rotqmby_ti, "spu_rlmaskqwbyte_0", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQWBYTE_1, CODE_FOR_rotqmby_ti, "spu_rlmaskqwbyte_1", B_INTERNAL, _A3(SPU_BTI_V16QI, SPU_BTI_V16QI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQWBYTE_2, CODE_FOR_rotqmby_ti, "spu_rlmaskqwbyte_2", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQWBYTE_3, CODE_FOR_rotqmby_ti, "spu_rlmaskqwbyte_3", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQWBYTE_4, CODE_FOR_rotqmby_ti, "spu_rlmaskqwbyte_4", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQWBYTE_5, CODE_FOR_rotqmby_ti, "spu_rlmaskqwbyte_5", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQWBYTE_6, CODE_FOR_rotqmby_ti, "spu_rlmaskqwbyte_6", B_INTERNAL, _A3(SPU_BTI_UV2DI, SPU_BTI_UV2DI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQWBYTE_7, CODE_FOR_rotqmby_ti, "spu_rlmaskqwbyte_7", B_INTERNAL, _A3(SPU_BTI_V2DI, SPU_BTI_V2DI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQWBYTE_8, CODE_FOR_rotqmby_ti, "spu_rlmaskqwbyte_8", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQWBYTE_9, CODE_FOR_rotqmby_ti, "spu_rlmaskqwbyte_9", B_INTERNAL, _A3(SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQWBYTEBC, CODE_FOR_nothing, "spu_rlmaskqwbytebc", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_RLMASKQWBYTEBC_0, CODE_FOR_rotqmbybi_ti, "spu_rlmaskqwbytebc_0", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQWBYTEBC_1, CODE_FOR_rotqmbybi_ti, "spu_rlmaskqwbytebc_1", B_INTERNAL, _A3(SPU_BTI_V16QI, SPU_BTI_V16QI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQWBYTEBC_2, CODE_FOR_rotqmbybi_ti, "spu_rlmaskqwbytebc_2", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQWBYTEBC_3, CODE_FOR_rotqmbybi_ti, "spu_rlmaskqwbytebc_3", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQWBYTEBC_4, CODE_FOR_rotqmbybi_ti, "spu_rlmaskqwbytebc_4", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQWBYTEBC_5, CODE_FOR_rotqmbybi_ti, "spu_rlmaskqwbytebc_5", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQWBYTEBC_6, CODE_FOR_rotqmbybi_ti, "spu_rlmaskqwbytebc_6", B_INTERNAL, _A3(SPU_BTI_UV2DI, SPU_BTI_UV2DI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQWBYTEBC_7, CODE_FOR_rotqmbybi_ti, "spu_rlmaskqwbytebc_7", B_INTERNAL, _A3(SPU_BTI_V2DI, SPU_BTI_V2DI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQWBYTEBC_8, CODE_FOR_rotqmbybi_ti, "spu_rlmaskqwbytebc_8", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_RLMASKQWBYTEBC_9, CODE_FOR_rotqmbybi_ti, "spu_rlmaskqwbytebc_9", B_INTERNAL, _A3(SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_SL, CODE_FOR_nothing, "spu_sl", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_SL_0, CODE_FOR_vashlv8hi3, "spu_sl_0", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UV8HI)) -DEF_BUILTIN (SPU_SL_1, CODE_FOR_vashlv8hi3, "spu_sl_1", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_UV8HI)) -DEF_BUILTIN (SPU_SL_2, CODE_FOR_vashlv4si3, "spu_sl_2", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_SL_3, CODE_FOR_vashlv4si3, "spu_sl_3", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_SL_4, CODE_FOR_vashlv8hi3, "spu_sl_4", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SL_5, CODE_FOR_vashlv8hi3, "spu_sl_5", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SL_6, CODE_FOR_vashlv4si3, "spu_sl_6", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SL_7, CODE_FOR_vashlv4si3, "spu_sl_7", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQW, CODE_FOR_nothing, "spu_slqw", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_SLQW_0, CODE_FOR_shlqbi_ti, "spu_slqw_0", B_INTERNAL, _A3(SPU_BTI_V2DI, SPU_BTI_V2DI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQW_1, CODE_FOR_shlqbi_ti, "spu_slqw_1", B_INTERNAL, _A3(SPU_BTI_UV2DI, SPU_BTI_UV2DI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQW_2, CODE_FOR_shlqbi_ti, "spu_slqw_2", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQW_3, CODE_FOR_shlqbi_ti, "spu_slqw_3", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQW_4, CODE_FOR_shlqbi_ti, "spu_slqw_4", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQW_5, CODE_FOR_shlqbi_ti, "spu_slqw_5", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQW_6, CODE_FOR_shlqbi_ti, "spu_slqw_6", B_INTERNAL, _A3(SPU_BTI_V16QI, SPU_BTI_V16QI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQW_7, CODE_FOR_shlqbi_ti, "spu_slqw_7", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQW_8, CODE_FOR_shlqbi_ti, "spu_slqw_8", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQW_9, CODE_FOR_shlqbi_ti, "spu_slqw_9", B_INTERNAL, _A3(SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQWBYTE, CODE_FOR_nothing, "spu_slqwbyte", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_SLQWBYTE_0, CODE_FOR_shlqby_ti, "spu_slqwbyte_0", B_INTERNAL, _A3(SPU_BTI_V2DI, SPU_BTI_V2DI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQWBYTE_1, CODE_FOR_shlqby_ti, "spu_slqwbyte_1", B_INTERNAL, _A3(SPU_BTI_UV2DI, SPU_BTI_UV2DI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQWBYTE_2, CODE_FOR_shlqby_ti, "spu_slqwbyte_2", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQWBYTE_3, CODE_FOR_shlqby_ti, "spu_slqwbyte_3", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQWBYTE_4, CODE_FOR_shlqby_ti, "spu_slqwbyte_4", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQWBYTE_5, CODE_FOR_shlqby_ti, "spu_slqwbyte_5", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQWBYTE_6, CODE_FOR_shlqby_ti, "spu_slqwbyte_6", B_INTERNAL, _A3(SPU_BTI_V16QI, SPU_BTI_V16QI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQWBYTE_7, CODE_FOR_shlqby_ti, "spu_slqwbyte_7", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQWBYTE_8, CODE_FOR_shlqby_ti, "spu_slqwbyte_8", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQWBYTE_9, CODE_FOR_shlqby_ti, "spu_slqwbyte_9", B_INTERNAL, _A3(SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQWBYTEBC, CODE_FOR_nothing, "spu_slqwbytebc", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_SLQWBYTEBC_0, CODE_FOR_shlqbybi_ti, "spu_slqwbytebc_0", B_INTERNAL, _A3(SPU_BTI_V2DI, SPU_BTI_V2DI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQWBYTEBC_1, CODE_FOR_shlqbybi_ti, "spu_slqwbytebc_1", B_INTERNAL, _A3(SPU_BTI_UV2DI, SPU_BTI_UV2DI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQWBYTEBC_2, CODE_FOR_shlqbybi_ti, "spu_slqwbytebc_2", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQWBYTEBC_3, CODE_FOR_shlqbybi_ti, "spu_slqwbytebc_3", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQWBYTEBC_4, CODE_FOR_shlqbybi_ti, "spu_slqwbytebc_4", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQWBYTEBC_5, CODE_FOR_shlqbybi_ti, "spu_slqwbytebc_5", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQWBYTEBC_6, CODE_FOR_shlqbybi_ti, "spu_slqwbytebc_6", B_INTERNAL, _A3(SPU_BTI_V16QI, SPU_BTI_V16QI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQWBYTEBC_7, CODE_FOR_shlqbybi_ti, "spu_slqwbytebc_7", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQWBYTEBC_8, CODE_FOR_shlqbybi_ti, "spu_slqwbytebc_8", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SLQWBYTEBC_9, CODE_FOR_shlqbybi_ti, "spu_slqwbytebc_9", B_INTERNAL, _A3(SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SR, CODE_FOR_nothing, "spu_sr", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_SR_0, CODE_FOR_vlshrv8hi3, "spu_sr_0", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UV8HI)) -DEF_BUILTIN (SPU_SR_1, CODE_FOR_vlshrv8hi3, "spu_sr_1", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_UV8HI)) -DEF_BUILTIN (SPU_SR_2, CODE_FOR_vlshrv4si3, "spu_sr_2", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_SR_3, CODE_FOR_vlshrv4si3, "spu_sr_3", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_SR_4, CODE_FOR_vlshrv8hi3, "spu_sr_4", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SR_5, CODE_FOR_vlshrv8hi3, "spu_sr_5", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SR_6, CODE_FOR_vlshrv4si3, "spu_sr_6", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SR_7, CODE_FOR_vlshrv4si3, "spu_sr_7", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRA, CODE_FOR_nothing, "spu_sra", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_SRA_0, CODE_FOR_vashrv8hi3, "spu_sra_0", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UV8HI)) -DEF_BUILTIN (SPU_SRA_1, CODE_FOR_vashrv8hi3, "spu_sra_1", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_UV8HI)) -DEF_BUILTIN (SPU_SRA_2, CODE_FOR_vashrv4si3, "spu_sra_2", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_SRA_3, CODE_FOR_vashrv4si3, "spu_sra_3", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_UV4SI)) -DEF_BUILTIN (SPU_SRA_4, CODE_FOR_vashrv8hi3, "spu_sra_4", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRA_5, CODE_FOR_vashrv8hi3, "spu_sra_5", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRA_6, CODE_FOR_vashrv4si3, "spu_sra_6", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRA_7, CODE_FOR_vashrv4si3, "spu_sra_7", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQW, CODE_FOR_nothing, "spu_srqw", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_SRQW_0, CODE_FOR_shrqbi_ti, "spu_srqw_0", B_INTERNAL, _A3(SPU_BTI_V2DI, SPU_BTI_V2DI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQW_1, CODE_FOR_shrqbi_ti, "spu_srqw_1", B_INTERNAL, _A3(SPU_BTI_UV2DI, SPU_BTI_UV2DI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQW_2, CODE_FOR_shrqbi_ti, "spu_srqw_2", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQW_3, CODE_FOR_shrqbi_ti, "spu_srqw_3", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQW_4, CODE_FOR_shrqbi_ti, "spu_srqw_4", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQW_5, CODE_FOR_shrqbi_ti, "spu_srqw_5", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQW_6, CODE_FOR_shrqbi_ti, "spu_srqw_6", B_INTERNAL, _A3(SPU_BTI_V16QI, SPU_BTI_V16QI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQW_7, CODE_FOR_shrqbi_ti, "spu_srqw_7", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQW_8, CODE_FOR_shrqbi_ti, "spu_srqw_8", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQW_9, CODE_FOR_shrqbi_ti, "spu_srqw_9", B_INTERNAL, _A3(SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQWBYTE, CODE_FOR_nothing, "spu_srqwbyte", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_SRQWBYTE_0, CODE_FOR_shrqby_ti, "spu_srqwbyte_0", B_INTERNAL, _A3(SPU_BTI_V2DI, SPU_BTI_V2DI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQWBYTE_1, CODE_FOR_shrqby_ti, "spu_srqwbyte_1", B_INTERNAL, _A3(SPU_BTI_UV2DI, SPU_BTI_UV2DI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQWBYTE_2, CODE_FOR_shrqby_ti, "spu_srqwbyte_2", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQWBYTE_3, CODE_FOR_shrqby_ti, "spu_srqwbyte_3", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQWBYTE_4, CODE_FOR_shrqby_ti, "spu_srqwbyte_4", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQWBYTE_5, CODE_FOR_shrqby_ti, "spu_srqwbyte_5", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQWBYTE_6, CODE_FOR_shrqby_ti, "spu_srqwbyte_6", B_INTERNAL, _A3(SPU_BTI_V16QI, SPU_BTI_V16QI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQWBYTE_7, CODE_FOR_shrqby_ti, "spu_srqwbyte_7", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQWBYTE_8, CODE_FOR_shrqby_ti, "spu_srqwbyte_8", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQWBYTE_9, CODE_FOR_shrqby_ti, "spu_srqwbyte_9", B_INTERNAL, _A3(SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQWBYTEBC, CODE_FOR_nothing, "spu_srqwbytebc", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_SRQWBYTEBC_0, CODE_FOR_shrqbybi_ti, "spu_srqwbytebc_0", B_INTERNAL, _A3(SPU_BTI_V2DI, SPU_BTI_V2DI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQWBYTEBC_1, CODE_FOR_shrqbybi_ti, "spu_srqwbytebc_1", B_INTERNAL, _A3(SPU_BTI_UV2DI, SPU_BTI_UV2DI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQWBYTEBC_2, CODE_FOR_shrqbybi_ti, "spu_srqwbytebc_2", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_V4SI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQWBYTEBC_3, CODE_FOR_shrqbybi_ti, "spu_srqwbytebc_3", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UV4SI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQWBYTEBC_4, CODE_FOR_shrqbybi_ti, "spu_srqwbytebc_4", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_V8HI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQWBYTEBC_5, CODE_FOR_shrqbybi_ti, "spu_srqwbytebc_5", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UV8HI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQWBYTEBC_6, CODE_FOR_shrqbybi_ti, "spu_srqwbytebc_6", B_INTERNAL, _A3(SPU_BTI_V16QI, SPU_BTI_V16QI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQWBYTEBC_7, CODE_FOR_shrqbybi_ti, "spu_srqwbytebc_7", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQWBYTEBC_8, CODE_FOR_shrqbybi_ti, "spu_srqwbytebc_8", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_V4SF, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SRQWBYTEBC_9, CODE_FOR_shrqbybi_ti, "spu_srqwbytebc_9", B_INTERNAL, _A3(SPU_BTI_V2DF, SPU_BTI_V2DF, SPU_BTI_UINTSI)) - -DEF_BUILTIN (SPU_SPLATS, CODE_FOR_nothing, "spu_splats", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_SPLATS_0, CODE_FOR_spu_splats, "spu_splats_0", B_INTERNAL, _A2(SPU_BTI_UV16QI, SPU_BTI_UINTQI)) -DEF_BUILTIN (SPU_SPLATS_1, CODE_FOR_spu_splats, "spu_splats_1", B_INTERNAL, _A2(SPU_BTI_V16QI, SPU_BTI_INTQI)) -DEF_BUILTIN (SPU_SPLATS_2, CODE_FOR_spu_splats, "spu_splats_2", B_INTERNAL, _A2(SPU_BTI_UV8HI, SPU_BTI_UINTHI)) -DEF_BUILTIN (SPU_SPLATS_3, CODE_FOR_spu_splats, "spu_splats_3", B_INTERNAL, _A2(SPU_BTI_V8HI, SPU_BTI_INTHI)) -DEF_BUILTIN (SPU_SPLATS_4, CODE_FOR_spu_splats, "spu_splats_4", B_INTERNAL, _A2(SPU_BTI_UV4SI, SPU_BTI_UINTSI)) -DEF_BUILTIN (SPU_SPLATS_5, CODE_FOR_spu_splats, "spu_splats_5", B_INTERNAL, _A2(SPU_BTI_V4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_SPLATS_6, CODE_FOR_spu_splats, "spu_splats_6", B_INTERNAL, _A2(SPU_BTI_UV2DI, SPU_BTI_UINTDI)) -DEF_BUILTIN (SPU_SPLATS_7, CODE_FOR_spu_splats, "spu_splats_7", B_INTERNAL, _A2(SPU_BTI_V2DI, SPU_BTI_INTDI)) -DEF_BUILTIN (SPU_SPLATS_8, CODE_FOR_spu_splats, "spu_splats_8", B_INTERNAL, _A2(SPU_BTI_V4SF, SPU_BTI_FLOAT)) -DEF_BUILTIN (SPU_SPLATS_9, CODE_FOR_spu_splats, "spu_splats_9", B_INTERNAL, _A2(SPU_BTI_V2DF, SPU_BTI_DOUBLE)) -DEF_BUILTIN (SPU_EXTRACT, CODE_FOR_nothing, "spu_extract", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_EXTRACT_0, CODE_FOR_spu_extract, "spu_extract_0", B_INTERNAL, _A3(SPU_BTI_UINTQI, SPU_BTI_UV16QI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_EXTRACT_1, CODE_FOR_spu_extract, "spu_extract_1", B_INTERNAL, _A3(SPU_BTI_INTQI, SPU_BTI_V16QI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_EXTRACT_2, CODE_FOR_spu_extract, "spu_extract_2", B_INTERNAL, _A3(SPU_BTI_UINTHI, SPU_BTI_UV8HI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_EXTRACT_3, CODE_FOR_spu_extract, "spu_extract_3", B_INTERNAL, _A3(SPU_BTI_INTHI, SPU_BTI_V8HI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_EXTRACT_4, CODE_FOR_spu_extract, "spu_extract_4", B_INTERNAL, _A3(SPU_BTI_UINTSI, SPU_BTI_UV4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_EXTRACT_5, CODE_FOR_spu_extract, "spu_extract_5", B_INTERNAL, _A3(SPU_BTI_INTSI, SPU_BTI_V4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_EXTRACT_6, CODE_FOR_spu_extract, "spu_extract_6", B_INTERNAL, _A3(SPU_BTI_UINTDI, SPU_BTI_UV2DI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_EXTRACT_7, CODE_FOR_spu_extract, "spu_extract_7", B_INTERNAL, _A3(SPU_BTI_INTDI, SPU_BTI_V2DI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_EXTRACT_8, CODE_FOR_spu_extract, "spu_extract_8", B_INTERNAL, _A3(SPU_BTI_FLOAT, SPU_BTI_V4SF, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_EXTRACT_9, CODE_FOR_spu_extract, "spu_extract_9", B_INTERNAL, _A3(SPU_BTI_DOUBLE, SPU_BTI_V2DF, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_INSERT, CODE_FOR_nothing, "spu_insert", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_INSERT_0, CODE_FOR_spu_insert, "spu_insert_0", B_INTERNAL, _A4(SPU_BTI_UV16QI, SPU_BTI_UINTQI, SPU_BTI_UV16QI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_INSERT_1, CODE_FOR_spu_insert, "spu_insert_1", B_INTERNAL, _A4(SPU_BTI_V16QI, SPU_BTI_INTQI, SPU_BTI_V16QI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_INSERT_2, CODE_FOR_spu_insert, "spu_insert_2", B_INTERNAL, _A4(SPU_BTI_UV8HI, SPU_BTI_UINTHI, SPU_BTI_UV8HI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_INSERT_3, CODE_FOR_spu_insert, "spu_insert_3", B_INTERNAL, _A4(SPU_BTI_V8HI, SPU_BTI_INTHI, SPU_BTI_V8HI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_INSERT_4, CODE_FOR_spu_insert, "spu_insert_4", B_INTERNAL, _A4(SPU_BTI_UV4SI, SPU_BTI_UINTSI, SPU_BTI_UV4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_INSERT_5, CODE_FOR_spu_insert, "spu_insert_5", B_INTERNAL, _A4(SPU_BTI_V4SI, SPU_BTI_INTSI, SPU_BTI_V4SI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_INSERT_6, CODE_FOR_spu_insert, "spu_insert_6", B_INTERNAL, _A4(SPU_BTI_UV2DI, SPU_BTI_UINTDI, SPU_BTI_UV2DI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_INSERT_7, CODE_FOR_spu_insert, "spu_insert_7", B_INTERNAL, _A4(SPU_BTI_V2DI, SPU_BTI_INTDI, SPU_BTI_V2DI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_INSERT_8, CODE_FOR_spu_insert, "spu_insert_8", B_INTERNAL, _A4(SPU_BTI_V4SF, SPU_BTI_FLOAT, SPU_BTI_V4SF, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_INSERT_9, CODE_FOR_spu_insert, "spu_insert_9", B_INTERNAL, _A4(SPU_BTI_V2DF, SPU_BTI_DOUBLE, SPU_BTI_V2DF, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_PROMOTE, CODE_FOR_nothing, "spu_promote", B_OVERLOAD, _A1(SPU_BTI_VOID)) -DEF_BUILTIN (SPU_PROMOTE_0, CODE_FOR_spu_promote, "spu_promote_0", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UINTQI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_PROMOTE_1, CODE_FOR_spu_promote, "spu_promote_1", B_INTERNAL, _A3(SPU_BTI_V16QI, SPU_BTI_INTQI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_PROMOTE_2, CODE_FOR_spu_promote, "spu_promote_2", B_INTERNAL, _A3(SPU_BTI_UV8HI, SPU_BTI_UINTHI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_PROMOTE_3, CODE_FOR_spu_promote, "spu_promote_3", B_INTERNAL, _A3(SPU_BTI_V8HI, SPU_BTI_INTHI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_PROMOTE_4, CODE_FOR_spu_promote, "spu_promote_4", B_INTERNAL, _A3(SPU_BTI_UV4SI, SPU_BTI_UINTSI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_PROMOTE_5, CODE_FOR_spu_promote, "spu_promote_5", B_INTERNAL, _A3(SPU_BTI_V4SI, SPU_BTI_INTSI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_PROMOTE_6, CODE_FOR_spu_promote, "spu_promote_6", B_INTERNAL, _A3(SPU_BTI_UV2DI, SPU_BTI_UINTDI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_PROMOTE_7, CODE_FOR_spu_promote, "spu_promote_7", B_INTERNAL, _A3(SPU_BTI_V2DI, SPU_BTI_INTDI, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_PROMOTE_8, CODE_FOR_spu_promote, "spu_promote_8", B_INTERNAL, _A3(SPU_BTI_V4SF, SPU_BTI_FLOAT, SPU_BTI_INTSI)) -DEF_BUILTIN (SPU_PROMOTE_9, CODE_FOR_spu_promote, "spu_promote_9", B_INTERNAL, _A3(SPU_BTI_V2DF, SPU_BTI_DOUBLE, SPU_BTI_INTSI)) - -/* We need something that is not B_INTERNAL as a sentinel. */ - -/* These are for the convenience of implementing fma() in the standard - libraries. */ -DEF_BUILTIN (SCALAR_FMA, CODE_FOR_fmasf4, "fmas", B_INSN, _A4(SPU_BTI_FLOAT, SPU_BTI_FLOAT, SPU_BTI_FLOAT, SPU_BTI_FLOAT)) -DEF_BUILTIN (SCALAR_DFMA, CODE_FOR_fmadf4, "dfmas", B_INSN, _A4(SPU_BTI_DOUBLE, SPU_BTI_DOUBLE, SPU_BTI_DOUBLE, SPU_BTI_DOUBLE)) - -DEF_BUILTIN (SPU_ALIGN_HINT, CODE_FOR_spu_align_hint,"spu_align_hint", B_INSN, _A4(SPU_BTI_VOID, SPU_BTI_PTR, SPU_BTI_7, SPU_BTI_7)) -#undef _A1 -#undef _A2 -#undef _A3 -#undef _A4 diff --git a/gcc/config/spu/spu-builtins.md b/gcc/config/spu/spu-builtins.md deleted file mode 100644 index 524324f..0000000 --- a/gcc/config/spu/spu-builtins.md +++ /dev/null @@ -1,864 +0,0 @@ -;; Copyright (C) 2006-2019 Free Software Foundation, Inc. - -;; This file is free software; you can redistribute it and/or modify it under -;; the terms of the GNU General Public License as published by the Free -;; Software Foundation; either version 3 of the License, or (at your option) -;; any later version. - -;; This file is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -;; for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; . - - -;; This includes expands for all the intrinsics. -;; spu_expand_builtin looks at the mode of match_operand. - - -;; load/store - -(define_expand "spu_lqd" - [(set (match_operand:TI 0 "spu_reg_operand" "") - (mem:TI (and:SI (plus:SI (match_operand:SI 1 "spu_reg_operand" "") - (match_operand:SI 2 "spu_nonmem_operand" "")) - (const_int -16))))] - "" - { - if (GET_CODE (operands[2]) == CONST_INT - && (INTVAL (operands[2]) & 15) != 0) - operands[2] = GEN_INT (INTVAL (operands[2]) & -16); - if (GET_CODE (operands[2]) != CONST_INT) - { - rtx op2 = operands[2]; - operands[2] = force_reg (Pmode, operands[2]); - if (!ALIGNED_SYMBOL_REF_P (op2)) - emit_insn (gen_andsi3 (operands[2], operands[2], GEN_INT (-16))); - } - }) - -(define_expand "spu_lqx" - [(set (match_operand:TI 0 "spu_reg_operand" "") - (mem:TI (and:SI (plus:SI (match_operand:SI 1 "spu_reg_operand" "") - (match_operand:SI 2 "spu_reg_operand" "")) - (const_int -16))))] - "" - "") - -(define_expand "spu_lqa" - [(set (match_operand:TI 0 "spu_reg_operand" "") - (mem:TI (and:SI (match_operand:SI 1 "immediate_operand" "") - (const_int -16))))] - "" - { - if (GET_CODE (operands[1]) == CONST_INT - && (INTVAL (operands[1]) & 15) != 0) - operands[1] = GEN_INT (INTVAL (operands[1]) & -16); - }) - -(define_expand "spu_lqr" - [(set (match_operand:TI 0 "spu_reg_operand" "") - (mem:TI (and:SI (match_operand:SI 1 "address_operand" "") - (const_int -16))))] - "" - "") - -(define_expand "spu_stqd" - [(set (mem:TI (and:SI (plus:SI (match_operand:SI 1 "spu_reg_operand" "") - (match_operand:SI 2 "spu_nonmem_operand" "")) - (const_int -16))) - (match_operand:TI 0 "spu_reg_operand" "r,r"))] - "" - { - if (GET_CODE (operands[2]) == CONST_INT - && (INTVAL (operands[2]) & 15) != 0) - operands[2] = GEN_INT (INTVAL (operands[2]) & -16); - if (GET_CODE (operands[2]) != CONST_INT) - { - rtx op2 = operands[2]; - operands[2] = force_reg (Pmode, operands[2]); - if (!ALIGNED_SYMBOL_REF_P (op2)) - emit_insn (gen_andsi3 (operands[2], operands[2], GEN_INT (-16))); - } - }) - -(define_expand "spu_stqx" - [(set (mem:TI (and:SI (plus:SI (match_operand:SI 1 "spu_reg_operand" "") - (match_operand:SI 2 "spu_reg_operand" "")) - (const_int -16))) - (match_operand:TI 0 "spu_reg_operand" "r"))] - "" - "") - -(define_expand "spu_stqa" - [(set (mem:TI (and:SI (match_operand:SI 1 "immediate_operand" "") - (const_int -16))) - (match_operand:TI 0 "spu_reg_operand" "r"))] - "" - { - if (GET_CODE (operands[1]) == CONST_INT - && (INTVAL (operands[1]) & 15) != 0) - operands[1] = GEN_INT (INTVAL (operands[1]) & -16); - }) - -(define_expand "spu_stqr" - [(set (mem:TI (and:SI (match_operand:SI 1 "address_operand" "") - (const_int -16))) - (match_operand:TI 0 "spu_reg_operand" ""))] - "" - "") - - -;; generate control word - -(define_expand "spu_cbx" - [(set (match_operand:TI 0 "spu_reg_operand" "") - (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "") - (match_operand:SI 2 "spu_nonmem_operand" "") - (const_int 1)] UNSPEC_CPAT))] - "" - "") - -(define_expand "spu_chx" - [(set (match_operand:TI 0 "spu_reg_operand" "") - (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "") - (match_operand:SI 2 "spu_nonmem_operand" "") - (const_int 2)] UNSPEC_CPAT))] - "" - "") - -(define_expand "spu_cwx" - [(set (match_operand:TI 0 "spu_reg_operand" "") - (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "") - (match_operand:SI 2 "spu_nonmem_operand" "") - (const_int 4)] UNSPEC_CPAT))] - "" - "") - -(define_expand "spu_cdx" - [(set (match_operand:TI 0 "spu_reg_operand" "") - (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "") - (match_operand:SI 2 "spu_nonmem_operand" "") - (const_int 8)] UNSPEC_CPAT))] - "" - "") - - - -;; Constant formation - -(define_expand "spu_ilhu" - [(set (match_operand:V4SI 0 "spu_reg_operand" "") - (const_vector:V4SI [(match_operand:SI 1 "immediate_operand" "")]))] - "" - "{ emit_insn(gen_movv4si(operands[0], spu_const(V4SImode, (INTVAL(operands[1]) << 16)))); - DONE; - }") - - -;; integer subtract -(define_expand "spu_sfh" - [(set (match_operand:V8HI 0 "spu_reg_operand" "") - (minus:V8HI (match_operand:V8HI 2 "spu_nonmem_operand" "") - (match_operand:V8HI 1 "spu_reg_operand" "")))] - "" - "") - -(define_expand "spu_sf" - [(set (match_operand:V4SI 0 "spu_reg_operand" "") - (minus:V4SI (match_operand:V4SI 2 "spu_nonmem_operand" "") - (match_operand:V4SI 1 "spu_reg_operand" "")))] - "" - "") - -(define_expand "spu_sfx" - [(set (match_operand:V4SI 0 "spu_reg_operand" "") - (unspec:V4SI [(match_operand:V4SI 2 "spu_reg_operand" "") - (match_operand:V4SI 1 "spu_reg_operand" "") - (match_operand:V4SI 3 "spu_reg_operand" "")] UNSPEC_SFX))] - "" - "") - -(define_expand "spu_bg" - [(set (match_operand:V4SI 0 "spu_reg_operand" "") - (unspec:V4SI [(match_operand:V4SI 2 "spu_reg_operand" "") - (match_operand:V4SI 1 "spu_reg_operand" "")] UNSPEC_BG))] - "" - "") - -(define_expand "spu_bgx" - [(set (match_operand:V4SI 0 "spu_reg_operand" "") - (unspec:V4SI [(match_operand:V4SI 2 "spu_reg_operand" "") - (match_operand:V4SI 1 "spu_reg_operand" "") - (match_operand:V4SI 3 "spu_reg_operand" "")] UNSPEC_BGX))] - "" - "") - -(define_insn "spu_mpya" - [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") - (plus:V4SI - (mult:V4SI - (sign_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 1 "spu_reg_operand" "r") - (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))) - (sign_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 2 "spu_reg_operand" "r") - (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))) - (match_operand:V4SI 3 "spu_reg_operand" "r")))] - "" - "mpya\t%0,%1,%2,%3" - [(set_attr "type" "fp7")]) - -(define_insn "spu_mpyh" - [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") - (ashift:V4SI - (mult:V4SI - (sign_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 1 "spu_reg_operand" "r") - (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))) - (sign_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 2 "spu_reg_operand" "r") - (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))) - (const_vector:V4SI [(const_int 16)(const_int 16)(const_int 16)(const_int 16)])))] - "" - "mpyh\t%0,%1,%2" - [(set_attr "type" "fp7")]) - -(define_insn "spu_mpys" - [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") - (ashiftrt:V4SI - (mult:V4SI - (sign_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 1 "spu_reg_operand" "r") - (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))) - (sign_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 2 "spu_reg_operand" "r") - (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))) - (const_vector:V4SI [(const_int 16)(const_int 16)(const_int 16)(const_int 16)])))] - "" - "mpys\t%0,%1,%2" - [(set_attr "type" "fp7")]) - -(define_insn "spu_mpyhhau" - [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") - (plus:V4SI - (mult:V4SI - (zero_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 1 "spu_reg_operand" "r") - (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))) - (zero_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 2 "spu_reg_operand" "r") - (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))) - (match_operand:V4SI 3 "spu_reg_operand" "0")))] - "" - "mpyhhau\t%0,%1,%2" - [(set_attr "type" "fp7")]) - -(define_insn "spu_mpyhha" - [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") - (plus:V4SI - (mult:V4SI - (sign_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 1 "spu_reg_operand" "r") - (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))) - (sign_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 2 "spu_reg_operand" "r") - (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))) - (match_operand:V4SI 3 "spu_reg_operand" "0")))] - "" - "mpyhha\t%0,%1,%2" - [(set_attr "type" "fp7")]) - -;; form select mask -(define_insn "spu_fsmb" - [(set (match_operand:V16QI 0 "spu_reg_operand" "=r,r") - (unspec:V16QI [(match_operand:SI 1 "spu_nonmem_operand" "r,MN")] UNSPEC_FSMB))] - "" - "@ - fsmb\t%0,%1 - fsmbi\t%0,%1" - [(set_attr "type" "shuf")]) - -(define_insn "spu_fsmh" - [(set (match_operand:V8HI 0 "spu_reg_operand" "=r") - (unspec:V8HI [(match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_FSMH))] - "" - "fsmh\t%0,%1" - [(set_attr "type" "shuf")]) - -(define_insn "spu_fsm" - [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") - (unspec:V4SI [(match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_FSM))] - "" - "fsm\t%0,%1" - [(set_attr "type" "shuf")]) - - -;; gather bits -(define_insn "spu_gbb" - [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") - (unspec:V4SI [(match_operand:V16QI 1 "spu_reg_operand" "r")] UNSPEC_GBB))] - "" - "gbb\t%0,%1" - [(set_attr "type" "shuf")]) - -(define_insn "spu_gbh" - [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") - (unspec:V4SI [(match_operand:V8HI 1 "spu_reg_operand" "r")] UNSPEC_GBH))] - "" - "gbh\t%0,%1" - [(set_attr "type" "shuf")]) - -(define_insn "spu_gb" - [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") - (unspec:V4SI [(match_operand:V4SI 1 "spu_reg_operand" "r")] UNSPEC_GB))] - "" - "gb\t%0,%1" - [(set_attr "type" "shuf")]) - -;; misc byte operations -(define_insn "spu_avgb" - [(set (match_operand:V16QI 0 "spu_reg_operand" "=r") - (unspec:V16QI [(match_operand:V16QI 1 "spu_reg_operand" "r") - (match_operand:V16QI 2 "spu_reg_operand" "r")] UNSPEC_AVGB))] - "" - "avgb\t%0,%1,%2" - [(set_attr "type" "fxb")]) - -(define_insn "spu_absdb" - [(set (match_operand:V16QI 0 "spu_reg_operand" "=r") - (unspec:V16QI [(match_operand:V16QI 1 "spu_reg_operand" "r") - (match_operand:V16QI 2 "spu_reg_operand" "r")] UNSPEC_ABSDB))] - "" - "absdb\t%0,%1,%2" - [(set_attr "type" "fxb")]) - -(define_insn "spu_sumb" - [(set (match_operand:V8HI 0 "spu_reg_operand" "=r") - (unspec:V8HI [(match_operand:V16QI 1 "spu_reg_operand" "r") - (match_operand:V16QI 2 "spu_reg_operand" "r")] UNSPEC_SUMB))] - "" - "sumb\t%0,%1,%2" - [(set_attr "type" "fxb")]) - -;; sign extend -(define_insn "spu_xsbh" - [(set (match_operand:V8HI 0 "spu_reg_operand" "=r") - (sign_extend:V8HI - (vec_select:V8QI - (match_operand:V16QI 1 "spu_reg_operand" "r") - (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7) - (const_int 9)(const_int 11)(const_int 13)(const_int 15)]))))] - "" - "xsbh\t%0,%1") - -(define_insn "spu_xshw" - [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") - (sign_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 1 "spu_reg_operand" "r") - (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))))] - "" - "xshw\t%0,%1") - -(define_insn "spu_xswd" - [(set (match_operand:V2DI 0 "spu_reg_operand" "=r") - (sign_extend:V2DI - (vec_select:V2SI - (match_operand:V4SI 1 "spu_reg_operand" "r") - (parallel [(const_int 1)(const_int 3)]))))] - "" - "xswd\t%0,%1") - -;; or across - -(define_insn "spu_orx" - [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") - (unspec:V4SI [(match_operand:V4SI 1 "spu_reg_operand" "r")] UNSPEC_ORX))] - "" - "orx\t%0,%1") - - -;; compare & halt -(define_insn "spu_heq" - [(unspec_volatile [(match_operand:SI 0 "spu_reg_operand" "r,r") - (match_operand:SI 1 "spu_nonmem_operand" "r,K")] UNSPEC_HEQ)] - "" - "@ - heq\t%0,%1 - heqi\t%0,%1") - -(define_insn "spu_hgt" - [(unspec_volatile [(match_operand:SI 0 "spu_reg_operand" "r,r") - (match_operand:SI 1 "spu_nonmem_operand" "r,K")] UNSPEC_HGT)] - "" - "@ - hgt\t%0,%1 - hgti\t%0,%1") - -(define_insn "spu_hlgt" - [(unspec_volatile [(match_operand:SI 0 "spu_reg_operand" "r,r") - (match_operand:SI 1 "spu_nonmem_operand" "r,K")] UNSPEC_HLGT)] - "" - "@ - hlgt\t%0,%1 - hlgti\t%0,%1") - -;; branches - -;; The description below hides the fact that bisled conditionally -;; executes the call depending on the value in channel 0. This was -;; done so that the description would conform to the format of a call -;; insn. Otherwise (if this were not part of call insn), the link -;; register, $lr, would not be saved/restored in the prologue/epilogue. - -(define_insn "spu_bisled" - [(parallel - [(call (mem:QI (match_operand:SI 0 "spu_reg_operand" "r")) - (const_int 0)) - (clobber (reg:SI 0)) - (clobber (reg:SI 130)) - (use (match_operand:SI 1 "address_operand" "")) - (use (const_int 0))])] - "" - "bisled\t$lr,%0" - [(set_attr "type" "br")]) - -(define_insn "spu_bisledd" - [(parallel - [(call (mem:QI (match_operand:SI 0 "spu_reg_operand" "r")) - (const_int 0)) - (clobber (reg:SI 0)) - (clobber (reg:SI 130)) - (use (match_operand:SI 1 "address_operand" "")) - (use (const_int 1))])] - "" - "bisledd\t$lr,%0" - [(set_attr "type" "br")]) - -(define_insn "spu_bislede" - [(parallel - [(call (mem:QI (match_operand:SI 0 "spu_reg_operand" "r")) - (const_int 0)) - (clobber (reg:SI 0)) - (clobber (reg:SI 130)) - (use (match_operand:SI 1 "address_operand" "")) - (use (const_int 2))])] - "" - "bislede\t$lr,%0" - [(set_attr "type" "br")]) - -;; float convert -(define_expand "spu_csflt" - [(set (match_operand:V4SF 0 "spu_reg_operand") - (unspec:V4SF [(match_operand:V4SI 1 "spu_reg_operand") - (match_operand:SI 2 "spu_nonmem_operand")] 0 ))] - "" -{ - if (GET_CODE (operands[2]) == CONST_INT - && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) > 127)) - { - error ("spu_convtf expects an integer literal in the range [0, 127]."); - operands[2] = force_reg (SImode, operands[2]); - } - if (GET_CODE (operands[2]) != CONST_INT) - { - rtx exp2; - rtx cnv = gen_reg_rtx (V4SFmode); - rtx scale = gen_reg_rtx (SImode); - rtx op2 = force_reg (SImode, operands[2]); - rtx m1 = spu_gen_exp2 (V4SFmode, GEN_INT (-1)); - emit_insn (gen_subsi3 (scale, const1_rtx, op2)); - exp2 = spu_gen_exp2 (V4SFmode, scale); - emit_insn (gen_floatv4siv4sf2_mul (cnv, operands[1], m1)); - emit_insn (gen_mulv4sf3 (operands[0], cnv, exp2)); - } - else - { - rtx exp2 = spu_gen_exp2 (V4SFmode, operands[2]); - emit_insn (gen_floatv4siv4sf2_div (operands[0], operands[1], exp2)); - } - DONE; -}) - -(define_expand "spu_cflts" - [(set (match_operand:V4SI 0 "spu_reg_operand") - (unspec:V4SI [(match_operand:V4SF 1 "spu_reg_operand") - (match_operand:SI 2 "spu_nonmem_operand")] 0 ))] - "" -{ - rtx exp2; - if (GET_CODE (operands[2]) == CONST_INT - && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) > 127)) - { - error ("spu_convts expects an integer literal in the range [0, 127]."); - operands[2] = force_reg (SImode, operands[2]); - } - exp2 = spu_gen_exp2 (V4SFmode, operands[2]); - if (GET_CODE (operands[2]) != CONST_INT) - { - rtx mul = gen_reg_rtx (V4SFmode); - emit_insn (gen_mulv4sf3 (mul, operands[1], exp2)); - emit_insn (gen_fix_truncv4sfv4si2 (operands[0], mul)); - } - else - emit_insn (gen_fix_truncv4sfv4si2_mul (operands[0], operands[1], exp2)); - DONE; -}) - -(define_expand "spu_cuflt" - [(set (match_operand:V4SF 0 "spu_reg_operand" "=r") - (unspec:V4SF [(match_operand:V4SI 1 "spu_reg_operand") - (match_operand:SI 2 "spu_nonmem_operand")] 0 ))] - "" -{ - if (GET_CODE (operands[2]) == CONST_INT - && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) > 127)) - { - error ("spu_convtf expects an integer literal in the range [0, 127]."); - operands[2] = force_reg (SImode, operands[2]); - } - if (GET_CODE (operands[2]) != CONST_INT) - { - rtx exp2; - rtx cnv = gen_reg_rtx (V4SFmode); - rtx scale = gen_reg_rtx (SImode); - rtx op2 = force_reg (SImode, operands[2]); - rtx m1 = spu_gen_exp2 (V4SFmode, GEN_INT (-1)); - emit_insn (gen_subsi3 (scale, const1_rtx, op2)); - exp2 = spu_gen_exp2 (V4SFmode, scale); - emit_insn (gen_floatunsv4siv4sf2_mul (cnv, operands[1], m1)); - emit_insn (gen_mulv4sf3 (operands[0], cnv, exp2)); - } - else - { - rtx exp2 = spu_gen_exp2 (V4SFmode, operands[2]); - emit_insn (gen_floatunsv4siv4sf2_div (operands[0], operands[1], exp2)); - } - DONE; -}) - -(define_expand "spu_cfltu" - [(set (match_operand:V4SI 0 "spu_reg_operand") - (unspec:V4SI [(match_operand:V4SF 1 "spu_reg_operand") - (match_operand:SI 2 "spu_nonmem_operand")] 0 ))] - "" -{ - rtx exp2; - if (GET_CODE (operands[2]) == CONST_INT - && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) > 127)) - { - error ("spu_convtu expects an integer literal in the range [0, 127]."); - operands[2] = force_reg (SImode, operands[2]); - } - exp2 = spu_gen_exp2 (V4SFmode, operands[2]); - if (GET_CODE (operands[2]) != CONST_INT) - { - rtx mul = gen_reg_rtx (V4SFmode); - emit_insn (gen_mulv4sf3 (mul, operands[1], exp2)); - emit_insn (gen_fixuns_truncv4sfv4si2 (operands[0], mul)); - } - else - emit_insn (gen_fixuns_truncv4sfv4si2_mul (operands[0], operands[1], exp2)); - DONE; -}) - -(define_expand "spu_frds" - [(set (match_operand:V4SF 0 "spu_reg_operand" "") - (vec_select:V4SF - (vec_concat:V4SF - (float_truncate:V2SF (match_operand:V2DF 1 "spu_reg_operand" "")) - (match_dup:V2SF 2)) - (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))] - "" - "operands[2] = spu_const(V2SFmode, 0);") - -(define_insn "_frds" - [(set (match_operand:V4SF 0 "spu_reg_operand" "=r") - (vec_select:V4SF - (vec_concat:V4SF - (float_truncate:V2SF (match_operand:V2DF 1 "spu_reg_operand" "r")) - (match_operand:V2SF 2 "vec_imm_operand" "i")) - (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))] - "" - "frds\t%0,%1" - [(set_attr "type" "fpd")]) - -(define_insn "spu_fesd" - [(set (match_operand:V2DF 0 "spu_reg_operand" "=r") - (float_extend:V2DF - (vec_select:V2SF - (match_operand:V4SF 1 "spu_reg_operand" "r") - (parallel [(const_int 0)(const_int 2)]))))] - "" - "fesd\t%0,%1" - [(set_attr "type" "fpd")]) - -;; control -(define_insn "spu_stop" - [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "M")] UNSPEC_STOP)] - "" - "stop\t%0" - [(set_attr "type" "br")]) - -(define_insn "spu_stopd" - [(unspec_volatile [(match_operand:SI 0 "spu_reg_operand" "r") - (match_operand:SI 1 "spu_reg_operand" "r") - (match_operand:SI 2 "spu_reg_operand" "r")] UNSPEC_STOPD)] - "" - "stopd\t%0,%1,%2" - [(set_attr "type" "br")]) - -;; interrupt disable/enable -(define_expand "spu_idisable" - [(parallel - [(unspec_volatile [(const_int 0)] UNSPEC_SET_INTR) - (clobber (match_dup:SI 0)) - (clobber (mem:BLK (scratch)))])] - "" - "operands[0] = gen_reg_rtx (SImode);") - -(define_expand "spu_ienable" - [(parallel - [(unspec_volatile [(const_int 1)] UNSPEC_SET_INTR) - (clobber (match_dup:SI 0)) - (clobber (mem:BLK (scratch)))])] - "" - "operands[0] = gen_reg_rtx (SImode);") - -(define_insn "set_intr" - [(unspec_volatile [(match_operand 1 "const_int_operand" "i")] UNSPEC_SET_INTR) - (clobber (match_operand:SI 0 "spu_reg_operand" "=&r")) - (clobber (mem:BLK (scratch)))] - "! flag_pic" - "ila\t%0,.+8\;bi%I1\t%0" - [(set_attr "length" "8") - (set_attr "type" "multi0")]) - -(define_insn "set_intr_pic" - [(unspec_volatile [(match_operand 1 "const_int_operand" "i")] UNSPEC_SET_INTR) - (clobber (match_operand:SI 0 "spu_reg_operand" "=&r")) - (clobber (mem:BLK (scratch)))] - "flag_pic" - "brsl\t%0,.+4\;ai\t%0,%0,8\;bi%I1\t%0" - [(set_attr "length" "12") - (set_attr "type" "multi1")]) - -(define_insn "set_intr_cc" - [(cond_exec (match_operator 1 "branch_comparison_operator" - [(match_operand 2 "spu_reg_operand" "r") - (const_int 0)]) - (parallel [(unspec_volatile [(match_operand:SI 3 "const_int_operand" "i")] UNSPEC_SET_INTR) - (clobber (match_operand:SI 0 "spu_reg_operand" "=&r")) - (clobber (mem:BLK (scratch)))]))] - "! flag_pic" - "ila\t%0,.+8\;bi%b2%b1z%I3\t%2,%0" - [(set_attr "length" "8") - (set_attr "type" "multi0")]) - -(define_insn "set_intr_cc_pic" - [(cond_exec (match_operator 1 "branch_comparison_operator" - [(match_operand 2 "spu_reg_operand" "r") - (const_int 0)]) - (parallel [(unspec_volatile [(match_operand:SI 3 "const_int_operand" "i")] UNSPEC_SET_INTR) - (clobber (match_operand:SI 0 "spu_reg_operand" "=&r")) - (clobber (mem:BLK (scratch)))]))] - "flag_pic" - "brsl\t%0,.+4\;ai\t%0,%0,8\;bi%b2%b1z%I3\t%2,%0" - [(set_attr "length" "12") - (set_attr "type" "multi1")]) - -(define_insn "set_intr_return" - [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")] UNSPEC_SET_INTR) - (return)] - "" - "bi%I0\t$lr" - [(set_attr "type" "br")]) - -(define_peephole2 - [(parallel - [(unspec_volatile [(match_operand:SI 0 "const_int_operand")] UNSPEC_SET_INTR) - (clobber (match_operand:SI 1 "spu_reg_operand")) - (clobber (mem:BLK (scratch)))]) - (use (reg:SI 0)) - (return)] - "" - [(use (reg:SI 0)) - (parallel - [(unspec_volatile [(match_dup:SI 0)] UNSPEC_SET_INTR) - (return)])] - "") - -;; special purpose registers -(define_insn "spu_fscrrd" - [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") - (unspec_volatile:V4SI [(const_int 6)] UNSPEC_FSCRRD))] - "" - "fscrrd\t%0" - [(set_attr "type" "spr")]) - -(define_insn "spu_fscrwr" - [(unspec_volatile [(match_operand:V4SI 0 "spu_reg_operand" "r")] UNSPEC_FSCRWR)] - "" - "fscrwr\t$0,%0" - [(set_attr "type" "spr")]) - -(define_insn "spu_mfspr" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_MFSPR))] - "" - "mfspr\t%0,$sp%1" - [(set_attr "type" "spr")]) - -(define_insn "spu_mtspr" - [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "J") - (match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_MTSPR)] - "" - "mtspr\t$sp%0,%1" - [(set_attr "type" "spr")]) - -;; channels -(define_expand "spu_rdch" - [(set (match_operand:V4SI 0 "spu_reg_operand" "") - (unspec_volatile:V4SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_RDCH))] - "" - "{ - if (spu_safe_dma (INTVAL (operands[1]))) - { - emit_insn (gen_spu_rdch_clobber (operands[0], operands[1])); - DONE; - } - }") - -(define_expand "spu_rchcnt" - [(set (match_operand:SI 0 "spu_reg_operand" "") - (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_RCHCNT))] - "" - "{ - if (spu_safe_dma (INTVAL (operands[1]))) - { - emit_insn (gen_spu_rchcnt_clobber (operands[0], operands[1])); - DONE; - } - }") - -(define_expand "spu_wrch" - [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "") - (match_operand:V4SI 1 "spu_reg_operand" "")] UNSPEC_WRCH)] - "" - "{ - if (spu_safe_dma (INTVAL (operands[0]))) - { - emit_insn (gen_spu_wrch_clobber (operands[0], operands[1])); - DONE; - } - }") - -(define_insn "spu_rdch_noclobber" - [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") - (unspec_volatile:V4SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RDCH))] - "" - "rdch\t%0,$ch%1" - [(set_attr "type" "spr")]) - -(define_insn "spu_rchcnt_noclobber" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RCHCNT))] - "" - "rchcnt\t%0,$ch%1" - [(set_attr "type" "spr")]) - -(define_insn "spu_wrch_noclobber" - [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "J") - (match_operand:V4SI 1 "spu_reg_operand" "r")] UNSPEC_WRCH)] - "" - "wrch\t$ch%0,%1" - [(set_attr "type" "spr")]) - -(define_insn "spu_rdch_clobber" - [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") - (unspec_volatile:V4SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RDCH)) - (clobber (mem:BLK (scratch)))] - "" - "rdch\t%0,$ch%1" - [(set_attr "type" "spr")]) - -(define_insn "spu_rchcnt_clobber" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RCHCNT)) - (clobber (mem:BLK (scratch)))] - "" - "rchcnt\t%0,$ch%1" - [(set_attr "type" "spr")]) - -(define_insn "spu_wrch_clobber" - [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "J") - (match_operand:V4SI 1 "spu_reg_operand" "r")] UNSPEC_WRCH) - (clobber (mem:BLK (scratch)))] - "" - "wrch\t$ch%0,%1" - [(set_attr "type" "spr")]) - -(define_expand "spu_splats" - [(set (match_operand 0 "spu_reg_operand" "") - (vec_duplicate (match_operand 1 "spu_nonmem_operand" "")))] - "" - { - spu_builtin_splats(operands); - DONE; - }) - -(define_expand "spu_extract" - [(set (match_operand 0 "spu_reg_operand" "") - (unspec [(match_operand 1 "spu_reg_operand" "") - (match_operand 2 "spu_nonmem_operand" "")] 0))] - "" - { - spu_builtin_extract (operands); - DONE; - }) - -(define_expand "spu_insert" - [(set (match_operand 0 "spu_reg_operand" "") - (unspec [(match_operand 1 "spu_reg_operand" "") - (match_operand 2 "spu_reg_operand" "") - (match_operand:SI 3 "spu_nonmem_operand" "")] 0))] - "" - { - spu_builtin_insert(operands); - DONE; - }) - -(define_expand "spu_promote" - [(set (match_operand 0 "spu_reg_operand" "") - (unspec [(match_operand 1 "spu_reg_operand" "") - (match_operand:SI 2 "immediate_operand" "")] 0))] - "" - { - spu_builtin_promote(operands); - DONE; - }) - -;; Currently doing nothing with this but expanding its args. -(define_expand "spu_align_hint" - [(unspec [(match_operand:SI 0 "address_operand" "") - (match_operand:SI 1 "immediate_operand" "") - (match_operand:SI 2 "immediate_operand" "")] 0)] - "" - { - DONE; - }) - diff --git a/gcc/config/spu/spu-c.c b/gcc/config/spu/spu-c.c deleted file mode 100644 index 6312082..0000000 --- a/gcc/config/spu/spu-c.c +++ /dev/null @@ -1,233 +0,0 @@ -/* Copyright (C) 2006-2019 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - . */ - -#define IN_TARGET_CODE 1 - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "target.h" -#include "c-family/c-common.h" -#include "stringpool.h" -#include "langhooks.h" - - -/* Keep the vector keywords handy for fast comparisons. */ -static GTY(()) tree __vector_keyword; -static GTY(()) tree vector_keyword; - -static cpp_hashnode * -spu_categorize_keyword (const cpp_token *tok) -{ - if (tok->type == CPP_NAME) - { - cpp_hashnode *ident = tok->val.node.node; - - if (ident == C_CPP_HASHNODE (vector_keyword) - || ident == C_CPP_HASHNODE (__vector_keyword)) - return C_CPP_HASHNODE (__vector_keyword); - else - return ident; - } - return 0; -} - -/* Called to decide whether a conditional macro should be expanded. - Since we have exactly one such macro (i.e, 'vector'), we do not - need to examine the 'tok' parameter. */ - -static cpp_hashnode * -spu_macro_to_expand (cpp_reader *pfile, const cpp_token *tok) -{ - cpp_hashnode *expand_this = tok->val.node.node; - cpp_hashnode *ident; - - ident = spu_categorize_keyword (tok); - if (ident == C_CPP_HASHNODE (__vector_keyword)) - { - tok = cpp_peek_token (pfile, 0); - ident = spu_categorize_keyword (tok); - - if (ident) - { - enum rid rid_code = (enum rid)(ident->rid_code); - if (cpp_macro_p (ident)) - { - (void) cpp_get_token (pfile); - tok = cpp_peek_token (pfile, 0); - ident = spu_categorize_keyword (tok); - if (ident) - rid_code = (enum rid)(ident->rid_code); - } - - if (rid_code == RID_UNSIGNED || rid_code == RID_LONG - || rid_code == RID_SHORT || rid_code == RID_SIGNED - || rid_code == RID_INT || rid_code == RID_CHAR - || rid_code == RID_FLOAT || rid_code == RID_DOUBLE) - expand_this = C_CPP_HASHNODE (__vector_keyword); - } - } - return expand_this; -} - -/* target hook for resolve_overloaded_builtin(). Returns a function call - RTX if we can resolve the overloaded builtin */ -tree -spu_resolve_overloaded_builtin (location_t loc, tree fndecl, void *passed_args) -{ -#define SCALAR_TYPE_P(t) (INTEGRAL_TYPE_P (t) \ - || SCALAR_FLOAT_TYPE_P (t) \ - || POINTER_TYPE_P (t)) - vec *fnargs = static_cast *> (passed_args); - unsigned int nargs = vec_safe_length (fnargs); - int new_fcode, fcode = DECL_MD_FUNCTION_CODE (fndecl); - struct spu_builtin_description *desc; - tree match = NULL_TREE; - - /* The vector types are not available if the backend is not initialized. */ - gcc_assert (!flag_preprocess_only); - - desc = &spu_builtins[fcode]; - if (desc->type != B_OVERLOAD) - return NULL_TREE; - - /* Compare the signature of each internal builtin function with the - function arguments until a match is found. */ - - for (new_fcode = fcode + 1; spu_builtins[new_fcode].type == B_INTERNAL; - new_fcode++) - { - tree decl = targetm.builtin_decl (new_fcode, true); - tree params = TYPE_ARG_TYPES (TREE_TYPE (decl)); - tree param; - bool all_scalar; - unsigned int p; - - /* Check whether all parameters are scalar. */ - all_scalar = true; - for (param = params; param != void_list_node; param = TREE_CHAIN (param)) - if (!SCALAR_TYPE_P (TREE_VALUE (param))) - all_scalar = false; - - for (param = params, p = 0; - param != void_list_node; - param = TREE_CHAIN (param), p++) - { - tree var, arg_type, param_type = TREE_VALUE (param); - - if (p >= nargs) - { - error ("insufficient arguments to overloaded function %s", - desc->name); - return error_mark_node; - } - - var = (*fnargs)[p]; - - if (TREE_CODE (var) == NON_LVALUE_EXPR) - var = TREE_OPERAND (var, 0); - - if (TREE_CODE (var) == ERROR_MARK) - return NULL_TREE; /* Let somebody else deal with the problem. */ - - arg_type = TREE_TYPE (var); - - /* The intrinsics spec does not specify precisely how to - resolve generic intrinsics. We require an exact match - for vector types and let C do it's usual parameter type - checking/promotions for scalar arguments, except for the - first argument of intrinsics which don't have a vector - parameter. */ - if ((!SCALAR_TYPE_P (param_type) - || !SCALAR_TYPE_P (arg_type) - || (all_scalar && p == 0)) - && !lang_hooks.types_compatible_p (param_type, arg_type)) - break; - } - if (param == void_list_node) - { - if (p != nargs) - { - error ("too many arguments to overloaded function %s", - desc->name); - return error_mark_node; - } - - match = decl; - break; - } - } - - if (match == NULL_TREE) - { - error ("parameter list does not match a valid signature for %s()", - desc->name); - return error_mark_node; - } - - return build_function_call_vec (loc, vNULL, match, fnargs, NULL); -#undef SCALAR_TYPE_P -} - - -void -spu_cpu_cpp_builtins (struct cpp_reader *pfile) -{ - cpp_define (pfile, "__SPU__"); - cpp_assert (pfile, "cpu=spu"); - cpp_assert (pfile, "machine=spu"); - if (spu_arch == PROCESSOR_CELLEDP) - cpp_define (pfile, "__SPU_EDP__"); - if (cpp_get_options (pfile)->lang != CLK_ASM) - cpp_define (pfile, "__vector=__attribute__((__spu_vector__))"); - switch (spu_ea_model) - { - case 32: - cpp_define (pfile, "__EA32__"); - break; - case 64: - cpp_define (pfile, "__EA64__"); - break; - default: - gcc_unreachable (); - } - - if (!flag_iso && cpp_get_options (pfile)->lang != CLK_ASM) - { - /* Define this when supporting context-sensitive keywords. */ - cpp_define (pfile, "__VECTOR_KEYWORD_SUPPORTED__"); - cpp_define (pfile, "vector=vector"); - - /* Initialize vector keywords. */ - __vector_keyword = get_identifier ("__vector"); - C_CPP_HASHNODE (__vector_keyword)->flags |= NODE_CONDITIONAL; - vector_keyword = get_identifier ("vector"); - C_CPP_HASHNODE (vector_keyword)->flags |= NODE_CONDITIONAL; - - /* Enable context-sensitive macros. */ - cpp_get_callbacks (pfile)->macro_to_expand = spu_macro_to_expand; - } -} - -void -spu_c_common_override_options (void) -{ - if (!TARGET_STD_MAIN) - { - /* Don't give warnings about the main() function. */ - warn_main = 0; - } -} diff --git a/gcc/config/spu/spu-elf.h b/gcc/config/spu/spu-elf.h deleted file mode 100644 index 7ce6020..0000000 --- a/gcc/config/spu/spu-elf.h +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright (C) 2006-2019 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - . */ - -#ifndef OBJECT_FORMAT_ELF - #error elf.h included before elfos.h -#endif - -#define BSS_SECTION_ASM_OP "\t.section .bss" - -#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ - asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN) - - -/* The following macros define "native" directory locations; on the SPU, - these are used only when building the compiler with --with-sysroot. - This can be used to build a pair of PPU and SPU cross-compilers with - a common sysroot; the SPU compiler will search for its files in - ${sysroot}/include and ${sysroot}/lib. */ - -/* STANDARD_STARTFILE_PREFIX_1 is "/lib", which we keep. - STANDARD_STARTFILE_PREFIX_2 is "/usr/lib" -- we remove this. */ -#undef STANDARD_STARTFILE_PREFIX_2 -#define STANDARD_STARTFILE_PREFIX_2 "" - -/* We do not provide any "/usr/local/include" directory on SPU. */ -#undef LOCAL_INCLUDE_DIR - -/* Provide a STARTFILE_SPEC appropriate for GNU/Linux. Here we add - the GNU/Linux magical crtbegin.o file (see crtstuff.c) which - provides part of the support for getting C++ file-scope static - object constructed before entering `main'. */ - -#undef STARTFILE_SPEC -#define STARTFILE_SPEC "%{mstdmain: %{pg|p:gcrt2.o%s;:crt2.o%s}}\ - %{!mstdmain: %{pg|p:gcrt1.o%s;:crt1.o%s}}\ - crti.o%s crtbegin.o%s" - -#undef ENDFILE_SPEC -#define ENDFILE_SPEC "crtend.o%s crtn.o%s" - -#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG - -#define DWARF2_DEBUGGING_INFO 1 -#define DWARF2_ASM_LINE_DEBUG_INFO 1 - -#define SET_ASM_OP "\t.set\t" - -#undef TARGET_ASM_NAMED_SECTION -#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section - -#define EH_FRAME_THROUGH_COLLECT2 1 - -#define LINK_SPEC "%{mlarge-mem: --defsym __stack=0xfffffff0 }" - -#define LIB_SPEC "-( %{!shared:%{g*:-lg}} -lc -lgloss -) \ - %{mno-atomic-updates:-lgcc_cachemgr_nonatomic; :-lgcc_cachemgr} \ - %{mcache-size=128:-lgcc_cache128k; \ - mcache-size=64 :-lgcc_cache64k; \ - mcache-size=32 :-lgcc_cache32k; \ - mcache-size=16 :-lgcc_cache16k; \ - mcache-size=8 :-lgcc_cache8k; \ - :-lgcc_cache64k}" diff --git a/gcc/config/spu/spu-modes.def b/gcc/config/spu/spu-modes.def deleted file mode 100644 index 319baf6..0000000 --- a/gcc/config/spu/spu-modes.def +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2006-2019 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - . */ - -/* Vector modes. */ -VECTOR_MODES (INT, 2); /* V2QI */ -VECTOR_MODES (INT, 4); /* V4QI V2HI */ -VECTOR_MODES (INT, 8); /* V8QI V4HI V2SI */ -VECTOR_MODES (INT, 16); /* V16QI V8HI V4SI V2DI */ - - -VECTOR_MODES (FLOAT, 8); /* V4HF V2SF */ -VECTOR_MODES (FLOAT, 16); /* V8HF V4SF V2DF */ - -/* cse_insn needs an INT_MODE larger than WORD_MODE, otherwise some - parts of it will go into an infinite loop. */ -INT_MODE (OI, 32); diff --git a/gcc/config/spu/spu-protos.h b/gcc/config/spu/spu-protos.h deleted file mode 100644 index 3b18d99..0000000 --- a/gcc/config/spu/spu-protos.h +++ /dev/null @@ -1,95 +0,0 @@ -/* Copyright (C) 2006-2019 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - . */ - -#ifndef _SPU_PROTOS_ -#define _SPU_PROTOS_ - -extern void spu_cpu_cpp_builtins (struct cpp_reader * pfile); -extern void builtin_define_std (const char *); -extern void spu_c_common_override_options (void); -extern int valid_subreg (rtx op); -extern void spu_expand_extv (rtx * ops, int unsignedp); -extern void spu_expand_insv (rtx * ops); -extern int spu_expand_block_move (rtx * ops); -extern void spu_emit_branch_or_set (int is_set, rtx cmp, rtx * operands); -extern int spu_emit_vector_cond_expr (rtx, rtx, rtx, rtx, rtx, rtx); -extern HOST_WIDE_INT const_double_to_hwint (rtx x); -extern void print_operand_address (FILE * file, register rtx addr); -extern void print_operand (FILE * file, rtx x, int code); -extern int spu_split_immediate (rtx * ops); -extern int spu_saved_regs_size (void); -extern int direct_return (void); -extern void spu_expand_prologue (void); -extern void spu_expand_epilogue (bool sibcall_p); -extern rtx spu_return_addr (int count, rtx frame); - -#ifdef RTX_CODE -extern rtx hwint_to_const_double (machine_mode mode, HOST_WIDE_INT v); -extern rtx spu_const (machine_mode mode, HOST_WIDE_INT val); -extern rtx spu_const_from_ints (machine_mode mode, - int a, int b, int c, int d); -extern rtx spu_float_const (const char *string, - machine_mode mode); -extern int immediate_load_p (rtx op, machine_mode mode); -extern int logical_immediate_p (rtx op, machine_mode mode); -extern int iohl_immediate_p (rtx op, machine_mode mode); -extern int arith_immediate_p (rtx op, machine_mode mode, - HOST_WIDE_INT low, HOST_WIDE_INT high); -extern bool exp2_immediate_p (rtx op, machine_mode mode, int low, - int high); -extern int spu_constant_address_p (rtx x); -extern bool spu_legitimate_constant_p (machine_mode, rtx); -extern int spu_initial_elimination_offset (int from, int to); -extern rtx spu_function_value (const_tree type, const_tree func); -extern int spu_expand_mov (rtx * ops, machine_mode mode); -extern int spu_split_load (rtx * ops); -extern int spu_split_store (rtx * ops); -extern int fsmbi_const_p (rtx x); -extern int cpat_const_p (rtx x, machine_mode mode); -extern rtx gen_cpat_const (rtx * ops); -extern void constant_to_array (machine_mode mode, rtx x, - unsigned char *arr); -extern rtx array_to_constant (machine_mode mode, const unsigned char *arr); -extern rtx spu_gen_exp2 (machine_mode mode, rtx x); -extern void spu_allocate_stack (rtx op0, rtx op1); -extern void spu_restore_stack_nonlocal (rtx op0, rtx op1); -extern void spu_restore_stack_block (rtx op0, rtx op1); -extern rtx spu_gen_subreg (machine_mode mode, rtx x); -extern int spu_safe_dma(HOST_WIDE_INT channel); -extern void spu_builtin_splats (rtx ops[]); -extern void spu_builtin_extract (rtx ops[]); -extern void spu_builtin_insert (rtx ops[]); -extern void spu_builtin_promote (rtx ops[]); -extern void spu_expand_sign_extend (rtx ops[]); -extern void spu_expand_vector_init (rtx target, rtx vals); -extern rtx spu_legitimize_reload_address (rtx, machine_mode, int, int); -extern void spu_expand_atomic_op (enum rtx_code code, rtx mem, rtx val, - rtx orig_before, rtx orig_after); -#endif /* RTX_CODE */ - -extern void spu_init_expanders (void); -extern void spu_split_convert (rtx *); -extern void spu_function_profiler (FILE *, int); - -/* spu-c.c */ -extern tree spu_resolve_overloaded_builtin (location_t, tree fndecl, - void *fnargs); -extern rtx spu_expand_builtin (tree exp, rtx target, rtx subtarget, - machine_mode mode, int ignore); -extern rtx spu_expand_builtin (tree, rtx, rtx, machine_mode, int); - -#endif /* _SPU_PROTOS_ */ - diff --git a/gcc/config/spu/spu.c b/gcc/config/spu/spu.c deleted file mode 100644 index 7afd43b..0000000 --- a/gcc/config/spu/spu.c +++ /dev/null @@ -1,7469 +0,0 @@ -/* Copyright (C) 2006-2019 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - . */ - -#define IN_TARGET_CODE 1 - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "backend.h" -#include "target.h" -#include "rtl.h" -#include "tree.h" -#include "gimple.h" -#include "cfghooks.h" -#include "cfgloop.h" -#include "df.h" -#include "memmodel.h" -#include "tm_p.h" -#include "stringpool.h" -#include "attribs.h" -#include "expmed.h" -#include "optabs.h" -#include "regs.h" -#include "emit-rtl.h" -#include "recog.h" -#include "diagnostic-core.h" -#include "insn-attr.h" -#include "alias.h" -#include "fold-const.h" -#include "stor-layout.h" -#include "calls.h" -#include "varasm.h" -#include "explow.h" -#include "expr.h" -#include "output.h" -#include "cfgrtl.h" -#include "cfgbuild.h" -#include "langhooks.h" -#include "reload.h" -#include "sched-int.h" -#include "params.h" -#include "gimplify.h" -#include "tm-constrs.h" -#include "ddg.h" -#include "dumpfile.h" -#include "builtins.h" -#include "rtl-iter.h" -#include "flags.h" -#include "toplev.h" - -/* This file should be included last. */ -#include "target-def.h" - -/* Builtin types, data and prototypes. */ - -enum spu_builtin_type_index -{ - SPU_BTI_END_OF_PARAMS, - - /* We create new type nodes for these. */ - SPU_BTI_V16QI, - SPU_BTI_V8HI, - SPU_BTI_V4SI, - SPU_BTI_V2DI, - SPU_BTI_V4SF, - SPU_BTI_V2DF, - SPU_BTI_UV16QI, - SPU_BTI_UV8HI, - SPU_BTI_UV4SI, - SPU_BTI_UV2DI, - - /* A 16-byte type. (Implemented with V16QI_type_node) */ - SPU_BTI_QUADWORD, - - /* These all correspond to intSI_type_node */ - SPU_BTI_7, - SPU_BTI_S7, - SPU_BTI_U7, - SPU_BTI_S10, - SPU_BTI_S10_4, - SPU_BTI_U14, - SPU_BTI_16, - SPU_BTI_S16, - SPU_BTI_S16_2, - SPU_BTI_U16, - SPU_BTI_U16_2, - SPU_BTI_U18, - - /* These correspond to the standard types */ - SPU_BTI_INTQI, - SPU_BTI_INTHI, - SPU_BTI_INTSI, - SPU_BTI_INTDI, - - SPU_BTI_UINTQI, - SPU_BTI_UINTHI, - SPU_BTI_UINTSI, - SPU_BTI_UINTDI, - - SPU_BTI_FLOAT, - SPU_BTI_DOUBLE, - - SPU_BTI_VOID, - SPU_BTI_PTR, - - SPU_BTI_MAX -}; - -#define V16QI_type_node (spu_builtin_types[SPU_BTI_V16QI]) -#define V8HI_type_node (spu_builtin_types[SPU_BTI_V8HI]) -#define V4SI_type_node (spu_builtin_types[SPU_BTI_V4SI]) -#define V2DI_type_node (spu_builtin_types[SPU_BTI_V2DI]) -#define V4SF_type_node (spu_builtin_types[SPU_BTI_V4SF]) -#define V2DF_type_node (spu_builtin_types[SPU_BTI_V2DF]) -#define unsigned_V16QI_type_node (spu_builtin_types[SPU_BTI_UV16QI]) -#define unsigned_V8HI_type_node (spu_builtin_types[SPU_BTI_UV8HI]) -#define unsigned_V4SI_type_node (spu_builtin_types[SPU_BTI_UV4SI]) -#define unsigned_V2DI_type_node (spu_builtin_types[SPU_BTI_UV2DI]) - -static GTY(()) tree spu_builtin_types[SPU_BTI_MAX]; - -struct spu_builtin_range -{ - int low, high; -}; - -static struct spu_builtin_range spu_builtin_range[] = { - {-0x40ll, 0x7fll}, /* SPU_BTI_7 */ - {-0x40ll, 0x3fll}, /* SPU_BTI_S7 */ - {0ll, 0x7fll}, /* SPU_BTI_U7 */ - {-0x200ll, 0x1ffll}, /* SPU_BTI_S10 */ - {-0x2000ll, 0x1fffll}, /* SPU_BTI_S10_4 */ - {0ll, 0x3fffll}, /* SPU_BTI_U14 */ - {-0x8000ll, 0xffffll}, /* SPU_BTI_16 */ - {-0x8000ll, 0x7fffll}, /* SPU_BTI_S16 */ - {-0x20000ll, 0x1ffffll}, /* SPU_BTI_S16_2 */ - {0ll, 0xffffll}, /* SPU_BTI_U16 */ - {0ll, 0x3ffffll}, /* SPU_BTI_U16_2 */ - {0ll, 0x3ffffll}, /* SPU_BTI_U18 */ -}; - - -/* Target specific attribute specifications. */ -char regs_ever_allocated[FIRST_PSEUDO_REGISTER]; - -/* Prototypes and external defs. */ -static int get_pipe (rtx_insn *insn); -static int spu_naked_function_p (tree func); -static int mem_is_padded_component_ref (rtx x); -static void fix_range (const char *); -static rtx spu_expand_load (rtx, rtx, rtx, int); - -/* Which instruction set architecture to use. */ -int spu_arch; -/* Which cpu are we tuning for. */ -int spu_tune; - -/* The hardware requires 8 insns between a hint and the branch it - effects. This variable describes how many rtl instructions the - compiler needs to see before inserting a hint, and then the compiler - will insert enough nops to make it at least 8 insns. The default is - for the compiler to allow up to 2 nops be emitted. The nops are - inserted in pairs, so we round down. */ -int spu_hint_dist = (8*4) - (2*4); - -enum spu_immediate { - SPU_NONE, - SPU_IL, - SPU_ILA, - SPU_ILH, - SPU_ILHU, - SPU_ORI, - SPU_ORHI, - SPU_ORBI, - SPU_IOHL -}; -enum immediate_class -{ - IC_POOL, /* constant pool */ - IC_IL1, /* one il* instruction */ - IC_IL2, /* both ilhu and iohl instructions */ - IC_IL1s, /* one il* instruction */ - IC_IL2s, /* both ilhu and iohl instructions */ - IC_FSMBI, /* the fsmbi instruction */ - IC_CPAT, /* one of the c*d instructions */ - IC_FSMBI2 /* fsmbi plus 1 other instruction */ -}; - -static enum spu_immediate which_immediate_load (HOST_WIDE_INT val); -static enum spu_immediate which_logical_immediate (HOST_WIDE_INT val); -static int cpat_info(unsigned char *arr, int size, int *prun, int *pstart); -static enum immediate_class classify_immediate (rtx op, - machine_mode mode); - -/* Pointer mode for __ea references. */ -#define EAmode (spu_ea_model != 32 ? DImode : SImode) - - -/* Define the structure for the machine field in struct function. */ -struct GTY(()) machine_function -{ - /* Register to use for PIC accesses. */ - rtx pic_reg; -}; - -/* How to allocate a 'struct machine_function'. */ -static struct machine_function * -spu_init_machine_status (void) -{ - return ggc_cleared_alloc (); -} - -/* Implement TARGET_OPTION_OVERRIDE. */ -static void -spu_option_override (void) -{ - /* Set up function hooks. */ - init_machine_status = spu_init_machine_status; - - /* Small loops will be unpeeled at -O3. For SPU it is more important - to keep code small by default. */ - if (!flag_unroll_loops && !flag_peel_loops) - maybe_set_param_value (PARAM_MAX_COMPLETELY_PEEL_TIMES, 4, - global_options.x_param_values, - global_options_set.x_param_values); - - flag_omit_frame_pointer = 1; - - /* Functions must be 8 byte aligned so we correctly handle dual issue */ - parse_alignment_opts (); - if (align_functions.levels[0].get_value () < 8) - str_align_functions = "8"; - - spu_hint_dist = 8*4 - spu_max_nops*4; - if (spu_hint_dist < 0) - spu_hint_dist = 0; - - if (spu_fixed_range_string) - fix_range (spu_fixed_range_string); - - /* Determine processor architectural level. */ - if (spu_arch_string) - { - if (strcmp (&spu_arch_string[0], "cell") == 0) - spu_arch = PROCESSOR_CELL; - else if (strcmp (&spu_arch_string[0], "celledp") == 0) - spu_arch = PROCESSOR_CELLEDP; - else - error ("bad value (%s) for %<-march=%> switch", spu_arch_string); - } - - /* Determine processor to tune for. */ - if (spu_tune_string) - { - if (strcmp (&spu_tune_string[0], "cell") == 0) - spu_tune = PROCESSOR_CELL; - else if (strcmp (&spu_tune_string[0], "celledp") == 0) - spu_tune = PROCESSOR_CELLEDP; - else - error ("bad value (%s) for %<-mtune=%> switch", spu_tune_string); - } - - /* Change defaults according to the processor architecture. */ - if (spu_arch == PROCESSOR_CELLEDP) - { - /* If no command line option has been otherwise specified, change - the default to -mno-safe-hints on celledp -- only the original - Cell/B.E. processors require this workaround. */ - if (!(target_flags_explicit & MASK_SAFE_HINTS)) - target_flags &= ~MASK_SAFE_HINTS; - } - - REAL_MODE_FORMAT (SFmode) = &spu_single_format; -} - -/* Implement TARGET_HARD_REGNO_NREGS. */ - -static unsigned int -spu_hard_regno_nregs (unsigned int, machine_mode mode) -{ - return CEIL (GET_MODE_BITSIZE (mode), MAX_FIXED_MODE_SIZE); -} - -/* Handle an attribute requiring a FUNCTION_DECL; arguments as in - struct attribute_spec.handler. */ - -/* True if MODE is valid for the target. By "valid", we mean able to - be manipulated in non-trivial ways. In particular, this means all - the arithmetic is supported. */ -static bool -spu_scalar_mode_supported_p (scalar_mode mode) -{ - switch (mode) - { - case E_QImode: - case E_HImode: - case E_SImode: - case E_SFmode: - case E_DImode: - case E_TImode: - case E_DFmode: - return true; - - default: - return false; - } -} - -/* Similarly for vector modes. "Supported" here is less strict. At - least some operations are supported; need to check optabs or builtins - for further details. */ -static bool -spu_vector_mode_supported_p (machine_mode mode) -{ - switch (mode) - { - case E_V16QImode: - case E_V8HImode: - case E_V4SImode: - case E_V2DImode: - case E_V4SFmode: - case E_V2DFmode: - return true; - - default: - return false; - } -} - -/* GCC assumes that in a paradoxical SUBREG the inner mode occupies the - least significant bytes of the outer mode. This function returns - TRUE for the SUBREG's where this is correct. */ -int -valid_subreg (rtx op) -{ - machine_mode om = GET_MODE (op); - machine_mode im = GET_MODE (SUBREG_REG (op)); - return om != VOIDmode && im != VOIDmode - && (GET_MODE_SIZE (im) == GET_MODE_SIZE (om) - || (GET_MODE_SIZE (im) <= 4 && GET_MODE_SIZE (om) <= 4) - || (GET_MODE_SIZE (im) >= 16 && GET_MODE_SIZE (om) >= 16)); -} - -/* When insv and ext[sz]v ar passed a TI SUBREG, we want to strip it off - and adjust the start offset. */ -static rtx -adjust_operand (rtx op, HOST_WIDE_INT * start) -{ - machine_mode mode; - int op_size; - /* Strip any paradoxical SUBREG. */ - if (GET_CODE (op) == SUBREG - && (GET_MODE_BITSIZE (GET_MODE (op)) - > GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op))))) - { - if (start) - *start -= - GET_MODE_BITSIZE (GET_MODE (op)) - - GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op))); - op = SUBREG_REG (op); - } - /* If it is smaller than SI, assure a SUBREG */ - op_size = GET_MODE_BITSIZE (GET_MODE (op)); - if (op_size < 32) - { - if (start) - *start += 32 - op_size; - op_size = 32; - } - /* If it is not a MODE_INT (and/or it is smaller than SI) add a SUBREG. */ - mode = int_mode_for_size (op_size, 0).require (); - if (mode != GET_MODE (op)) - op = gen_rtx_SUBREG (mode, op, 0); - return op; -} - -void -spu_expand_extv (rtx ops[], int unsignedp) -{ - rtx dst = ops[0], src = ops[1]; - HOST_WIDE_INT width = INTVAL (ops[2]); - HOST_WIDE_INT start = INTVAL (ops[3]); - HOST_WIDE_INT align_mask; - rtx s0, s1, mask, r0; - - gcc_assert (REG_P (dst) && GET_MODE (dst) == TImode); - - if (MEM_P (src)) - { - /* First, determine if we need 1 TImode load or 2. We need only 1 - if the bits being extracted do not cross the alignment boundary - as determined by the MEM and its address. */ - - align_mask = -MEM_ALIGN (src); - if ((start & align_mask) == ((start + width - 1) & align_mask)) - { - /* Alignment is sufficient for 1 load. */ - s0 = gen_reg_rtx (TImode); - r0 = spu_expand_load (s0, 0, src, start / 8); - start &= 7; - if (r0) - emit_insn (gen_rotqby_ti (s0, s0, r0)); - } - else - { - /* Need 2 loads. */ - s0 = gen_reg_rtx (TImode); - s1 = gen_reg_rtx (TImode); - r0 = spu_expand_load (s0, s1, src, start / 8); - start &= 7; - - gcc_assert (start + width <= 128); - if (r0) - { - rtx r1 = gen_reg_rtx (SImode); - mask = gen_reg_rtx (TImode); - emit_move_insn (mask, GEN_INT (-1)); - emit_insn (gen_rotqby_ti (s0, s0, r0)); - emit_insn (gen_rotqby_ti (s1, s1, r0)); - if (GET_CODE (r0) == CONST_INT) - r1 = GEN_INT (INTVAL (r0) & 15); - else - emit_insn (gen_andsi3 (r1, r0, GEN_INT (15))); - emit_insn (gen_shlqby_ti (mask, mask, r1)); - emit_insn (gen_selb (s0, s1, s0, mask)); - } - } - - } - else if (GET_CODE (src) == SUBREG) - { - rtx r = SUBREG_REG (src); - gcc_assert (REG_P (r) && SCALAR_INT_MODE_P (GET_MODE (r))); - s0 = gen_reg_rtx (TImode); - if (GET_MODE_SIZE (GET_MODE (r)) < GET_MODE_SIZE (TImode)) - emit_insn (gen_rtx_SET (s0, gen_rtx_ZERO_EXTEND (TImode, r))); - else - emit_move_insn (s0, src); - } - else - { - gcc_assert (REG_P (src) && GET_MODE (src) == TImode); - s0 = gen_reg_rtx (TImode); - emit_move_insn (s0, src); - } - - /* Now s0 is TImode and contains the bits to extract at start. */ - - if (start) - emit_insn (gen_rotlti3 (s0, s0, GEN_INT (start))); - - if (128 - width) - s0 = expand_shift (RSHIFT_EXPR, TImode, s0, 128 - width, s0, unsignedp); - - emit_move_insn (dst, s0); -} - -void -spu_expand_insv (rtx ops[]) -{ - HOST_WIDE_INT width = INTVAL (ops[1]); - HOST_WIDE_INT start = INTVAL (ops[2]); - unsigned HOST_WIDE_INT maskbits; - machine_mode dst_mode; - rtx dst = ops[0], src = ops[3]; - int dst_size; - rtx mask; - rtx shift_reg; - int shift; - - - if (GET_CODE (ops[0]) == MEM) - dst = gen_reg_rtx (TImode); - else - dst = adjust_operand (dst, &start); - dst_mode = GET_MODE (dst); - dst_size = GET_MODE_BITSIZE (GET_MODE (dst)); - - if (CONSTANT_P (src)) - { - machine_mode m = - (width <= 32 ? SImode : width <= 64 ? DImode : TImode); - src = force_reg (m, convert_to_mode (m, src, 0)); - } - src = adjust_operand (src, 0); - - mask = gen_reg_rtx (dst_mode); - shift_reg = gen_reg_rtx (dst_mode); - shift = dst_size - start - width; - - /* It's not safe to use subreg here because the compiler assumes - that the SUBREG_REG is right justified in the SUBREG. */ - convert_move (shift_reg, src, 1); - - if (shift > 0) - { - switch (dst_mode) - { - case E_SImode: - emit_insn (gen_ashlsi3 (shift_reg, shift_reg, GEN_INT (shift))); - break; - case E_DImode: - emit_insn (gen_ashldi3 (shift_reg, shift_reg, GEN_INT (shift))); - break; - case E_TImode: - emit_insn (gen_ashlti3 (shift_reg, shift_reg, GEN_INT (shift))); - break; - default: - abort (); - } - } - else if (shift < 0) - abort (); - - switch (dst_size) - { - case 32: - maskbits = (~(unsigned HOST_WIDE_INT)0 << (32 - width - start)); - if (start) - maskbits += ((unsigned HOST_WIDE_INT)1 << (32 - start)); - emit_move_insn (mask, GEN_INT (maskbits)); - break; - case 64: - maskbits = (~(unsigned HOST_WIDE_INT)0 << (64 - width - start)); - if (start) - maskbits += ((unsigned HOST_WIDE_INT)1 << (64 - start)); - emit_move_insn (mask, GEN_INT (maskbits)); - break; - case 128: - { - unsigned char arr[16]; - int i = start / 8; - memset (arr, 0, sizeof (arr)); - arr[i] = 0xff >> (start & 7); - for (i++; i <= (start + width - 1) / 8; i++) - arr[i] = 0xff; - arr[i - 1] &= 0xff << (7 - ((start + width - 1) & 7)); - emit_move_insn (mask, array_to_constant (TImode, arr)); - } - break; - default: - abort (); - } - if (GET_CODE (ops[0]) == MEM) - { - rtx low = gen_reg_rtx (SImode); - rtx rotl = gen_reg_rtx (SImode); - rtx mask0 = gen_reg_rtx (TImode); - rtx addr; - rtx addr0; - rtx addr1; - rtx mem; - - addr = force_reg (Pmode, XEXP (ops[0], 0)); - addr0 = gen_rtx_AND (Pmode, addr, GEN_INT (-16)); - emit_insn (gen_andsi3 (low, addr, GEN_INT (15))); - emit_insn (gen_negsi2 (rotl, low)); - emit_insn (gen_rotqby_ti (shift_reg, shift_reg, rotl)); - emit_insn (gen_rotqmby_ti (mask0, mask, rotl)); - mem = change_address (ops[0], TImode, addr0); - set_mem_alias_set (mem, 0); - emit_move_insn (dst, mem); - emit_insn (gen_selb (dst, dst, shift_reg, mask0)); - if (start + width > MEM_ALIGN (ops[0])) - { - rtx shl = gen_reg_rtx (SImode); - rtx mask1 = gen_reg_rtx (TImode); - rtx dst1 = gen_reg_rtx (TImode); - rtx mem1; - addr1 = plus_constant (Pmode, addr, 16); - addr1 = gen_rtx_AND (Pmode, addr1, GEN_INT (-16)); - emit_insn (gen_subsi3 (shl, GEN_INT (16), low)); - emit_insn (gen_shlqby_ti (mask1, mask, shl)); - mem1 = change_address (ops[0], TImode, addr1); - set_mem_alias_set (mem1, 0); - emit_move_insn (dst1, mem1); - emit_insn (gen_selb (dst1, dst1, shift_reg, mask1)); - emit_move_insn (mem1, dst1); - } - emit_move_insn (mem, dst); - } - else - emit_insn (gen_selb (dst, copy_rtx (dst), shift_reg, mask)); -} - - -int -spu_expand_block_move (rtx ops[]) -{ - HOST_WIDE_INT bytes, align, offset; - rtx src, dst, sreg, dreg, target; - int i; - if (GET_CODE (ops[2]) != CONST_INT - || GET_CODE (ops[3]) != CONST_INT - || INTVAL (ops[2]) > (HOST_WIDE_INT) (MOVE_RATIO (optimize_insn_for_speed_p ()) * 8)) - return 0; - - bytes = INTVAL (ops[2]); - align = INTVAL (ops[3]); - - if (bytes <= 0) - return 1; - - dst = ops[0]; - src = ops[1]; - - if (align == 16) - { - for (offset = 0; offset + 16 <= bytes; offset += 16) - { - dst = adjust_address (ops[0], V16QImode, offset); - src = adjust_address (ops[1], V16QImode, offset); - emit_move_insn (dst, src); - } - if (offset < bytes) - { - rtx mask; - unsigned char arr[16] = { 0 }; - for (i = 0; i < bytes - offset; i++) - arr[i] = 0xff; - dst = adjust_address (ops[0], V16QImode, offset); - src = adjust_address (ops[1], V16QImode, offset); - mask = gen_reg_rtx (V16QImode); - sreg = gen_reg_rtx (V16QImode); - dreg = gen_reg_rtx (V16QImode); - target = gen_reg_rtx (V16QImode); - emit_move_insn (mask, array_to_constant (V16QImode, arr)); - emit_move_insn (dreg, dst); - emit_move_insn (sreg, src); - emit_insn (gen_selb (target, dreg, sreg, mask)); - emit_move_insn (dst, target); - } - return 1; - } - return 0; -} - -enum spu_comp_code -{ SPU_EQ, SPU_GT, SPU_GTU }; - -int spu_comp_icode[12][3] = { - {CODE_FOR_ceq_qi, CODE_FOR_cgt_qi, CODE_FOR_clgt_qi}, - {CODE_FOR_ceq_hi, CODE_FOR_cgt_hi, CODE_FOR_clgt_hi}, - {CODE_FOR_ceq_si, CODE_FOR_cgt_si, CODE_FOR_clgt_si}, - {CODE_FOR_ceq_di, CODE_FOR_cgt_di, CODE_FOR_clgt_di}, - {CODE_FOR_ceq_ti, CODE_FOR_cgt_ti, CODE_FOR_clgt_ti}, - {CODE_FOR_ceq_sf, CODE_FOR_cgt_sf, 0}, - {CODE_FOR_ceq_df, CODE_FOR_cgt_df, 0}, - {CODE_FOR_ceq_v16qi, CODE_FOR_cgt_v16qi, CODE_FOR_clgt_v16qi}, - {CODE_FOR_ceq_v8hi, CODE_FOR_cgt_v8hi, CODE_FOR_clgt_v8hi}, - {CODE_FOR_ceq_v4si, CODE_FOR_cgt_v4si, CODE_FOR_clgt_v4si}, - {CODE_FOR_ceq_v4sf, CODE_FOR_cgt_v4sf, 0}, - {CODE_FOR_ceq_v2df, CODE_FOR_cgt_v2df, 0}, -}; - -/* Generate a compare for CODE. Return a brand-new rtx that represents - the result of the compare. GCC can figure this out too if we don't - provide all variations of compares, but GCC always wants to use - WORD_MODE, we can generate better code in most cases if we do it - ourselves. */ -void -spu_emit_branch_or_set (int is_set, rtx cmp, rtx operands[]) -{ - int reverse_compare = 0; - int reverse_test = 0; - rtx compare_result, eq_result; - rtx comp_rtx, eq_rtx; - machine_mode comp_mode; - machine_mode op_mode; - enum spu_comp_code scode, eq_code; - enum insn_code ior_code; - enum rtx_code code = GET_CODE (cmp); - rtx op0 = XEXP (cmp, 0); - rtx op1 = XEXP (cmp, 1); - int index; - int eq_test = 0; - - /* When op1 is a CONST_INT change (X >= C) to (X > C-1), - and so on, to keep the constant in operand 1. */ - if (GET_CODE (op1) == CONST_INT) - { - HOST_WIDE_INT val = INTVAL (op1) - 1; - if (trunc_int_for_mode (val, GET_MODE (op0)) == val) - switch (code) - { - case GE: - op1 = GEN_INT (val); - code = GT; - break; - case LT: - op1 = GEN_INT (val); - code = LE; - break; - case GEU: - op1 = GEN_INT (val); - code = GTU; - break; - case LTU: - op1 = GEN_INT (val); - code = LEU; - break; - default: - break; - } - } - - /* However, if we generate an integer result, performing a reverse test - would require an extra negation, so avoid that where possible. */ - if (GET_CODE (op1) == CONST_INT && is_set == 1) - { - HOST_WIDE_INT val = INTVAL (op1) + 1; - if (trunc_int_for_mode (val, GET_MODE (op0)) == val) - switch (code) - { - case LE: - op1 = GEN_INT (val); - code = LT; - break; - case LEU: - op1 = GEN_INT (val); - code = LTU; - break; - default: - break; - } - } - - comp_mode = SImode; - op_mode = GET_MODE (op0); - - switch (code) - { - case GE: - scode = SPU_GT; - if (HONOR_NANS (op_mode)) - { - reverse_compare = 0; - reverse_test = 0; - eq_test = 1; - eq_code = SPU_EQ; - } - else - { - reverse_compare = 1; - reverse_test = 1; - } - break; - case LE: - scode = SPU_GT; - if (HONOR_NANS (op_mode)) - { - reverse_compare = 1; - reverse_test = 0; - eq_test = 1; - eq_code = SPU_EQ; - } - else - { - reverse_compare = 0; - reverse_test = 1; - } - break; - case LT: - reverse_compare = 1; - reverse_test = 0; - scode = SPU_GT; - break; - case GEU: - reverse_compare = 1; - reverse_test = 1; - scode = SPU_GTU; - break; - case LEU: - reverse_compare = 0; - reverse_test = 1; - scode = SPU_GTU; - break; - case LTU: - reverse_compare = 1; - reverse_test = 0; - scode = SPU_GTU; - break; - case NE: - reverse_compare = 0; - reverse_test = 1; - scode = SPU_EQ; - break; - - case EQ: - scode = SPU_EQ; - break; - case GT: - scode = SPU_GT; - break; - case GTU: - scode = SPU_GTU; - break; - default: - scode = SPU_EQ; - break; - } - - switch (op_mode) - { - case E_QImode: - index = 0; - comp_mode = QImode; - break; - case E_HImode: - index = 1; - comp_mode = HImode; - break; - case E_SImode: - index = 2; - break; - case E_DImode: - index = 3; - break; - case E_TImode: - index = 4; - break; - case E_SFmode: - index = 5; - break; - case E_DFmode: - index = 6; - break; - case E_V16QImode: - index = 7; - comp_mode = op_mode; - break; - case E_V8HImode: - index = 8; - comp_mode = op_mode; - break; - case E_V4SImode: - index = 9; - comp_mode = op_mode; - break; - case E_V4SFmode: - index = 10; - comp_mode = V4SImode; - break; - case E_V2DFmode: - index = 11; - comp_mode = V2DImode; - break; - case E_V2DImode: - default: - abort (); - } - - if (GET_MODE (op1) == DFmode - && (scode != SPU_GT && scode != SPU_EQ)) - abort (); - - if (is_set == 0 && op1 == const0_rtx - && (GET_MODE (op0) == SImode - || GET_MODE (op0) == HImode - || GET_MODE (op0) == QImode) && scode == SPU_EQ) - { - /* Don't need to set a register with the result when we are - comparing against zero and branching. */ - reverse_test = !reverse_test; - compare_result = op0; - } - else - { - compare_result = gen_reg_rtx (comp_mode); - - if (reverse_compare) - { - rtx t = op1; - op1 = op0; - op0 = t; - } - - if (spu_comp_icode[index][scode] == 0) - abort (); - - if (!(*insn_data[spu_comp_icode[index][scode]].operand[1].predicate) - (op0, op_mode)) - op0 = force_reg (op_mode, op0); - if (!(*insn_data[spu_comp_icode[index][scode]].operand[2].predicate) - (op1, op_mode)) - op1 = force_reg (op_mode, op1); - comp_rtx = GEN_FCN (spu_comp_icode[index][scode]) (compare_result, - op0, op1); - if (comp_rtx == 0) - abort (); - emit_insn (comp_rtx); - - if (eq_test) - { - eq_result = gen_reg_rtx (comp_mode); - eq_rtx = GEN_FCN (spu_comp_icode[index][eq_code]) (eq_result, - op0, op1); - if (eq_rtx == 0) - abort (); - emit_insn (eq_rtx); - ior_code = optab_handler (ior_optab, comp_mode); - gcc_assert (ior_code != CODE_FOR_nothing); - emit_insn (GEN_FCN (ior_code) - (compare_result, compare_result, eq_result)); - } - } - - if (is_set == 0) - { - rtx bcomp; - rtx loc_ref; - - /* We don't have branch on QI compare insns, so we convert the - QI compare result to a HI result. */ - if (comp_mode == QImode) - { - rtx old_res = compare_result; - compare_result = gen_reg_rtx (HImode); - comp_mode = HImode; - emit_insn (gen_extendqihi2 (compare_result, old_res)); - } - - if (reverse_test) - bcomp = gen_rtx_EQ (comp_mode, compare_result, const0_rtx); - else - bcomp = gen_rtx_NE (comp_mode, compare_result, const0_rtx); - - loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]); - emit_jump_insn (gen_rtx_SET (pc_rtx, - gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp, - loc_ref, pc_rtx))); - } - else if (is_set == 2) - { - rtx target = operands[0]; - int compare_size = GET_MODE_BITSIZE (comp_mode); - int target_size = GET_MODE_BITSIZE (GET_MODE (target)); - machine_mode mode = int_mode_for_size (target_size, 0).require (); - rtx select_mask; - rtx op_t = operands[2]; - rtx op_f = operands[3]; - - /* The result of the comparison can be SI, HI or QI mode. Create a - mask based on that result. */ - if (target_size > compare_size) - { - select_mask = gen_reg_rtx (mode); - emit_insn (gen_extend_compare (select_mask, compare_result)); - } - else if (target_size < compare_size) - select_mask = - gen_rtx_SUBREG (mode, compare_result, - (compare_size - target_size) / BITS_PER_UNIT); - else if (comp_mode != mode) - select_mask = gen_rtx_SUBREG (mode, compare_result, 0); - else - select_mask = compare_result; - - if (GET_MODE (target) != GET_MODE (op_t) - || GET_MODE (target) != GET_MODE (op_f)) - abort (); - - if (reverse_test) - emit_insn (gen_selb (target, op_t, op_f, select_mask)); - else - emit_insn (gen_selb (target, op_f, op_t, select_mask)); - } - else - { - rtx target = operands[0]; - if (reverse_test) - emit_insn (gen_rtx_SET (compare_result, - gen_rtx_NOT (comp_mode, compare_result))); - if (GET_MODE (target) == SImode && GET_MODE (compare_result) == HImode) - emit_insn (gen_extendhisi2 (target, compare_result)); - else if (GET_MODE (target) == SImode - && GET_MODE (compare_result) == QImode) - emit_insn (gen_extend_compare (target, compare_result)); - else - emit_move_insn (target, compare_result); - } -} - -HOST_WIDE_INT -const_double_to_hwint (rtx x) -{ - HOST_WIDE_INT val; - if (GET_MODE (x) == SFmode) - REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), val); - else if (GET_MODE (x) == DFmode) - { - long l[2]; - REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (x), l); - val = l[0]; - val = (val << 32) | (l[1] & 0xffffffff); - } - else - abort (); - return val; -} - -rtx -hwint_to_const_double (machine_mode mode, HOST_WIDE_INT v) -{ - long tv[2]; - REAL_VALUE_TYPE rv; - gcc_assert (mode == SFmode || mode == DFmode); - - if (mode == SFmode) - tv[0] = (v << 32) >> 32; - else if (mode == DFmode) - { - tv[1] = (v << 32) >> 32; - tv[0] = v >> 32; - } - real_from_target (&rv, tv, mode); - return const_double_from_real_value (rv, mode); -} - -void -print_operand_address (FILE * file, register rtx addr) -{ - rtx reg; - rtx offset; - - if (GET_CODE (addr) == AND - && GET_CODE (XEXP (addr, 1)) == CONST_INT - && INTVAL (XEXP (addr, 1)) == -16) - addr = XEXP (addr, 0); - - switch (GET_CODE (addr)) - { - case REG: - fprintf (file, "0(%s)", reg_names[REGNO (addr)]); - break; - - case PLUS: - reg = XEXP (addr, 0); - offset = XEXP (addr, 1); - if (GET_CODE (offset) == REG) - { - fprintf (file, "%s,%s", reg_names[REGNO (reg)], - reg_names[REGNO (offset)]); - } - else if (GET_CODE (offset) == CONST_INT) - { - fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)", - INTVAL (offset), reg_names[REGNO (reg)]); - } - else - abort (); - break; - - case CONST: - case LABEL_REF: - case SYMBOL_REF: - case CONST_INT: - output_addr_const (file, addr); - break; - - default: - debug_rtx (addr); - abort (); - } -} - -void -print_operand (FILE * file, rtx x, int code) -{ - machine_mode mode = GET_MODE (x); - HOST_WIDE_INT val; - unsigned char arr[16]; - int xcode = GET_CODE (x); - int i, info; - if (GET_MODE (x) == VOIDmode) - switch (code) - { - case 'L': /* 128 bits, signed */ - case 'm': /* 128 bits, signed */ - case 'T': /* 128 bits, signed */ - case 't': /* 128 bits, signed */ - mode = TImode; - break; - case 'K': /* 64 bits, signed */ - case 'k': /* 64 bits, signed */ - case 'D': /* 64 bits, signed */ - case 'd': /* 64 bits, signed */ - mode = DImode; - break; - case 'J': /* 32 bits, signed */ - case 'j': /* 32 bits, signed */ - case 's': /* 32 bits, signed */ - case 'S': /* 32 bits, signed */ - mode = SImode; - break; - } - switch (code) - { - - case 'j': /* 32 bits, signed */ - case 'k': /* 64 bits, signed */ - case 'm': /* 128 bits, signed */ - if (xcode == CONST_INT - || xcode == CONST_DOUBLE || xcode == CONST_VECTOR) - { - gcc_assert (logical_immediate_p (x, mode)); - constant_to_array (mode, x, arr); - val = (arr[0] << 24) | (arr[1] << 16) | (arr[2] << 8) | arr[3]; - val = trunc_int_for_mode (val, SImode); - switch (which_logical_immediate (val)) - { - case SPU_ORI: - break; - case SPU_ORHI: - fprintf (file, "h"); - break; - case SPU_ORBI: - fprintf (file, "b"); - break; - default: - gcc_unreachable(); - } - } - else - gcc_unreachable(); - return; - - case 'J': /* 32 bits, signed */ - case 'K': /* 64 bits, signed */ - case 'L': /* 128 bits, signed */ - if (xcode == CONST_INT - || xcode == CONST_DOUBLE || xcode == CONST_VECTOR) - { - gcc_assert (logical_immediate_p (x, mode) - || iohl_immediate_p (x, mode)); - constant_to_array (mode, x, arr); - val = (arr[0] << 24) | (arr[1] << 16) | (arr[2] << 8) | arr[3]; - val = trunc_int_for_mode (val, SImode); - switch (which_logical_immediate (val)) - { - case SPU_ORI: - case SPU_IOHL: - break; - case SPU_ORHI: - val = trunc_int_for_mode (val, HImode); - break; - case SPU_ORBI: - val = trunc_int_for_mode (val, QImode); - break; - default: - gcc_unreachable(); - } - fprintf (file, HOST_WIDE_INT_PRINT_DEC, val); - } - else - gcc_unreachable(); - return; - - case 't': /* 128 bits, signed */ - case 'd': /* 64 bits, signed */ - case 's': /* 32 bits, signed */ - if (CONSTANT_P (x)) - { - enum immediate_class c = classify_immediate (x, mode); - switch (c) - { - case IC_IL1: - constant_to_array (mode, x, arr); - val = (arr[0] << 24) | (arr[1] << 16) | (arr[2] << 8) | arr[3]; - val = trunc_int_for_mode (val, SImode); - switch (which_immediate_load (val)) - { - case SPU_IL: - break; - case SPU_ILA: - fprintf (file, "a"); - break; - case SPU_ILH: - fprintf (file, "h"); - break; - case SPU_ILHU: - fprintf (file, "hu"); - break; - default: - gcc_unreachable (); - } - break; - case IC_CPAT: - constant_to_array (mode, x, arr); - cpat_info (arr, GET_MODE_SIZE (mode), &info, 0); - if (info == 1) - fprintf (file, "b"); - else if (info == 2) - fprintf (file, "h"); - else if (info == 4) - fprintf (file, "w"); - else if (info == 8) - fprintf (file, "d"); - break; - case IC_IL1s: - if (xcode == CONST_VECTOR) - { - x = CONST_VECTOR_ELT (x, 0); - xcode = GET_CODE (x); - } - if (xcode == SYMBOL_REF || xcode == LABEL_REF || xcode == CONST) - fprintf (file, "a"); - else if (xcode == HIGH) - fprintf (file, "hu"); - break; - case IC_FSMBI: - case IC_FSMBI2: - case IC_IL2: - case IC_IL2s: - case IC_POOL: - abort (); - } - } - else - gcc_unreachable (); - return; - - case 'T': /* 128 bits, signed */ - case 'D': /* 64 bits, signed */ - case 'S': /* 32 bits, signed */ - if (CONSTANT_P (x)) - { - enum immediate_class c = classify_immediate (x, mode); - switch (c) - { - case IC_IL1: - constant_to_array (mode, x, arr); - val = (arr[0] << 24) | (arr[1] << 16) | (arr[2] << 8) | arr[3]; - val = trunc_int_for_mode (val, SImode); - switch (which_immediate_load (val)) - { - case SPU_IL: - case SPU_ILA: - break; - case SPU_ILH: - case SPU_ILHU: - val = trunc_int_for_mode (((arr[0] << 8) | arr[1]), HImode); - break; - default: - gcc_unreachable (); - } - fprintf (file, HOST_WIDE_INT_PRINT_DEC, val); - break; - case IC_FSMBI: - constant_to_array (mode, x, arr); - val = 0; - for (i = 0; i < 16; i++) - { - val <<= 1; - val |= arr[i] & 1; - } - print_operand (file, GEN_INT (val), 0); - break; - case IC_CPAT: - constant_to_array (mode, x, arr); - cpat_info (arr, GET_MODE_SIZE (mode), 0, &info); - fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)info); - break; - case IC_IL1s: - if (xcode == HIGH) - x = XEXP (x, 0); - if (GET_CODE (x) == CONST_VECTOR) - x = CONST_VECTOR_ELT (x, 0); - output_addr_const (file, x); - if (xcode == HIGH) - fprintf (file, "@h"); - break; - case IC_IL2: - case IC_IL2s: - case IC_FSMBI2: - case IC_POOL: - abort (); - } - } - else - gcc_unreachable (); - return; - - case 'C': - if (xcode == CONST_INT) - { - /* Only 4 least significant bits are relevant for generate - control word instructions. */ - fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 15); - return; - } - break; - - case 'M': /* print code for c*d */ - if (GET_CODE (x) == CONST_INT) - switch (INTVAL (x)) - { - case 1: - fprintf (file, "b"); - break; - case 2: - fprintf (file, "h"); - break; - case 4: - fprintf (file, "w"); - break; - case 8: - fprintf (file, "d"); - break; - default: - gcc_unreachable(); - } - else - gcc_unreachable(); - return; - - case 'N': /* Negate the operand */ - if (xcode == CONST_INT) - fprintf (file, HOST_WIDE_INT_PRINT_DEC, -INTVAL (x)); - else if (xcode == CONST_VECTOR) - fprintf (file, HOST_WIDE_INT_PRINT_DEC, - -INTVAL (CONST_VECTOR_ELT (x, 0))); - return; - - case 'I': /* enable/disable interrupts */ - if (xcode == CONST_INT) - fprintf (file, "%s", INTVAL (x) == 0 ? "d" : "e"); - return; - - case 'b': /* branch modifiers */ - if (xcode == REG) - fprintf (file, "%s", GET_MODE (x) == HImode ? "h" : ""); - else if (COMPARISON_P (x)) - fprintf (file, "%s", xcode == NE ? "n" : ""); - return; - - case 'i': /* indirect call */ - if (xcode == MEM) - { - if (GET_CODE (XEXP (x, 0)) == REG) - /* Used in indirect function calls. */ - fprintf (file, "%s", reg_names[REGNO (XEXP (x, 0))]); - else - output_address (GET_MODE (x), XEXP (x, 0)); - } - return; - - case 'p': /* load/store */ - if (xcode == MEM) - { - x = XEXP (x, 0); - xcode = GET_CODE (x); - } - if (xcode == AND) - { - x = XEXP (x, 0); - xcode = GET_CODE (x); - } - if (xcode == REG) - fprintf (file, "d"); - else if (xcode == CONST_INT) - fprintf (file, "a"); - else if (xcode == CONST || xcode == SYMBOL_REF || xcode == LABEL_REF) - fprintf (file, "r"); - else if (xcode == PLUS || xcode == LO_SUM) - { - if (GET_CODE (XEXP (x, 1)) == REG) - fprintf (file, "x"); - else - fprintf (file, "d"); - } - return; - - case 'e': - val = xcode == CONST_INT ? INTVAL (x) : INTVAL (CONST_VECTOR_ELT (x, 0)); - val &= 0x7; - output_addr_const (file, GEN_INT (val)); - return; - - case 'f': - val = xcode == CONST_INT ? INTVAL (x) : INTVAL (CONST_VECTOR_ELT (x, 0)); - val &= 0x1f; - output_addr_const (file, GEN_INT (val)); - return; - - case 'g': - val = xcode == CONST_INT ? INTVAL (x) : INTVAL (CONST_VECTOR_ELT (x, 0)); - val &= 0x3f; - output_addr_const (file, GEN_INT (val)); - return; - - case 'h': - val = xcode == CONST_INT ? INTVAL (x) : INTVAL (CONST_VECTOR_ELT (x, 0)); - val = (val >> 3) & 0x1f; - output_addr_const (file, GEN_INT (val)); - return; - - case 'E': - val = xcode == CONST_INT ? INTVAL (x) : INTVAL (CONST_VECTOR_ELT (x, 0)); - val = -val; - val &= 0x7; - output_addr_const (file, GEN_INT (val)); - return; - - case 'F': - val = xcode == CONST_INT ? INTVAL (x) : INTVAL (CONST_VECTOR_ELT (x, 0)); - val = -val; - val &= 0x1f; - output_addr_const (file, GEN_INT (val)); - return; - - case 'G': - val = xcode == CONST_INT ? INTVAL (x) : INTVAL (CONST_VECTOR_ELT (x, 0)); - val = -val; - val &= 0x3f; - output_addr_const (file, GEN_INT (val)); - return; - - case 'H': - val = xcode == CONST_INT ? INTVAL (x) : INTVAL (CONST_VECTOR_ELT (x, 0)); - val = -(val & -8ll); - val = (val >> 3) & 0x1f; - output_addr_const (file, GEN_INT (val)); - return; - - case 'v': - case 'w': - constant_to_array (mode, x, arr); - val = (((arr[0] << 1) + (arr[1] >> 7)) & 0xff) - 127; - output_addr_const (file, GEN_INT (code == 'w' ? -val : val)); - return; - - case 0: - if (xcode == REG) - fprintf (file, "%s", reg_names[REGNO (x)]); - else if (xcode == MEM) - output_address (GET_MODE (x), XEXP (x, 0)); - else if (xcode == CONST_VECTOR) - print_operand (file, CONST_VECTOR_ELT (x, 0), 0); - else - output_addr_const (file, x); - return; - - /* unused letters - o qr u yz - AB OPQR UVWXYZ */ - default: - output_operand_lossage ("invalid %%xn code"); - } - gcc_unreachable (); -} - -/* For PIC mode we've reserved PIC_OFFSET_TABLE_REGNUM, which is a - caller saved register. For leaf functions it is more efficient to - use a volatile register because we won't need to save and restore the - pic register. This routine is only valid after register allocation - is completed, so we can pick an unused register. */ -static rtx -get_pic_reg (void) -{ - if (!reload_completed && !reload_in_progress) - abort (); - - /* If we've already made the decision, we need to keep with it. Once we've - decided to use LAST_ARG_REGNUM, future calls to df_regs_ever_live_p may - return true since the register is now live; this should not cause us to - "switch back" to using pic_offset_table_rtx. */ - if (!cfun->machine->pic_reg) - { - if (crtl->is_leaf && !df_regs_ever_live_p (LAST_ARG_REGNUM)) - cfun->machine->pic_reg = gen_rtx_REG (SImode, LAST_ARG_REGNUM); - else - cfun->machine->pic_reg = pic_offset_table_rtx; - } - - return cfun->machine->pic_reg; -} - -/* Split constant addresses to handle cases that are too large. - Add in the pic register when in PIC mode. - Split immediates that require more than 1 instruction. */ -int -spu_split_immediate (rtx * ops) -{ - machine_mode mode = GET_MODE (ops[0]); - enum immediate_class c = classify_immediate (ops[1], mode); - - switch (c) - { - case IC_IL2: - { - unsigned char arrhi[16]; - unsigned char arrlo[16]; - rtx to, temp, hi, lo; - int i; - /* We need to do reals as ints because the constant used in the - IOR might not be a legitimate real constant. */ - scalar_int_mode imode = int_mode_for_mode (mode).require (); - constant_to_array (mode, ops[1], arrhi); - if (imode != mode) - to = simplify_gen_subreg (imode, ops[0], mode, 0); - else - to = ops[0]; - temp = !can_create_pseudo_p () ? to : gen_reg_rtx (imode); - for (i = 0; i < 16; i += 4) - { - arrlo[i + 2] = arrhi[i + 2]; - arrlo[i + 3] = arrhi[i + 3]; - arrlo[i + 0] = arrlo[i + 1] = 0; - arrhi[i + 2] = arrhi[i + 3] = 0; - } - hi = array_to_constant (imode, arrhi); - lo = array_to_constant (imode, arrlo); - emit_move_insn (temp, hi); - emit_insn (gen_rtx_SET (to, gen_rtx_IOR (imode, temp, lo))); - return 1; - } - case IC_FSMBI2: - { - unsigned char arr_fsmbi[16]; - unsigned char arr_andbi[16]; - rtx to, reg_fsmbi, reg_and; - int i; - /* We need to do reals as ints because the constant used in the - * AND might not be a legitimate real constant. */ - scalar_int_mode imode = int_mode_for_mode (mode).require (); - constant_to_array (mode, ops[1], arr_fsmbi); - if (imode != mode) - to = simplify_gen_subreg(imode, ops[0], GET_MODE (ops[0]), 0); - else - to = ops[0]; - for (i = 0; i < 16; i++) - if (arr_fsmbi[i] != 0) - { - arr_andbi[0] = arr_fsmbi[i]; - arr_fsmbi[i] = 0xff; - } - for (i = 1; i < 16; i++) - arr_andbi[i] = arr_andbi[0]; - reg_fsmbi = array_to_constant (imode, arr_fsmbi); - reg_and = array_to_constant (imode, arr_andbi); - emit_move_insn (to, reg_fsmbi); - emit_insn (gen_rtx_SET (to, gen_rtx_AND (imode, to, reg_and))); - return 1; - } - case IC_POOL: - if (reload_in_progress || reload_completed) - { - rtx mem = force_const_mem (mode, ops[1]); - if (TARGET_LARGE_MEM) - { - rtx addr = gen_rtx_REG (Pmode, REGNO (ops[0])); - emit_move_insn (addr, XEXP (mem, 0)); - mem = replace_equiv_address (mem, addr); - } - emit_move_insn (ops[0], mem); - return 1; - } - break; - case IC_IL1s: - case IC_IL2s: - if (reload_completed && GET_CODE (ops[1]) != HIGH) - { - if (c == IC_IL2s) - { - emit_move_insn (ops[0], gen_rtx_HIGH (mode, ops[1])); - emit_move_insn (ops[0], gen_rtx_LO_SUM (mode, ops[0], ops[1])); - } - else if (flag_pic) - emit_insn (gen_pic (ops[0], ops[1])); - if (flag_pic) - { - rtx pic_reg = get_pic_reg (); - emit_insn (gen_addsi3 (ops[0], ops[0], pic_reg)); - } - return flag_pic || c == IC_IL2s; - } - break; - case IC_IL1: - case IC_FSMBI: - case IC_CPAT: - break; - } - return 0; -} - -/* SAVING is TRUE when we are generating the actual load and store - instructions for REGNO. When determining the size of the stack - needed for saving register we must allocate enough space for the - worst case, because we don't always have the information early enough - to not allocate it. But we can at least eliminate the actual loads - and stores during the prologue/epilogue. */ -static int -need_to_save_reg (int regno, int saving) -{ - if (df_regs_ever_live_p (regno) && !call_used_regs[regno]) - return 1; - if (flag_pic - && regno == PIC_OFFSET_TABLE_REGNUM - && (!saving || cfun->machine->pic_reg == pic_offset_table_rtx)) - return 1; - return 0; -} - -/* This function is only correct starting with local register - allocation */ -int -spu_saved_regs_size (void) -{ - int reg_save_size = 0; - int regno; - - for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; --regno) - if (need_to_save_reg (regno, 0)) - reg_save_size += 0x10; - return reg_save_size; -} - -static rtx_insn * -frame_emit_store (int regno, rtx addr, HOST_WIDE_INT offset) -{ - rtx reg = gen_rtx_REG (V4SImode, regno); - rtx mem = - gen_frame_mem (V4SImode, gen_rtx_PLUS (Pmode, addr, GEN_INT (offset))); - return emit_insn (gen_movv4si (mem, reg)); -} - -static rtx_insn * -frame_emit_load (int regno, rtx addr, HOST_WIDE_INT offset) -{ - rtx reg = gen_rtx_REG (V4SImode, regno); - rtx mem = - gen_frame_mem (V4SImode, gen_rtx_PLUS (Pmode, addr, GEN_INT (offset))); - return emit_insn (gen_movv4si (reg, mem)); -} - -/* This happens after reload, so we need to expand it. */ -static rtx_insn * -frame_emit_add_imm (rtx dst, rtx src, HOST_WIDE_INT imm, rtx scratch) -{ - rtx_insn *insn; - if (satisfies_constraint_K (GEN_INT (imm))) - { - insn = emit_insn (gen_addsi3 (dst, src, GEN_INT (imm))); - } - else - { - emit_insn (gen_movsi (scratch, gen_int_mode (imm, SImode))); - insn = emit_insn (gen_addsi3 (dst, src, scratch)); - if (REGNO (src) == REGNO (scratch)) - abort (); - } - return insn; -} - -/* Return nonzero if this function is known to have a null epilogue. */ - -int -direct_return (void) -{ - if (reload_completed) - { - if (cfun->static_chain_decl == 0 - && (spu_saved_regs_size () - + get_frame_size () - + crtl->outgoing_args_size - + crtl->args.pretend_args_size == 0) - && crtl->is_leaf) - return 1; - } - return 0; -} - -/* - The stack frame looks like this: - +-------------+ - | incoming | - | args | - AP -> +-------------+ - | $lr save | - +-------------+ - prev SP | back chain | - +-------------+ - | var args | - | reg save | crtl->args.pretend_args_size bytes - +-------------+ - | ... | - | saved regs | spu_saved_regs_size() bytes - FP -> +-------------+ - | ... | - | vars | get_frame_size() bytes - HFP -> +-------------+ - | ... | - | outgoing | - | args | crtl->outgoing_args_size bytes - +-------------+ - | $lr of next | - | frame | - +-------------+ - | back chain | - SP -> +-------------+ - -*/ -void -spu_expand_prologue (void) -{ - HOST_WIDE_INT size = get_frame_size (), offset, regno; - HOST_WIDE_INT total_size; - HOST_WIDE_INT saved_regs_size; - rtx sp_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM); - rtx scratch_reg_0, scratch_reg_1; - rtx_insn *insn; - rtx real; - - if (flag_pic && optimize == 0 && !cfun->machine->pic_reg) - cfun->machine->pic_reg = pic_offset_table_rtx; - - if (spu_naked_function_p (current_function_decl)) - return; - - scratch_reg_0 = gen_rtx_REG (SImode, LAST_ARG_REGNUM + 1); - scratch_reg_1 = gen_rtx_REG (SImode, LAST_ARG_REGNUM + 2); - - saved_regs_size = spu_saved_regs_size (); - total_size = size + saved_regs_size - + crtl->outgoing_args_size - + crtl->args.pretend_args_size; - - if (!crtl->is_leaf - || cfun->calls_alloca || total_size > 0) - total_size += STACK_POINTER_OFFSET; - - /* Save this first because code after this might use the link - register as a scratch register. */ - if (!crtl->is_leaf) - { - insn = frame_emit_store (LINK_REGISTER_REGNUM, sp_reg, 16); - RTX_FRAME_RELATED_P (insn) = 1; - } - - if (total_size > 0) - { - offset = -crtl->args.pretend_args_size; - for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno) - if (need_to_save_reg (regno, 1)) - { - offset -= 16; - insn = frame_emit_store (regno, sp_reg, offset); - RTX_FRAME_RELATED_P (insn) = 1; - } - } - - if (flag_pic && cfun->machine->pic_reg) - { - rtx pic_reg = cfun->machine->pic_reg; - insn = emit_insn (gen_load_pic_offset (pic_reg, scratch_reg_0)); - insn = emit_insn (gen_subsi3 (pic_reg, pic_reg, scratch_reg_0)); - } - - if (total_size > 0) - { - if (flag_stack_check || flag_stack_clash_protection) - { - /* We compare against total_size-1 because - ($sp >= total_size) <=> ($sp > total_size-1) */ - rtx scratch_v4si = gen_rtx_REG (V4SImode, REGNO (scratch_reg_0)); - rtx sp_v4si = gen_rtx_REG (V4SImode, STACK_POINTER_REGNUM); - rtx size_v4si = spu_const (V4SImode, total_size - 1); - if (!satisfies_constraint_K (GEN_INT (total_size - 1))) - { - emit_move_insn (scratch_v4si, size_v4si); - size_v4si = scratch_v4si; - } - emit_insn (gen_cgt_v4si (scratch_v4si, sp_v4si, size_v4si)); - emit_insn (gen_vec_extractv4sisi - (scratch_reg_0, scratch_v4si, GEN_INT (1))); - emit_insn (gen_spu_heq (scratch_reg_0, GEN_INT (0))); - } - - /* Adjust the stack pointer, and make sure scratch_reg_0 contains - the value of the previous $sp because we save it as the back - chain. */ - if (total_size <= 2000) - { - /* In this case we save the back chain first. */ - insn = frame_emit_store (STACK_POINTER_REGNUM, sp_reg, -total_size); - insn = - frame_emit_add_imm (sp_reg, sp_reg, -total_size, scratch_reg_0); - } - else - { - insn = emit_move_insn (scratch_reg_0, sp_reg); - insn = - frame_emit_add_imm (sp_reg, sp_reg, -total_size, scratch_reg_1); - } - RTX_FRAME_RELATED_P (insn) = 1; - real = gen_addsi3 (sp_reg, sp_reg, GEN_INT (-total_size)); - add_reg_note (insn, REG_FRAME_RELATED_EXPR, real); - - if (total_size > 2000) - { - /* Save the back chain ptr */ - insn = frame_emit_store (REGNO (scratch_reg_0), sp_reg, 0); - } - - if (frame_pointer_needed) - { - rtx fp_reg = gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM); - HOST_WIDE_INT fp_offset = STACK_POINTER_OFFSET - + crtl->outgoing_args_size; - /* Set the new frame_pointer */ - insn = frame_emit_add_imm (fp_reg, sp_reg, fp_offset, scratch_reg_0); - RTX_FRAME_RELATED_P (insn) = 1; - real = gen_addsi3 (fp_reg, sp_reg, GEN_INT (fp_offset)); - add_reg_note (insn, REG_FRAME_RELATED_EXPR, real); - REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = STACK_BOUNDARY; - } - } - - if (flag_stack_usage_info) - current_function_static_stack_size = total_size; -} - -void -spu_expand_epilogue (bool sibcall_p) -{ - int size = get_frame_size (), offset, regno; - HOST_WIDE_INT saved_regs_size, total_size; - rtx sp_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM); - rtx scratch_reg_0; - - if (spu_naked_function_p (current_function_decl)) - return; - - scratch_reg_0 = gen_rtx_REG (SImode, LAST_ARG_REGNUM + 1); - - saved_regs_size = spu_saved_regs_size (); - total_size = size + saved_regs_size - + crtl->outgoing_args_size - + crtl->args.pretend_args_size; - - if (!crtl->is_leaf - || cfun->calls_alloca || total_size > 0) - total_size += STACK_POINTER_OFFSET; - - if (total_size > 0) - { - if (cfun->calls_alloca) - frame_emit_load (STACK_POINTER_REGNUM, sp_reg, 0); - else - frame_emit_add_imm (sp_reg, sp_reg, total_size, scratch_reg_0); - - - if (saved_regs_size > 0) - { - offset = -crtl->args.pretend_args_size; - for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno) - if (need_to_save_reg (regno, 1)) - { - offset -= 0x10; - frame_emit_load (regno, sp_reg, offset); - } - } - } - - if (!crtl->is_leaf) - frame_emit_load (LINK_REGISTER_REGNUM, sp_reg, 16); - - if (!sibcall_p) - { - emit_use (gen_rtx_REG (SImode, LINK_REGISTER_REGNUM)); - emit_jump_insn (gen__return ()); - } -} - -rtx -spu_return_addr (int count, rtx frame ATTRIBUTE_UNUSED) -{ - if (count != 0) - return 0; - /* This is inefficient because it ends up copying to a save-register - which then gets saved even though $lr has already been saved. But - it does generate better code for leaf functions and we don't need - to use RETURN_ADDRESS_POINTER_REGNUM to get it working. It's only - used for __builtin_return_address anyway, so maybe we don't care if - it's inefficient. */ - return get_hard_reg_initial_val (Pmode, LINK_REGISTER_REGNUM); -} - - -/* Given VAL, generate a constant appropriate for MODE. - If MODE is a vector mode, every element will be VAL. - For TImode, VAL will be zero extended to 128 bits. */ -rtx -spu_const (machine_mode mode, HOST_WIDE_INT val) -{ - rtx inner; - - gcc_assert (GET_MODE_CLASS (mode) == MODE_INT - || GET_MODE_CLASS (mode) == MODE_FLOAT - || GET_MODE_CLASS (mode) == MODE_VECTOR_INT - || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT); - - if (GET_MODE_CLASS (mode) == MODE_INT) - return immed_double_const (val, 0, mode); - - /* val is the bit representation of the float */ - if (GET_MODE_CLASS (mode) == MODE_FLOAT) - return hwint_to_const_double (mode, val); - - if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT) - inner = immed_double_const (val, 0, GET_MODE_INNER (mode)); - else - inner = hwint_to_const_double (GET_MODE_INNER (mode), val); - - return gen_const_vec_duplicate (mode, inner); -} - -/* Create a MODE vector constant from 4 ints. */ -rtx -spu_const_from_ints(machine_mode mode, int a, int b, int c, int d) -{ - unsigned char arr[16]; - arr[0] = (a >> 24) & 0xff; - arr[1] = (a >> 16) & 0xff; - arr[2] = (a >> 8) & 0xff; - arr[3] = (a >> 0) & 0xff; - arr[4] = (b >> 24) & 0xff; - arr[5] = (b >> 16) & 0xff; - arr[6] = (b >> 8) & 0xff; - arr[7] = (b >> 0) & 0xff; - arr[8] = (c >> 24) & 0xff; - arr[9] = (c >> 16) & 0xff; - arr[10] = (c >> 8) & 0xff; - arr[11] = (c >> 0) & 0xff; - arr[12] = (d >> 24) & 0xff; - arr[13] = (d >> 16) & 0xff; - arr[14] = (d >> 8) & 0xff; - arr[15] = (d >> 0) & 0xff; - return array_to_constant(mode, arr); -} - -/* branch hint stuff */ - -/* An array of these is used to propagate hints to predecessor blocks. */ -struct spu_bb_info -{ - rtx_insn *prop_jump; /* propagated from another block */ - int bb_index; /* the original block. */ -}; -static struct spu_bb_info *spu_bb_info; - -#define STOP_HINT_P(INSN) \ - (CALL_P(INSN) \ - || INSN_CODE(INSN) == CODE_FOR_divmodsi4 \ - || INSN_CODE(INSN) == CODE_FOR_udivmodsi4) - -/* 1 when RTX is a hinted branch or its target. We keep track of - what has been hinted so the safe-hint code can test it easily. */ -#define HINTED_P(RTX) \ - (RTL_FLAG_CHECK3("HINTED_P", (RTX), CODE_LABEL, JUMP_INSN, CALL_INSN)->unchanging) - -/* 1 when RTX is an insn that must be scheduled on an even boundary. */ -#define SCHED_ON_EVEN_P(RTX) \ - (RTL_FLAG_CHECK2("SCHED_ON_EVEN_P", (RTX), JUMP_INSN, CALL_INSN)->in_struct) - -/* Emit a nop for INSN such that the two will dual issue. This assumes - INSN is 8-byte aligned. When INSN is inline asm we emit an lnop. - We check for TImode to handle a MULTI1 insn which has dual issued its - first instruction. get_pipe returns -1 for MULTI0 or inline asm. */ -static void -emit_nop_for_insn (rtx_insn *insn) -{ - int p; - rtx_insn *new_insn; - - /* We need to handle JUMP_TABLE_DATA separately. */ - if (JUMP_TABLE_DATA_P (insn)) - { - new_insn = emit_insn_after (gen_lnop(), insn); - recog_memoized (new_insn); - INSN_LOCATION (new_insn) = UNKNOWN_LOCATION; - return; - } - - p = get_pipe (insn); - if ((CALL_P (insn) || JUMP_P (insn)) && SCHED_ON_EVEN_P (insn)) - new_insn = emit_insn_after (gen_lnop (), insn); - else if (p == 1 && GET_MODE (insn) == TImode) - { - new_insn = emit_insn_before (gen_nopn (GEN_INT (127)), insn); - PUT_MODE (new_insn, TImode); - PUT_MODE (insn, VOIDmode); - } - else - new_insn = emit_insn_after (gen_lnop (), insn); - recog_memoized (new_insn); - INSN_LOCATION (new_insn) = INSN_LOCATION (insn); -} - -/* Insert nops in basic blocks to meet dual issue alignment - requirements. Also make sure hbrp and hint instructions are at least - one cycle apart, possibly inserting a nop. */ -static void -pad_bb(void) -{ - rtx_insn *insn, *next_insn, *prev_insn, *hbr_insn = 0; - int length; - int addr; - - /* This sets up INSN_ADDRESSES. */ - shorten_branches (get_insns ()); - - /* Keep track of length added by nops. */ - length = 0; - - prev_insn = 0; - insn = get_insns (); - if (!active_insn_p (insn)) - insn = next_active_insn (insn); - for (; insn; insn = next_insn) - { - next_insn = next_active_insn (insn); - if (INSN_P (insn) - && (INSN_CODE (insn) == CODE_FOR_iprefetch - || INSN_CODE (insn) == CODE_FOR_hbr)) - { - if (hbr_insn) - { - int a0 = INSN_ADDRESSES (INSN_UID (hbr_insn)); - int a1 = INSN_ADDRESSES (INSN_UID (insn)); - if ((a1 - a0 == 8 && GET_MODE (insn) != TImode) - || (a1 - a0 == 4)) - { - prev_insn = emit_insn_before (gen_lnop (), insn); - PUT_MODE (prev_insn, GET_MODE (insn)); - PUT_MODE (insn, TImode); - INSN_LOCATION (prev_insn) = INSN_LOCATION (insn); - length += 4; - } - } - hbr_insn = insn; - } - if (INSN_P (insn) && INSN_CODE (insn) == CODE_FOR_blockage && next_insn) - { - if (GET_MODE (insn) == TImode) - PUT_MODE (next_insn, TImode); - insn = next_insn; - next_insn = next_active_insn (insn); - } - addr = INSN_ADDRESSES (INSN_UID (insn)); - if ((CALL_P (insn) || JUMP_P (insn)) && SCHED_ON_EVEN_P (insn)) - { - if (((addr + length) & 7) != 0) - { - emit_nop_for_insn (prev_insn); - length += 4; - } - } - else if (GET_MODE (insn) == TImode - && ((next_insn && GET_MODE (next_insn) != TImode) - || get_attr_type (insn) == TYPE_MULTI0) - && ((addr + length) & 7) != 0) - { - /* prev_insn will always be set because the first insn is - always 8-byte aligned. */ - emit_nop_for_insn (prev_insn); - length += 4; - } - prev_insn = insn; - } -} - - -/* Routines for branch hints. */ - -static void -spu_emit_branch_hint (rtx_insn *before, rtx_insn *branch, rtx target, - int distance, sbitmap blocks) -{ - rtx_insn *hint; - rtx_insn *insn; - rtx_jump_table_data *table; - - if (before == 0 || branch == 0 || target == 0) - return; - - /* While scheduling we require hints to be no further than 600, so - we need to enforce that here too */ - if (distance > 600) - return; - - /* If we have a Basic block note, emit it after the basic block note. */ - if (NOTE_INSN_BASIC_BLOCK_P (before)) - before = NEXT_INSN (before); - - rtx_code_label *branch_label = gen_label_rtx (); - LABEL_NUSES (branch_label)++; - LABEL_PRESERVE_P (branch_label) = 1; - insn = emit_label_before (branch_label, branch); - rtx branch_label_ref = gen_rtx_LABEL_REF (VOIDmode, branch_label); - bitmap_set_bit (blocks, BLOCK_FOR_INSN (branch)->index); - - hint = emit_insn_before (gen_hbr (branch_label_ref, target), before); - recog_memoized (hint); - INSN_LOCATION (hint) = INSN_LOCATION (branch); - HINTED_P (branch) = 1; - - if (GET_CODE (target) == LABEL_REF) - HINTED_P (XEXP (target, 0)) = 1; - else if (tablejump_p (branch, 0, &table)) - { - rtvec vec; - int j; - if (GET_CODE (PATTERN (table)) == ADDR_VEC) - vec = XVEC (PATTERN (table), 0); - else - vec = XVEC (PATTERN (table), 1); - for (j = GET_NUM_ELEM (vec) - 1; j >= 0; --j) - HINTED_P (XEXP (RTVEC_ELT (vec, j), 0)) = 1; - } - - if (distance >= 588) - { - /* Make sure the hint isn't scheduled any earlier than this point, - which could make it too far for the branch offest to fit */ - insn = emit_insn_before (gen_blockage (), hint); - recog_memoized (insn); - INSN_LOCATION (insn) = INSN_LOCATION (hint); - } - else if (distance <= 8 * 4) - { - /* To guarantee at least 8 insns between the hint and branch we - insert nops. */ - int d; - for (d = distance; d < 8 * 4; d += 4) - { - insn = - emit_insn_after (gen_nopn_nv (gen_rtx_REG (SImode, 127)), hint); - recog_memoized (insn); - INSN_LOCATION (insn) = INSN_LOCATION (hint); - } - - /* Make sure any nops inserted aren't scheduled before the hint. */ - insn = emit_insn_after (gen_blockage (), hint); - recog_memoized (insn); - INSN_LOCATION (insn) = INSN_LOCATION (hint); - - /* Make sure any nops inserted aren't scheduled after the call. */ - if (CALL_P (branch) && distance < 8 * 4) - { - insn = emit_insn_before (gen_blockage (), branch); - recog_memoized (insn); - INSN_LOCATION (insn) = INSN_LOCATION (branch); - } - } -} - -/* Returns 0 if we don't want a hint for this branch. Otherwise return - the rtx for the branch target. */ -static rtx -get_branch_target (rtx_insn *branch) -{ - if (JUMP_P (branch)) - { - rtx set, src; - - /* Return statements */ - if (GET_CODE (PATTERN (branch)) == RETURN) - return gen_rtx_REG (SImode, LINK_REGISTER_REGNUM); - - /* ASM GOTOs. */ - if (extract_asm_operands (PATTERN (branch)) != NULL) - return NULL; - - set = single_set (branch); - src = SET_SRC (set); - if (GET_CODE (SET_DEST (set)) != PC) - abort (); - - if (GET_CODE (src) == IF_THEN_ELSE) - { - rtx lab = 0; - rtx note = find_reg_note (branch, REG_BR_PROB, 0); - if (note) - { - /* If the more probable case is not a fall through, then - try a branch hint. */ - int prob = profile_probability::from_reg_br_prob_note - (XINT (note, 0)).to_reg_br_prob_base (); - if (prob > (REG_BR_PROB_BASE * 6 / 10) - && GET_CODE (XEXP (src, 1)) != PC) - lab = XEXP (src, 1); - else if (prob < (REG_BR_PROB_BASE * 4 / 10) - && GET_CODE (XEXP (src, 2)) != PC) - lab = XEXP (src, 2); - } - if (lab) - { - if (GET_CODE (lab) == RETURN) - return gen_rtx_REG (SImode, LINK_REGISTER_REGNUM); - return lab; - } - return 0; - } - - return src; - } - else if (CALL_P (branch)) - { - rtx call; - /* All of our call patterns are in a PARALLEL and the CALL is - the first pattern in the PARALLEL. */ - if (GET_CODE (PATTERN (branch)) != PARALLEL) - abort (); - call = XVECEXP (PATTERN (branch), 0, 0); - if (GET_CODE (call) == SET) - call = SET_SRC (call); - if (GET_CODE (call) != CALL) - abort (); - return XEXP (XEXP (call, 0), 0); - } - return 0; -} - -/* The special $hbr register is used to prevent the insn scheduler from - moving hbr insns across instructions which invalidate them. It - should only be used in a clobber, and this function searches for - insns which clobber it. */ -static bool -insn_clobbers_hbr (rtx_insn *insn) -{ - if (INSN_P (insn) - && GET_CODE (PATTERN (insn)) == PARALLEL) - { - rtx parallel = PATTERN (insn); - rtx clobber; - int j; - for (j = XVECLEN (parallel, 0) - 1; j >= 0; j--) - { - clobber = XVECEXP (parallel, 0, j); - if (GET_CODE (clobber) == CLOBBER - && GET_CODE (XEXP (clobber, 0)) == REG - && REGNO (XEXP (clobber, 0)) == HBR_REGNUM) - return 1; - } - } - return 0; -} - -/* Search up to 32 insns starting at FIRST: - - at any kind of hinted branch, just return - - at any unconditional branch in the first 15 insns, just return - - at a call or indirect branch, after the first 15 insns, force it to - an even address and return - - at any unconditional branch, after the first 15 insns, force it to - an even address. - At then end of the search, insert an hbrp within 4 insns of FIRST, - and an hbrp within 16 instructions of FIRST. - */ -static void -insert_hbrp_for_ilb_runout (rtx_insn *first) -{ - rtx_insn *insn, *before_4 = 0, *before_16 = 0; - int addr = 0, length, first_addr = -1; - int hbrp_addr0 = 128 * 4, hbrp_addr1 = 128 * 4; - int insert_lnop_after = 0; - for (insn = first; insn; insn = NEXT_INSN (insn)) - if (INSN_P (insn)) - { - if (first_addr == -1) - first_addr = INSN_ADDRESSES (INSN_UID (insn)); - addr = INSN_ADDRESSES (INSN_UID (insn)) - first_addr; - length = get_attr_length (insn); - - if (before_4 == 0 && addr + length >= 4 * 4) - before_4 = insn; - /* We test for 14 instructions because the first hbrp will add - up to 2 instructions. */ - if (before_16 == 0 && addr + length >= 14 * 4) - before_16 = insn; - - if (INSN_CODE (insn) == CODE_FOR_hbr) - { - /* Make sure an hbrp is at least 2 cycles away from a hint. - Insert an lnop after the hbrp when necessary. */ - if (before_4 == 0 && addr > 0) - { - before_4 = insn; - insert_lnop_after |= 1; - } - else if (before_4 && addr <= 4 * 4) - insert_lnop_after |= 1; - if (before_16 == 0 && addr > 10 * 4) - { - before_16 = insn; - insert_lnop_after |= 2; - } - else if (before_16 && addr <= 14 * 4) - insert_lnop_after |= 2; - } - - if (INSN_CODE (insn) == CODE_FOR_iprefetch) - { - if (addr < hbrp_addr0) - hbrp_addr0 = addr; - else if (addr < hbrp_addr1) - hbrp_addr1 = addr; - } - - if (CALL_P (insn) || JUMP_P (insn)) - { - if (HINTED_P (insn)) - return; - - /* Any branch after the first 15 insns should be on an even - address to avoid a special case branch. There might be - some nops and/or hbrps inserted, so we test after 10 - insns. */ - if (addr > 10 * 4) - SCHED_ON_EVEN_P (insn) = 1; - } - - if (CALL_P (insn) || tablejump_p (insn, 0, 0)) - return; - - - if (addr + length >= 32 * 4) - { - gcc_assert (before_4 && before_16); - if (hbrp_addr0 > 4 * 4) - { - insn = - emit_insn_before (gen_iprefetch (GEN_INT (1)), before_4); - recog_memoized (insn); - INSN_LOCATION (insn) = INSN_LOCATION (before_4); - INSN_ADDRESSES_NEW (insn, - INSN_ADDRESSES (INSN_UID (before_4))); - PUT_MODE (insn, GET_MODE (before_4)); - PUT_MODE (before_4, TImode); - if (insert_lnop_after & 1) - { - insn = emit_insn_before (gen_lnop (), before_4); - recog_memoized (insn); - INSN_LOCATION (insn) = INSN_LOCATION (before_4); - INSN_ADDRESSES_NEW (insn, - INSN_ADDRESSES (INSN_UID (before_4))); - PUT_MODE (insn, TImode); - } - } - if ((hbrp_addr0 <= 4 * 4 || hbrp_addr0 > 16 * 4) - && hbrp_addr1 > 16 * 4) - { - insn = - emit_insn_before (gen_iprefetch (GEN_INT (2)), before_16); - recog_memoized (insn); - INSN_LOCATION (insn) = INSN_LOCATION (before_16); - INSN_ADDRESSES_NEW (insn, - INSN_ADDRESSES (INSN_UID (before_16))); - PUT_MODE (insn, GET_MODE (before_16)); - PUT_MODE (before_16, TImode); - if (insert_lnop_after & 2) - { - insn = emit_insn_before (gen_lnop (), before_16); - recog_memoized (insn); - INSN_LOCATION (insn) = INSN_LOCATION (before_16); - INSN_ADDRESSES_NEW (insn, - INSN_ADDRESSES (INSN_UID - (before_16))); - PUT_MODE (insn, TImode); - } - } - return; - } - } - else if (BARRIER_P (insn)) - return; - -} - -/* The SPU might hang when it executes 48 inline instructions after a - hinted branch jumps to its hinted target. The beginning of a - function and the return from a call might have been hinted, and - must be handled as well. To prevent a hang we insert 2 hbrps. The - first should be within 6 insns of the branch target. The second - should be within 22 insns of the branch target. When determining - if hbrps are necessary, we look for only 32 inline instructions, - because up to 12 nops and 4 hbrps could be inserted. Similarily, - when inserting new hbrps, we insert them within 4 and 16 insns of - the target. */ -static void -insert_hbrp (void) -{ - rtx_insn *insn; - if (TARGET_SAFE_HINTS) - { - shorten_branches (get_insns ()); - /* Insert hbrp at beginning of function */ - insn = next_active_insn (get_insns ()); - if (insn) - insert_hbrp_for_ilb_runout (insn); - /* Insert hbrp after hinted targets. */ - for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) - if ((LABEL_P (insn) && HINTED_P (insn)) || CALL_P (insn)) - insert_hbrp_for_ilb_runout (next_active_insn (insn)); - } -} - -static int in_spu_reorg; - -static void -spu_var_tracking (void) -{ - if (flag_var_tracking) - { - df_analyze (); - timevar_push (TV_VAR_TRACKING); - variable_tracking_main (); - timevar_pop (TV_VAR_TRACKING); - df_finish_pass (false); - } -} - -/* Insert branch hints. There are no branch optimizations after this - pass, so it's safe to set our branch hints now. */ -static void -spu_machine_dependent_reorg (void) -{ - sbitmap blocks; - basic_block bb; - rtx_insn *branch, *insn; - rtx branch_target = 0; - int branch_addr = 0, insn_addr, required_dist = 0; - int i; - unsigned int j; - - if (!TARGET_BRANCH_HINTS || optimize == 0) - { - /* We still do it for unoptimized code because an external - function might have hinted a call or return. */ - compute_bb_for_insn (); - insert_hbrp (); - pad_bb (); - spu_var_tracking (); - free_bb_for_insn (); - return; - } - - blocks = sbitmap_alloc (last_basic_block_for_fn (cfun)); - bitmap_clear (blocks); - - in_spu_reorg = 1; - compute_bb_for_insn (); - - /* (Re-)discover loops so that bb->loop_father can be used - in the analysis below. */ - loop_optimizer_init (AVOID_CFG_MODIFICATIONS); - - compact_blocks (); - - spu_bb_info = - (struct spu_bb_info *) xcalloc (n_basic_blocks_for_fn (cfun), - sizeof (struct spu_bb_info)); - - /* We need exact insn addresses and lengths. */ - shorten_branches (get_insns ()); - - for (i = n_basic_blocks_for_fn (cfun) - 1; i >= 0; i--) - { - bb = BASIC_BLOCK_FOR_FN (cfun, i); - branch = 0; - if (spu_bb_info[i].prop_jump) - { - branch = spu_bb_info[i].prop_jump; - branch_target = get_branch_target (branch); - branch_addr = INSN_ADDRESSES (INSN_UID (branch)); - required_dist = spu_hint_dist; - } - /* Search from end of a block to beginning. In this loop, find - jumps which need a branch and emit them only when: - - it's an indirect branch and we're at the insn which sets - the register - - we're at an insn that will invalidate the hint. e.g., a - call, another hint insn, inline asm that clobbers $hbr, and - some inlined operations (divmodsi4). Don't consider jumps - because they are only at the end of a block and are - considered when we are deciding whether to propagate - - we're getting too far away from the branch. The hbr insns - only have a signed 10 bit offset - We go back as far as possible so the branch will be considered - for propagation when we get to the beginning of the block. */ - for (insn = BB_END (bb); insn; insn = PREV_INSN (insn)) - { - if (INSN_P (insn)) - { - insn_addr = INSN_ADDRESSES (INSN_UID (insn)); - if (branch - && ((GET_CODE (branch_target) == REG - && set_of (branch_target, insn) != NULL_RTX) - || insn_clobbers_hbr (insn) - || branch_addr - insn_addr > 600)) - { - rtx_insn *next = NEXT_INSN (insn); - int next_addr = INSN_ADDRESSES (INSN_UID (next)); - if (insn != BB_END (bb) - && branch_addr - next_addr >= required_dist) - { - if (dump_file) - fprintf (dump_file, - "hint for %i in block %i before %i\n", - INSN_UID (branch), bb->index, - INSN_UID (next)); - spu_emit_branch_hint (next, branch, branch_target, - branch_addr - next_addr, blocks); - } - branch = 0; - } - - /* JUMP_P will only be true at the end of a block. When - branch is already set it means we've previously decided - to propagate a hint for that branch into this block. */ - if (CALL_P (insn) || (JUMP_P (insn) && !branch)) - { - branch = 0; - if ((branch_target = get_branch_target (insn))) - { - branch = insn; - branch_addr = insn_addr; - required_dist = spu_hint_dist; - } - } - } - if (insn == BB_HEAD (bb)) - break; - } - - if (branch) - { - /* If we haven't emitted a hint for this branch yet, it might - be profitable to emit it in one of the predecessor blocks, - especially for loops. */ - rtx_insn *bbend; - basic_block prev = 0, prop = 0, prev2 = 0; - int loop_exit = 0, simple_loop = 0; - int next_addr = INSN_ADDRESSES (INSN_UID (NEXT_INSN (insn))); - - for (j = 0; j < EDGE_COUNT (bb->preds); j++) - if (EDGE_PRED (bb, j)->flags & EDGE_FALLTHRU) - prev = EDGE_PRED (bb, j)->src; - else - prev2 = EDGE_PRED (bb, j)->src; - - for (j = 0; j < EDGE_COUNT (bb->succs); j++) - if (EDGE_SUCC (bb, j)->flags & EDGE_LOOP_EXIT) - loop_exit = 1; - else if (EDGE_SUCC (bb, j)->dest == bb) - simple_loop = 1; - - /* If this branch is a loop exit then propagate to previous - fallthru block. This catches the cases when it is a simple - loop or when there is an initial branch into the loop. */ - if (prev && (loop_exit || simple_loop) - && bb_loop_depth (prev) <= bb_loop_depth (bb)) - prop = prev; - - /* If there is only one adjacent predecessor. Don't propagate - outside this loop. */ - else if (prev && single_pred_p (bb) - && prev->loop_father == bb->loop_father) - prop = prev; - - /* If this is the JOIN block of a simple IF-THEN then - propagate the hint to the HEADER block. */ - else if (prev && prev2 - && EDGE_COUNT (bb->preds) == 2 - && EDGE_COUNT (prev->preds) == 1 - && EDGE_PRED (prev, 0)->src == prev2 - && prev2->loop_father == bb->loop_father - && GET_CODE (branch_target) != REG) - prop = prev; - - /* Don't propagate when: - - this is a simple loop and the hint would be too far - - this is not a simple loop and there are 16 insns in - this block already - - the predecessor block ends in a branch that will be - hinted - - the predecessor block ends in an insn that invalidates - the hint */ - if (prop - && prop->index >= 0 - && (bbend = BB_END (prop)) - && branch_addr - INSN_ADDRESSES (INSN_UID (bbend)) < - (simple_loop ? 600 : 16 * 4) && get_branch_target (bbend) == 0 - && (JUMP_P (bbend) || !insn_clobbers_hbr (bbend))) - { - if (dump_file) - fprintf (dump_file, "propagate from %i to %i (loop depth %i) " - "for %i (loop_exit %i simple_loop %i dist %i)\n", - bb->index, prop->index, bb_loop_depth (bb), - INSN_UID (branch), loop_exit, simple_loop, - branch_addr - INSN_ADDRESSES (INSN_UID (bbend))); - - spu_bb_info[prop->index].prop_jump = branch; - spu_bb_info[prop->index].bb_index = i; - } - else if (branch_addr - next_addr >= required_dist) - { - if (dump_file) - fprintf (dump_file, "hint for %i in block %i before %i\n", - INSN_UID (branch), bb->index, - INSN_UID (NEXT_INSN (insn))); - spu_emit_branch_hint (NEXT_INSN (insn), branch, branch_target, - branch_addr - next_addr, blocks); - } - branch = 0; - } - } - free (spu_bb_info); - - if (!bitmap_empty_p (blocks)) - find_many_sub_basic_blocks (blocks); - - /* We have to schedule to make sure alignment is ok. */ - FOR_EACH_BB_FN (bb, cfun) bb->flags &= ~BB_DISABLE_SCHEDULE; - - /* The hints need to be scheduled, so call it again. */ - schedule_insns (); - df_finish_pass (true); - - insert_hbrp (); - - pad_bb (); - - for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) - if (NONJUMP_INSN_P (insn) && INSN_CODE (insn) == CODE_FOR_hbr) - { - /* Adjust the LABEL_REF in a hint when we have inserted a nop - between its branch label and the branch . We don't move the - label because GCC expects it at the beginning of the block. */ - rtx unspec = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); - rtx label_ref = XVECEXP (unspec, 0, 0); - rtx_insn *label = as_a (XEXP (label_ref, 0)); - rtx_insn *branch; - int offset = 0; - for (branch = NEXT_INSN (label); - !JUMP_P (branch) && !CALL_P (branch); - branch = NEXT_INSN (branch)) - if (NONJUMP_INSN_P (branch)) - offset += get_attr_length (branch); - if (offset > 0) - XVECEXP (unspec, 0, 0) = plus_constant (Pmode, label_ref, offset); - } - - spu_var_tracking (); - - loop_optimizer_finalize (); - - free_bb_for_insn (); - - in_spu_reorg = 0; -} - - -/* Insn scheduling routines, primarily for dual issue. */ -static int -spu_sched_issue_rate (void) -{ - return 2; -} - -static int -uses_ls_unit(rtx_insn *insn) -{ - rtx set = single_set (insn); - if (set != 0 - && (GET_CODE (SET_DEST (set)) == MEM - || GET_CODE (SET_SRC (set)) == MEM)) - return 1; - return 0; -} - -static int -get_pipe (rtx_insn *insn) -{ - enum attr_type t; - /* Handle inline asm */ - if (INSN_CODE (insn) == -1) - return -1; - t = get_attr_type (insn); - switch (t) - { - case TYPE_CONVERT: - return -2; - case TYPE_MULTI0: - return -1; - - case TYPE_FX2: - case TYPE_FX3: - case TYPE_SPR: - case TYPE_NOP: - case TYPE_FXB: - case TYPE_FPD: - case TYPE_FP6: - case TYPE_FP7: - return 0; - - case TYPE_LNOP: - case TYPE_SHUF: - case TYPE_LOAD: - case TYPE_STORE: - case TYPE_BR: - case TYPE_MULTI1: - case TYPE_HBR: - case TYPE_IPREFETCH: - return 1; - default: - abort (); - } -} - - -/* haifa-sched.c has a static variable that keeps track of the current - cycle. It is passed to spu_sched_reorder, and we record it here for - use by spu_sched_variable_issue. It won't be accurate if the - scheduler updates it's clock_var between the two calls. */ -static int clock_var; - -/* This is used to keep track of insn alignment. Set to 0 at the - beginning of each block and increased by the "length" attr of each - insn scheduled. */ -static int spu_sched_length; - -/* Record when we've issued pipe0 and pipe1 insns so we can reorder the - ready list appropriately in spu_sched_reorder(). */ -static int pipe0_clock; -static int pipe1_clock; - -static int prev_clock_var; - -static int prev_priority; - -/* The SPU needs to load the next ilb sometime during the execution of - the previous ilb. There is a potential conflict if every cycle has a - load or store. To avoid the conflict we make sure the load/store - unit is free for at least one cycle during the execution of insns in - the previous ilb. */ -static int spu_ls_first; -static int prev_ls_clock; - -static void -spu_sched_init_global (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED, - int max_ready ATTRIBUTE_UNUSED) -{ - spu_sched_length = 0; -} - -static void -spu_sched_init (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED, - int max_ready ATTRIBUTE_UNUSED) -{ - if (align_labels.levels[0].get_value () > 4 - || align_loops.levels[0].get_value () > 4 - || align_jumps.levels[0].get_value () > 4) - { - /* When any block might be at least 8-byte aligned, assume they - will all be at least 8-byte aligned to make sure dual issue - works out correctly. */ - spu_sched_length = 0; - } - spu_ls_first = INT_MAX; - clock_var = -1; - prev_ls_clock = -1; - pipe0_clock = -1; - pipe1_clock = -1; - prev_clock_var = -1; - prev_priority = -1; -} - -static int -spu_sched_variable_issue (FILE *file ATTRIBUTE_UNUSED, - int verbose ATTRIBUTE_UNUSED, - rtx_insn *insn, int more) -{ - int len; - int p; - if (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER - || (len = get_attr_length (insn)) == 0) - return more; - - spu_sched_length += len; - - /* Reset on inline asm */ - if (INSN_CODE (insn) == -1) - { - spu_ls_first = INT_MAX; - pipe0_clock = -1; - pipe1_clock = -1; - return 0; - } - p = get_pipe (insn); - if (p == 0) - pipe0_clock = clock_var; - else - pipe1_clock = clock_var; - - if (in_spu_reorg) - { - if (clock_var - prev_ls_clock > 1 - || INSN_CODE (insn) == CODE_FOR_iprefetch) - spu_ls_first = INT_MAX; - if (uses_ls_unit (insn)) - { - if (spu_ls_first == INT_MAX) - spu_ls_first = spu_sched_length; - prev_ls_clock = clock_var; - } - - /* The scheduler hasn't inserted the nop, but we will later on. - Include those nops in spu_sched_length. */ - if (prev_clock_var == clock_var && (spu_sched_length & 7)) - spu_sched_length += 4; - prev_clock_var = clock_var; - - /* more is -1 when called from spu_sched_reorder for new insns - that don't have INSN_PRIORITY */ - if (more >= 0) - prev_priority = INSN_PRIORITY (insn); - } - - /* Always try issuing more insns. spu_sched_reorder will decide - when the cycle should be advanced. */ - return 1; -} - -/* This function is called for both TARGET_SCHED_REORDER and - TARGET_SCHED_REORDER2. */ -static int -spu_sched_reorder (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED, - rtx_insn **ready, int *nreadyp, int clock) -{ - int i, nready = *nreadyp; - int pipe_0, pipe_1, pipe_hbrp, pipe_ls, schedule_i; - rtx_insn *insn; - - clock_var = clock; - - if (nready <= 0 || pipe1_clock >= clock) - return 0; - - /* Find any rtl insns that don't generate assembly insns and schedule - them first. */ - for (i = nready - 1; i >= 0; i--) - { - insn = ready[i]; - if (INSN_CODE (insn) == -1 - || INSN_CODE (insn) == CODE_FOR_blockage - || (INSN_P (insn) && get_attr_length (insn) == 0)) - { - ready[i] = ready[nready - 1]; - ready[nready - 1] = insn; - return 1; - } - } - - pipe_0 = pipe_1 = pipe_hbrp = pipe_ls = schedule_i = -1; - for (i = 0; i < nready; i++) - if (INSN_CODE (ready[i]) != -1) - { - insn = ready[i]; - switch (get_attr_type (insn)) - { - default: - case TYPE_MULTI0: - case TYPE_CONVERT: - case TYPE_FX2: - case TYPE_FX3: - case TYPE_SPR: - case TYPE_NOP: - case TYPE_FXB: - case TYPE_FPD: - case TYPE_FP6: - case TYPE_FP7: - pipe_0 = i; - break; - case TYPE_LOAD: - case TYPE_STORE: - pipe_ls = i; - /* FALLTHRU */ - case TYPE_LNOP: - case TYPE_SHUF: - case TYPE_BR: - case TYPE_MULTI1: - case TYPE_HBR: - pipe_1 = i; - break; - case TYPE_IPREFETCH: - pipe_hbrp = i; - break; - } - } - - /* In the first scheduling phase, schedule loads and stores together - to increase the chance they will get merged during postreload CSE. */ - if (!reload_completed && pipe_ls >= 0) - { - insn = ready[pipe_ls]; - ready[pipe_ls] = ready[nready - 1]; - ready[nready - 1] = insn; - return 1; - } - - /* If there is an hbrp ready, prefer it over other pipe 1 insns. */ - if (pipe_hbrp >= 0) - pipe_1 = pipe_hbrp; - - /* When we have loads/stores in every cycle of the last 15 insns and - we are about to schedule another load/store, emit an hbrp insn - instead. */ - if (in_spu_reorg - && spu_sched_length - spu_ls_first >= 4 * 15 - && !(pipe0_clock < clock && pipe_0 >= 0) && pipe_1 == pipe_ls) - { - insn = sched_emit_insn (gen_iprefetch (GEN_INT (3))); - recog_memoized (insn); - if (pipe0_clock < clock) - PUT_MODE (insn, TImode); - spu_sched_variable_issue (file, verbose, insn, -1); - return 0; - } - - /* In general, we want to emit nops to increase dual issue, but dual - issue isn't faster when one of the insns could be scheduled later - without effecting the critical path. We look at INSN_PRIORITY to - make a good guess, but it isn't perfect so -mdual-nops=n can be - used to effect it. */ - if (in_spu_reorg && spu_dual_nops < 10) - { - /* When we are at an even address and we are not issuing nops to - improve scheduling then we need to advance the cycle. */ - if ((spu_sched_length & 7) == 0 && prev_clock_var == clock - && (spu_dual_nops == 0 - || (pipe_1 != -1 - && prev_priority > - INSN_PRIORITY (ready[pipe_1]) + spu_dual_nops))) - return 0; - - /* When at an odd address, schedule the highest priority insn - without considering pipeline. */ - if ((spu_sched_length & 7) == 4 && prev_clock_var != clock - && (spu_dual_nops == 0 - || (prev_priority > - INSN_PRIORITY (ready[nready - 1]) + spu_dual_nops))) - return 1; - } - - - /* We haven't issued a pipe0 insn yet this cycle, if there is a - pipe0 insn in the ready list, schedule it. */ - if (pipe0_clock < clock && pipe_0 >= 0) - schedule_i = pipe_0; - - /* Either we've scheduled a pipe0 insn already or there is no pipe0 - insn to schedule. Put a pipe1 insn at the front of the ready list. */ - else - schedule_i = pipe_1; - - if (schedule_i > -1) - { - insn = ready[schedule_i]; - ready[schedule_i] = ready[nready - 1]; - ready[nready - 1] = insn; - return 1; - } - return 0; -} - -/* INSN is dependent on DEP_INSN. */ -static int -spu_sched_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep_insn, - int cost, unsigned int) -{ - rtx set; - - /* The blockage pattern is used to prevent instructions from being - moved across it and has no cost. */ - if (INSN_CODE (insn) == CODE_FOR_blockage - || INSN_CODE (dep_insn) == CODE_FOR_blockage) - return 0; - - if ((INSN_P (insn) && get_attr_length (insn) == 0) - || (INSN_P (dep_insn) && get_attr_length (dep_insn) == 0)) - return 0; - - /* Make sure hbrps are spread out. */ - if (INSN_CODE (insn) == CODE_FOR_iprefetch - && INSN_CODE (dep_insn) == CODE_FOR_iprefetch) - return 8; - - /* Make sure hints and hbrps are 2 cycles apart. */ - if ((INSN_CODE (insn) == CODE_FOR_iprefetch - || INSN_CODE (insn) == CODE_FOR_hbr) - && (INSN_CODE (dep_insn) == CODE_FOR_iprefetch - || INSN_CODE (dep_insn) == CODE_FOR_hbr)) - return 2; - - /* An hbrp has no real dependency on other insns. */ - if (INSN_CODE (insn) == CODE_FOR_iprefetch - || INSN_CODE (dep_insn) == CODE_FOR_iprefetch) - return 0; - - /* Assuming that it is unlikely an argument register will be used in - the first cycle of the called function, we reduce the cost for - slightly better scheduling of dep_insn. When not hinted, the - mispredicted branch would hide the cost as well. */ - if (CALL_P (insn)) - { - rtx target = get_branch_target (insn); - if (GET_CODE (target) != REG || !set_of (target, insn)) - return cost - 2; - return cost; - } - - /* And when returning from a function, let's assume the return values - are completed sooner too. */ - if (CALL_P (dep_insn)) - return cost - 2; - - /* Make sure an instruction that loads from the back chain is schedule - away from the return instruction so a hint is more likely to get - issued. */ - if (INSN_CODE (insn) == CODE_FOR__return - && (set = single_set (dep_insn)) - && GET_CODE (SET_DEST (set)) == REG - && REGNO (SET_DEST (set)) == LINK_REGISTER_REGNUM) - return 20; - - /* The dfa scheduler sets cost to 0 for all anti-dependencies and the - scheduler makes every insn in a block anti-dependent on the final - jump_insn. We adjust here so higher cost insns will get scheduled - earlier. */ - if (JUMP_P (insn) && dep_type == REG_DEP_ANTI) - return insn_sched_cost (dep_insn) - 3; - - return cost; -} - -/* Create a CONST_DOUBLE from a string. */ -rtx -spu_float_const (const char *string, machine_mode mode) -{ - REAL_VALUE_TYPE value; - value = REAL_VALUE_ATOF (string, mode); - return const_double_from_real_value (value, mode); -} - -int -spu_constant_address_p (rtx x) -{ - return (GET_CODE (x) == LABEL_REF || GET_CODE (x) == SYMBOL_REF - || GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST - || GET_CODE (x) == HIGH); -} - -static enum spu_immediate -which_immediate_load (HOST_WIDE_INT val) -{ - gcc_assert (val == trunc_int_for_mode (val, SImode)); - - if (val >= -0x8000 && val <= 0x7fff) - return SPU_IL; - if (val >= 0 && val <= 0x3ffff) - return SPU_ILA; - if ((val & 0xffff) == ((val >> 16) & 0xffff)) - return SPU_ILH; - if ((val & 0xffff) == 0) - return SPU_ILHU; - - return SPU_NONE; -} - -/* Return true when OP can be loaded by one of the il instructions, or - when flow2 is not completed and OP can be loaded using ilhu and iohl. */ -int -immediate_load_p (rtx op, machine_mode mode) -{ - if (CONSTANT_P (op)) - { - enum immediate_class c = classify_immediate (op, mode); - return c == IC_IL1 || c == IC_IL1s - || (!epilogue_completed && (c == IC_IL2 || c == IC_IL2s)); - } - return 0; -} - -/* Return true if the first SIZE bytes of arr is a constant that can be - generated with cbd, chd, cwd or cdd. When non-NULL, PRUN and PSTART - represent the size and offset of the instruction to use. */ -static int -cpat_info(unsigned char *arr, int size, int *prun, int *pstart) -{ - int cpat, run, i, start; - cpat = 1; - run = 0; - start = -1; - for (i = 0; i < size && cpat; i++) - if (arr[i] != i+16) - { - if (!run) - { - start = i; - if (arr[i] == 3) - run = 1; - else if (arr[i] == 2 && arr[i+1] == 3) - run = 2; - else if (arr[i] == 0) - { - while (arr[i+run] == run && i+run < 16) - run++; - if (run != 4 && run != 8) - cpat = 0; - } - else - cpat = 0; - if ((i & (run-1)) != 0) - cpat = 0; - i += run; - } - else - cpat = 0; - } - if (cpat && (run || size < 16)) - { - if (run == 0) - run = 1; - if (prun) - *prun = run; - if (pstart) - *pstart = start == -1 ? 16-run : start; - return 1; - } - return 0; -} - -/* OP is a CONSTANT_P. Determine what instructions can be used to load - it into a register. MODE is only valid when OP is a CONST_INT. */ -static enum immediate_class -classify_immediate (rtx op, machine_mode mode) -{ - HOST_WIDE_INT val; - unsigned char arr[16]; - int i, j, repeated, fsmbi, repeat; - - gcc_assert (CONSTANT_P (op)); - - if (GET_MODE (op) != VOIDmode) - mode = GET_MODE (op); - - /* A V4SI const_vector with all identical symbols is ok. */ - if (!flag_pic - && mode == V4SImode - && GET_CODE (op) == CONST_VECTOR - && GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_INT - && GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_DOUBLE) - op = unwrap_const_vec_duplicate (op); - - switch (GET_CODE (op)) - { - case SYMBOL_REF: - case LABEL_REF: - return TARGET_LARGE_MEM ? IC_IL2s : IC_IL1s; - - case CONST: - /* We can never know if the resulting address fits in 18 bits and can be - loaded with ila. For now, assume the address will not overflow if - the displacement is "small" (fits 'K' constraint). */ - if (!TARGET_LARGE_MEM && GET_CODE (XEXP (op, 0)) == PLUS) - { - rtx sym = XEXP (XEXP (op, 0), 0); - rtx cst = XEXP (XEXP (op, 0), 1); - - if (GET_CODE (sym) == SYMBOL_REF - && GET_CODE (cst) == CONST_INT - && satisfies_constraint_K (cst)) - return IC_IL1s; - } - return IC_IL2s; - - case HIGH: - return IC_IL1s; - - case CONST_VECTOR: - for (i = 0; i < GET_MODE_NUNITS (mode); i++) - if (GET_CODE (CONST_VECTOR_ELT (op, i)) != CONST_INT - && GET_CODE (CONST_VECTOR_ELT (op, i)) != CONST_DOUBLE) - return IC_POOL; - /* Fall through. */ - - case CONST_INT: - case CONST_DOUBLE: - constant_to_array (mode, op, arr); - - /* Check that each 4-byte slot is identical. */ - repeated = 1; - for (i = 4; i < 16; i += 4) - for (j = 0; j < 4; j++) - if (arr[j] != arr[i + j]) - repeated = 0; - - if (repeated) - { - val = (arr[0] << 24) | (arr[1] << 16) | (arr[2] << 8) | arr[3]; - val = trunc_int_for_mode (val, SImode); - - if (which_immediate_load (val) != SPU_NONE) - return IC_IL1; - } - - /* Any mode of 2 bytes or smaller can be loaded with an il - instruction. */ - gcc_assert (GET_MODE_SIZE (mode) > 2); - - fsmbi = 1; - repeat = 0; - for (i = 0; i < 16 && fsmbi; i++) - if (arr[i] != 0 && repeat == 0) - repeat = arr[i]; - else if (arr[i] != 0 && arr[i] != repeat) - fsmbi = 0; - if (fsmbi) - return repeat == 0xff ? IC_FSMBI : IC_FSMBI2; - - if (cpat_info (arr, GET_MODE_SIZE (mode), 0, 0)) - return IC_CPAT; - - if (repeated) - return IC_IL2; - - return IC_POOL; - default: - break; - } - gcc_unreachable (); -} - -static enum spu_immediate -which_logical_immediate (HOST_WIDE_INT val) -{ - gcc_assert (val == trunc_int_for_mode (val, SImode)); - - if (val >= -0x200 && val <= 0x1ff) - return SPU_ORI; - if (val >= 0 && val <= 0xffff) - return SPU_IOHL; - if ((val & 0xffff) == ((val >> 16) & 0xffff)) - { - val = trunc_int_for_mode (val, HImode); - if (val >= -0x200 && val <= 0x1ff) - return SPU_ORHI; - if ((val & 0xff) == ((val >> 8) & 0xff)) - { - val = trunc_int_for_mode (val, QImode); - if (val >= -0x200 && val <= 0x1ff) - return SPU_ORBI; - } - } - return SPU_NONE; -} - -/* Return TRUE when X, a CONST_VECTOR, only contains CONST_INTs or - CONST_DOUBLEs. */ -static int -const_vector_immediate_p (rtx x) -{ - int i; - gcc_assert (GET_CODE (x) == CONST_VECTOR); - for (i = 0; i < GET_MODE_NUNITS (GET_MODE (x)); i++) - if (GET_CODE (CONST_VECTOR_ELT (x, i)) != CONST_INT - && GET_CODE (CONST_VECTOR_ELT (x, i)) != CONST_DOUBLE) - return 0; - return 1; -} - -int -logical_immediate_p (rtx op, machine_mode mode) -{ - HOST_WIDE_INT val; - unsigned char arr[16]; - int i, j; - - gcc_assert (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE - || GET_CODE (op) == CONST_VECTOR); - - if (GET_CODE (op) == CONST_VECTOR - && !const_vector_immediate_p (op)) - return 0; - - if (GET_MODE (op) != VOIDmode) - mode = GET_MODE (op); - - constant_to_array (mode, op, arr); - - /* Check that bytes are repeated. */ - for (i = 4; i < 16; i += 4) - for (j = 0; j < 4; j++) - if (arr[j] != arr[i + j]) - return 0; - - val = (arr[0] << 24) | (arr[1] << 16) | (arr[2] << 8) | arr[3]; - val = trunc_int_for_mode (val, SImode); - - i = which_logical_immediate (val); - return i != SPU_NONE && i != SPU_IOHL; -} - -int -iohl_immediate_p (rtx op, machine_mode mode) -{ - HOST_WIDE_INT val; - unsigned char arr[16]; - int i, j; - - gcc_assert (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE - || GET_CODE (op) == CONST_VECTOR); - - if (GET_CODE (op) == CONST_VECTOR - && !const_vector_immediate_p (op)) - return 0; - - if (GET_MODE (op) != VOIDmode) - mode = GET_MODE (op); - - constant_to_array (mode, op, arr); - - /* Check that bytes are repeated. */ - for (i = 4; i < 16; i += 4) - for (j = 0; j < 4; j++) - if (arr[j] != arr[i + j]) - return 0; - - val = (arr[0] << 24) | (arr[1] << 16) | (arr[2] << 8) | arr[3]; - val = trunc_int_for_mode (val, SImode); - - return val >= 0 && val <= 0xffff; -} - -int -arith_immediate_p (rtx op, machine_mode mode, - HOST_WIDE_INT low, HOST_WIDE_INT high) -{ - HOST_WIDE_INT val; - unsigned char arr[16]; - int bytes, i, j; - - gcc_assert (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE - || GET_CODE (op) == CONST_VECTOR); - - if (GET_CODE (op) == CONST_VECTOR - && !const_vector_immediate_p (op)) - return 0; - - if (GET_MODE (op) != VOIDmode) - mode = GET_MODE (op); - - constant_to_array (mode, op, arr); - - bytes = GET_MODE_UNIT_SIZE (mode); - mode = int_mode_for_mode (GET_MODE_INNER (mode)).require (); - - /* Check that bytes are repeated. */ - for (i = bytes; i < 16; i += bytes) - for (j = 0; j < bytes; j++) - if (arr[j] != arr[i + j]) - return 0; - - val = arr[0]; - for (j = 1; j < bytes; j++) - val = (val << 8) | arr[j]; - - val = trunc_int_for_mode (val, mode); - - return val >= low && val <= high; -} - -/* TRUE when op is an immediate and an exact power of 2, and given that - OP is 2^scale, scale >= LOW && scale <= HIGH. When OP is a vector, - all entries must be the same. */ -bool -exp2_immediate_p (rtx op, machine_mode mode, int low, int high) -{ - machine_mode int_mode; - HOST_WIDE_INT val; - unsigned char arr[16]; - int bytes, i, j; - - gcc_assert (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE - || GET_CODE (op) == CONST_VECTOR); - - if (GET_CODE (op) == CONST_VECTOR - && !const_vector_immediate_p (op)) - return 0; - - if (GET_MODE (op) != VOIDmode) - mode = GET_MODE (op); - - constant_to_array (mode, op, arr); - - mode = GET_MODE_INNER (mode); - - bytes = GET_MODE_SIZE (mode); - int_mode = int_mode_for_mode (mode).require (); - - /* Check that bytes are repeated. */ - for (i = bytes; i < 16; i += bytes) - for (j = 0; j < bytes; j++) - if (arr[j] != arr[i + j]) - return 0; - - val = arr[0]; - for (j = 1; j < bytes; j++) - val = (val << 8) | arr[j]; - - val = trunc_int_for_mode (val, int_mode); - - /* Currently, we only handle SFmode */ - gcc_assert (mode == SFmode); - if (mode == SFmode) - { - int exp = (val >> 23) - 127; - return val > 0 && (val & 0x007fffff) == 0 - && exp >= low && exp <= high; - } - return FALSE; -} - -/* Return true if X is a SYMBOL_REF to an __ea qualified variable. */ - -static bool -ea_symbol_ref_p (const_rtx x) -{ - tree decl; - - if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS) - { - rtx plus = XEXP (x, 0); - rtx op0 = XEXP (plus, 0); - rtx op1 = XEXP (plus, 1); - if (GET_CODE (op1) == CONST_INT) - x = op0; - } - - return (GET_CODE (x) == SYMBOL_REF - && (decl = SYMBOL_REF_DECL (x)) != 0 - && TREE_CODE (decl) == VAR_DECL - && TYPE_ADDR_SPACE (TREE_TYPE (decl))); -} - -/* We accept: - - any 32-bit constant (SImode, SFmode) - - any constant that can be generated with fsmbi (any mode) - - a 64-bit constant where the high and low bits are identical - (DImode, DFmode) - - a 128-bit constant where the four 32-bit words match. */ -bool -spu_legitimate_constant_p (machine_mode mode, rtx x) -{ - subrtx_iterator::array_type array; - if (GET_CODE (x) == HIGH) - x = XEXP (x, 0); - - /* Reject any __ea qualified reference. These can't appear in - instructions but must be forced to the constant pool. */ - FOR_EACH_SUBRTX (iter, array, x, ALL) - if (ea_symbol_ref_p (*iter)) - return 0; - - /* V4SI with all identical symbols is valid. */ - if (!flag_pic - && mode == V4SImode - && (GET_CODE (CONST_VECTOR_ELT (x, 0)) == SYMBOL_REF - || GET_CODE (CONST_VECTOR_ELT (x, 0)) == LABEL_REF - || GET_CODE (CONST_VECTOR_ELT (x, 0)) == CONST)) - return const_vec_duplicate_p (x); - - if (GET_CODE (x) == CONST_VECTOR - && !const_vector_immediate_p (x)) - return 0; - return 1; -} - -/* Valid address are: - - symbol_ref, label_ref, const - - reg - - reg + const_int, where const_int is 16 byte aligned - - reg + reg, alignment doesn't matter - The alignment matters in the reg+const case because lqd and stqd - ignore the 4 least significant bits of the const. We only care about - 16 byte modes because the expand phase will change all smaller MEM - references to TImode. */ -static bool -spu_legitimate_address_p (machine_mode mode, - rtx x, bool reg_ok_strict) -{ - int aligned = GET_MODE_SIZE (mode) >= 16; - if (aligned - && GET_CODE (x) == AND - && GET_CODE (XEXP (x, 1)) == CONST_INT - && INTVAL (XEXP (x, 1)) == (HOST_WIDE_INT) - 16) - x = XEXP (x, 0); - switch (GET_CODE (x)) - { - case LABEL_REF: - return !TARGET_LARGE_MEM; - - case SYMBOL_REF: - case CONST: - /* Keep __ea references until reload so that spu_expand_mov can see them - in MEMs. */ - if (ea_symbol_ref_p (x)) - return !reload_in_progress && !reload_completed; - return !TARGET_LARGE_MEM; - - case CONST_INT: - return INTVAL (x) >= 0 && INTVAL (x) <= 0x3ffff; - - case SUBREG: - x = XEXP (x, 0); - if (!REG_P (x)) - return 0; - /* FALLTHRU */ - - case REG: - return INT_REG_OK_FOR_BASE_P (x, reg_ok_strict); - - case PLUS: - case LO_SUM: - { - rtx op0 = XEXP (x, 0); - rtx op1 = XEXP (x, 1); - if (GET_CODE (op0) == SUBREG) - op0 = XEXP (op0, 0); - if (GET_CODE (op1) == SUBREG) - op1 = XEXP (op1, 0); - if (GET_CODE (op0) == REG - && INT_REG_OK_FOR_BASE_P (op0, reg_ok_strict) - && GET_CODE (op1) == CONST_INT - && ((INTVAL (op1) >= -0x2000 && INTVAL (op1) <= 0x1fff) - /* If virtual registers are involved, the displacement will - change later on anyway, so checking would be premature. - Reload will make sure the final displacement after - register elimination is OK. */ - || op0 == arg_pointer_rtx - || op0 == frame_pointer_rtx - || op0 == virtual_stack_vars_rtx) - && (!aligned || (INTVAL (op1) & 15) == 0)) - return TRUE; - if (GET_CODE (op0) == REG - && INT_REG_OK_FOR_BASE_P (op0, reg_ok_strict) - && GET_CODE (op1) == REG - && INT_REG_OK_FOR_INDEX_P (op1, reg_ok_strict)) - return TRUE; - } - break; - - default: - break; - } - return FALSE; -} - -/* Like spu_legitimate_address_p, except with named addresses. */ -static bool -spu_addr_space_legitimate_address_p (machine_mode mode, rtx x, - bool reg_ok_strict, addr_space_t as) -{ - if (as == ADDR_SPACE_EA) - return (REG_P (x) && (GET_MODE (x) == EAmode)); - - else if (as != ADDR_SPACE_GENERIC) - gcc_unreachable (); - - return spu_legitimate_address_p (mode, x, reg_ok_strict); -} - -/* When the address is reg + const_int, force the const_int into a - register. */ -static rtx -spu_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, - machine_mode mode ATTRIBUTE_UNUSED) -{ - rtx op0, op1; - /* Make sure both operands are registers. */ - if (GET_CODE (x) == PLUS) - { - op0 = XEXP (x, 0); - op1 = XEXP (x, 1); - if (ALIGNED_SYMBOL_REF_P (op0)) - { - op0 = force_reg (Pmode, op0); - mark_reg_pointer (op0, 128); - } - else if (GET_CODE (op0) != REG) - op0 = force_reg (Pmode, op0); - if (ALIGNED_SYMBOL_REF_P (op1)) - { - op1 = force_reg (Pmode, op1); - mark_reg_pointer (op1, 128); - } - else if (GET_CODE (op1) != REG) - op1 = force_reg (Pmode, op1); - x = gen_rtx_PLUS (Pmode, op0, op1); - } - return x; -} - -/* Like spu_legitimate_address, except with named address support. */ -static rtx -spu_addr_space_legitimize_address (rtx x, rtx oldx, machine_mode mode, - addr_space_t as) -{ - if (as != ADDR_SPACE_GENERIC) - return x; - - return spu_legitimize_address (x, oldx, mode); -} - -/* Reload reg + const_int for out-of-range displacements. */ -rtx -spu_legitimize_reload_address (rtx ad, machine_mode mode ATTRIBUTE_UNUSED, - int opnum, int type) -{ - bool removed_and = false; - - if (GET_CODE (ad) == AND - && CONST_INT_P (XEXP (ad, 1)) - && INTVAL (XEXP (ad, 1)) == (HOST_WIDE_INT) - 16) - { - ad = XEXP (ad, 0); - removed_and = true; - } - - if (GET_CODE (ad) == PLUS - && REG_P (XEXP (ad, 0)) - && CONST_INT_P (XEXP (ad, 1)) - && !(INTVAL (XEXP (ad, 1)) >= -0x2000 - && INTVAL (XEXP (ad, 1)) <= 0x1fff)) - { - /* Unshare the sum. */ - ad = copy_rtx (ad); - - /* Reload the displacement. */ - push_reload (XEXP (ad, 1), NULL_RTX, &XEXP (ad, 1), NULL, - BASE_REG_CLASS, GET_MODE (ad), VOIDmode, 0, 0, - opnum, (enum reload_type) type); - - /* Add back AND for alignment if we stripped it. */ - if (removed_and) - ad = gen_rtx_AND (GET_MODE (ad), ad, GEN_INT (-16)); - - return ad; - } - - return NULL_RTX; -} - -/* Handle an attribute requiring a FUNCTION_DECL; arguments as in - struct attribute_spec.handler. */ -static tree -spu_handle_fndecl_attribute (tree * node, - tree name, - tree args ATTRIBUTE_UNUSED, - int flags ATTRIBUTE_UNUSED, bool * no_add_attrs) -{ - if (TREE_CODE (*node) != FUNCTION_DECL) - { - warning (0, "%qE attribute only applies to functions", - name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle the "vector" attribute. */ -static tree -spu_handle_vector_attribute (tree * node, tree name, - tree args ATTRIBUTE_UNUSED, - int flags ATTRIBUTE_UNUSED, bool * no_add_attrs) -{ - tree type = *node, result = NULL_TREE; - machine_mode mode; - int unsigned_p; - - while (POINTER_TYPE_P (type) - || TREE_CODE (type) == FUNCTION_TYPE - || TREE_CODE (type) == METHOD_TYPE || TREE_CODE (type) == ARRAY_TYPE) - type = TREE_TYPE (type); - - mode = TYPE_MODE (type); - - unsigned_p = TYPE_UNSIGNED (type); - switch (mode) - { - case E_DImode: - result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node); - break; - case E_SImode: - result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node); - break; - case E_HImode: - result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node); - break; - case E_QImode: - result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node); - break; - case E_SFmode: - result = V4SF_type_node; - break; - case E_DFmode: - result = V2DF_type_node; - break; - default: - break; - } - - /* Propagate qualifiers attached to the element type - onto the vector type. */ - if (result && result != type && TYPE_QUALS (type)) - result = build_qualified_type (result, TYPE_QUALS (type)); - - *no_add_attrs = true; /* No need to hang on to the attribute. */ - - if (!result) - warning (0, "%qE attribute ignored", name); - else - *node = lang_hooks.types.reconstruct_complex_type (*node, result); - - return NULL_TREE; -} - -/* Return nonzero if FUNC is a naked function. */ -static int -spu_naked_function_p (tree func) -{ - tree a; - - if (TREE_CODE (func) != FUNCTION_DECL) - abort (); - - a = lookup_attribute ("naked", DECL_ATTRIBUTES (func)); - return a != NULL_TREE; -} - -int -spu_initial_elimination_offset (int from, int to) -{ - int saved_regs_size = spu_saved_regs_size (); - int sp_offset = 0; - if (!crtl->is_leaf || crtl->outgoing_args_size - || get_frame_size () || saved_regs_size) - sp_offset = STACK_POINTER_OFFSET; - if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM) - return get_frame_size () + crtl->outgoing_args_size + sp_offset; - else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM) - return get_frame_size (); - else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM) - return sp_offset + crtl->outgoing_args_size - + get_frame_size () + saved_regs_size + STACK_POINTER_OFFSET; - else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM) - return get_frame_size () + saved_regs_size + sp_offset; - else - gcc_unreachable (); -} - -rtx -spu_function_value (const_tree type, const_tree func ATTRIBUTE_UNUSED) -{ - machine_mode mode = TYPE_MODE (type); - int byte_size = ((mode == BLKmode) - ? int_size_in_bytes (type) : GET_MODE_SIZE (mode)); - - /* Make sure small structs are left justified in a register. */ - if ((mode == BLKmode || (type && AGGREGATE_TYPE_P (type))) - && byte_size <= UNITS_PER_WORD * MAX_REGISTER_RETURN && byte_size > 0) - { - machine_mode smode; - rtvec v; - int i; - int nregs = (byte_size + UNITS_PER_WORD - 1) / UNITS_PER_WORD; - int n = byte_size / UNITS_PER_WORD; - v = rtvec_alloc (nregs); - for (i = 0; i < n; i++) - { - RTVEC_ELT (v, i) = gen_rtx_EXPR_LIST (VOIDmode, - gen_rtx_REG (TImode, - FIRST_RETURN_REGNUM - + i), - GEN_INT (UNITS_PER_WORD * i)); - byte_size -= UNITS_PER_WORD; - } - - if (n < nregs) - { - if (byte_size < 4) - byte_size = 4; - smode = smallest_int_mode_for_size (byte_size * BITS_PER_UNIT); - RTVEC_ELT (v, n) = - gen_rtx_EXPR_LIST (VOIDmode, - gen_rtx_REG (smode, FIRST_RETURN_REGNUM + n), - GEN_INT (UNITS_PER_WORD * n)); - } - return gen_rtx_PARALLEL (mode, v); - } - return gen_rtx_REG (mode, FIRST_RETURN_REGNUM); -} - -static rtx -spu_function_arg (cumulative_args_t cum_v, const function_arg_info &arg) -{ - CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); - int byte_size; - - if (*cum >= MAX_REGISTER_ARGS) - return 0; - - byte_size = arg.promoted_size_in_bytes (); - - /* The ABI does not allow parameters to be passed partially in - reg and partially in stack. */ - if ((*cum + (byte_size + 15) / 16) > MAX_REGISTER_ARGS) - return 0; - - /* Make sure small structs are left justified in a register. */ - if ((arg.mode == BLKmode || arg.aggregate_type_p ()) - && byte_size < UNITS_PER_WORD && byte_size > 0) - { - machine_mode smode; - rtx gr_reg; - if (byte_size < 4) - byte_size = 4; - smode = smallest_int_mode_for_size (byte_size * BITS_PER_UNIT); - gr_reg = gen_rtx_EXPR_LIST (VOIDmode, - gen_rtx_REG (smode, FIRST_ARG_REGNUM + *cum), - const0_rtx); - return gen_rtx_PARALLEL (arg.mode, gen_rtvec (1, gr_reg)); - } - else - return gen_rtx_REG (arg.mode, FIRST_ARG_REGNUM + *cum); -} - -static void -spu_function_arg_advance (cumulative_args_t cum_v, - const function_arg_info &arg) -{ - CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); - - *cum += (arg.type && TREE_CODE (TYPE_SIZE (arg.type)) != INTEGER_CST - ? 1 - : arg.mode == BLKmode - ? ((int_size_in_bytes (arg.type) + 15) / 16) - : arg.mode == VOIDmode - ? 1 - : spu_hard_regno_nregs (FIRST_ARG_REGNUM, arg.mode)); -} - -/* Implement TARGET_FUNCTION_ARG_OFFSET. The SPU ABI wants 32/64-bit - types at offset 0 in the quad-word on the stack. 8/16-bit types - should be at offsets 3/2 respectively. */ - -static HOST_WIDE_INT -spu_function_arg_offset (machine_mode mode, const_tree type) -{ - if (type && INTEGRAL_TYPE_P (type) && GET_MODE_SIZE (mode) < 4) - return 4 - GET_MODE_SIZE (mode); - return 0; -} - -/* Implement TARGET_FUNCTION_ARG_PADDING. */ - -static pad_direction -spu_function_arg_padding (machine_mode, const_tree) -{ - return PAD_UPWARD; -} - -/* Variable sized types are passed by reference. */ -static bool -spu_pass_by_reference (cumulative_args_t, const function_arg_info &arg) -{ - return arg.type && TREE_CODE (TYPE_SIZE (arg.type)) != INTEGER_CST; -} - - -/* Var args. */ - -/* Create and return the va_list datatype. - - On SPU, va_list is an array type equivalent to - - typedef struct __va_list_tag - { - void *__args __attribute__((__aligned(16))); - void *__skip __attribute__((__aligned(16))); - - } va_list[1]; - - where __args points to the arg that will be returned by the next - va_arg(), and __skip points to the previous stack frame such that - when __args == __skip we should advance __args by 32 bytes. */ -static tree -spu_build_builtin_va_list (void) -{ - tree f_args, f_skip, record, type_decl; - bool owp; - - record = (*lang_hooks.types.make_type) (RECORD_TYPE); - - type_decl = - build_decl (BUILTINS_LOCATION, - TYPE_DECL, get_identifier ("__va_list_tag"), record); - - f_args = build_decl (BUILTINS_LOCATION, - FIELD_DECL, get_identifier ("__args"), ptr_type_node); - f_skip = build_decl (BUILTINS_LOCATION, - FIELD_DECL, get_identifier ("__skip"), ptr_type_node); - - DECL_FIELD_CONTEXT (f_args) = record; - SET_DECL_ALIGN (f_args, 128); - DECL_USER_ALIGN (f_args) = 1; - - DECL_FIELD_CONTEXT (f_skip) = record; - SET_DECL_ALIGN (f_skip, 128); - DECL_USER_ALIGN (f_skip) = 1; - - TYPE_STUB_DECL (record) = type_decl; - TYPE_NAME (record) = type_decl; - TYPE_FIELDS (record) = f_args; - DECL_CHAIN (f_args) = f_skip; - - /* We know this is being padded and we want it too. It is an internal - type so hide the warnings from the user. */ - owp = warn_padded; - warn_padded = false; - - layout_type (record); - - warn_padded = owp; - - /* The correct type is an array type of one element. */ - return build_array_type (record, build_index_type (size_zero_node)); -} - -/* Implement va_start by filling the va_list structure VALIST. - NEXTARG points to the first anonymous stack argument. - - The following global variables are used to initialize - the va_list structure: - - crtl->args.info; - the CUMULATIVE_ARGS for this function - - crtl->args.arg_offset_rtx: - holds the offset of the first anonymous stack argument - (relative to the virtual arg pointer). */ - -static void -spu_va_start (tree valist, rtx nextarg) -{ - tree f_args, f_skip; - tree args, skip, t; - - f_args = TYPE_FIELDS (TREE_TYPE (va_list_type_node)); - f_skip = DECL_CHAIN (f_args); - - valist = build_simple_mem_ref (valist); - args = - build3 (COMPONENT_REF, TREE_TYPE (f_args), valist, f_args, NULL_TREE); - skip = - build3 (COMPONENT_REF, TREE_TYPE (f_skip), valist, f_skip, NULL_TREE); - - /* Find the __args area. */ - t = make_tree (TREE_TYPE (args), nextarg); - if (crtl->args.pretend_args_size > 0) - t = fold_build_pointer_plus_hwi (t, -STACK_POINTER_OFFSET); - t = build2 (MODIFY_EXPR, TREE_TYPE (args), args, t); - TREE_SIDE_EFFECTS (t) = 1; - expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); - - /* Find the __skip area. */ - t = make_tree (TREE_TYPE (skip), virtual_incoming_args_rtx); - t = fold_build_pointer_plus_hwi (t, (crtl->args.pretend_args_size - - STACK_POINTER_OFFSET)); - t = build2 (MODIFY_EXPR, TREE_TYPE (skip), skip, t); - TREE_SIDE_EFFECTS (t) = 1; - expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); -} - -/* Gimplify va_arg by updating the va_list structure - VALIST as required to retrieve an argument of type - TYPE, and returning that argument. - - ret = va_arg(VALIST, TYPE); - - generates code equivalent to: - - paddedsize = (sizeof(TYPE) + 15) & -16; - if (VALIST.__args + paddedsize > VALIST.__skip - && VALIST.__args <= VALIST.__skip) - addr = VALIST.__skip + 32; - else - addr = VALIST.__args; - VALIST.__args = addr + paddedsize; - ret = *(TYPE *)addr; - */ -static tree -spu_gimplify_va_arg_expr (tree valist, tree type, gimple_seq * pre_p, - gimple_seq * post_p ATTRIBUTE_UNUSED) -{ - tree f_args, f_skip; - tree args, skip; - HOST_WIDE_INT size, rsize; - tree addr, tmp; - bool pass_by_reference_p; - - f_args = TYPE_FIELDS (TREE_TYPE (va_list_type_node)); - f_skip = DECL_CHAIN (f_args); - - args = - build3 (COMPONENT_REF, TREE_TYPE (f_args), valist, f_args, NULL_TREE); - skip = - build3 (COMPONENT_REF, TREE_TYPE (f_skip), valist, f_skip, NULL_TREE); - - addr = create_tmp_var (ptr_type_node, "va_arg"); - - /* if an object is dynamically sized, a pointer to it is passed - instead of the object itself. */ - pass_by_reference_p = pass_va_arg_by_reference (type); - if (pass_by_reference_p) - type = build_pointer_type (type); - size = int_size_in_bytes (type); - rsize = ((size + UNITS_PER_WORD - 1) / UNITS_PER_WORD) * UNITS_PER_WORD; - - /* build conditional expression to calculate addr. The expression - will be gimplified later. */ - tmp = fold_build_pointer_plus_hwi (unshare_expr (args), rsize); - tmp = build2 (TRUTH_AND_EXPR, boolean_type_node, - build2 (GT_EXPR, boolean_type_node, tmp, unshare_expr (skip)), - build2 (LE_EXPR, boolean_type_node, unshare_expr (args), - unshare_expr (skip))); - - tmp = build3 (COND_EXPR, ptr_type_node, tmp, - fold_build_pointer_plus_hwi (unshare_expr (skip), 32), - unshare_expr (args)); - - gimplify_assign (addr, tmp, pre_p); - - /* update VALIST.__args */ - tmp = fold_build_pointer_plus_hwi (addr, rsize); - gimplify_assign (unshare_expr (args), tmp, pre_p); - - addr = fold_convert (build_pointer_type_for_mode (type, ptr_mode, true), - addr); - - if (pass_by_reference_p) - addr = build_va_arg_indirect_ref (addr); - - return build_va_arg_indirect_ref (addr); -} - -/* Save parameter registers starting with the register that corresponds - to the first unnamed parameters. If the first unnamed parameter is - in the stack then save no registers. Set pretend_args_size to the - amount of space needed to save the registers. */ -static void -spu_setup_incoming_varargs (cumulative_args_t cum, - const function_arg_info &arg, - int *pretend_size, int no_rtl) -{ - if (!no_rtl) - { - rtx tmp; - int regno; - int offset; - int ncum = *get_cumulative_args (cum); - - /* cum currently points to the last named argument, we want to - start at the next argument. */ - spu_function_arg_advance (pack_cumulative_args (&ncum), arg); - - offset = -STACK_POINTER_OFFSET; - for (regno = ncum; regno < MAX_REGISTER_ARGS; regno++) - { - tmp = gen_frame_mem (V4SImode, - plus_constant (Pmode, virtual_incoming_args_rtx, - offset)); - emit_move_insn (tmp, - gen_rtx_REG (V4SImode, FIRST_ARG_REGNUM + regno)); - offset += 16; - } - *pretend_size = offset + STACK_POINTER_OFFSET; - } -} - -static void -spu_conditional_register_usage (void) -{ - if (flag_pic) - { - fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; - call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; - } -} - -/* This is called any time we inspect the alignment of a register for - addresses. */ -static int -reg_aligned_for_addr (rtx x) -{ - int regno = - REGNO (x) < FIRST_PSEUDO_REGISTER ? ORIGINAL_REGNO (x) : REGNO (x); - return REGNO_POINTER_ALIGN (regno) >= 128; -} - -/* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF - into its SYMBOL_REF_FLAGS. */ -static void -spu_encode_section_info (tree decl, rtx rtl, int first) -{ - default_encode_section_info (decl, rtl, first); - - /* If a variable has a forced alignment to < 16 bytes, mark it with - SYMBOL_FLAG_ALIGN1. */ - if (TREE_CODE (decl) == VAR_DECL - && DECL_USER_ALIGN (decl) && DECL_ALIGN (decl) < 128) - SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_ALIGN1; -} - -/* Return TRUE if we are certain the mem refers to a complete object - which is both 16-byte aligned and padded to a 16-byte boundary. This - would make it safe to store with a single instruction. - We guarantee the alignment and padding for static objects by aligning - all of them to 16-bytes. (DATA_ALIGNMENT and TARGET_CONSTANT_ALIGNMENT.) - FIXME: We currently cannot guarantee this for objects on the stack - because assign_parm_setup_stack calls assign_stack_local with the - alignment of the parameter mode and in that case the alignment never - gets adjusted by LOCAL_ALIGNMENT. */ -static int -store_with_one_insn_p (rtx mem) -{ - machine_mode mode = GET_MODE (mem); - rtx addr = XEXP (mem, 0); - if (mode == BLKmode) - return 0; - if (GET_MODE_SIZE (mode) >= 16) - return 1; - /* Only static objects. */ - if (GET_CODE (addr) == SYMBOL_REF) - { - /* We use the associated declaration to make sure the access is - referring to the whole object. - We check both MEM_EXPR and SYMBOL_REF_DECL. I'm not sure - if it is necessary. Will there be cases where one exists, and - the other does not? Will there be cases where both exist, but - have different types? */ - tree decl = MEM_EXPR (mem); - if (decl - && TREE_CODE (decl) == VAR_DECL - && GET_MODE (mem) == TYPE_MODE (TREE_TYPE (decl))) - return 1; - decl = SYMBOL_REF_DECL (addr); - if (decl - && TREE_CODE (decl) == VAR_DECL - && GET_MODE (mem) == TYPE_MODE (TREE_TYPE (decl))) - return 1; - } - return 0; -} - -/* Return 1 when the address is not valid for a simple load and store as - required by the '_mov*' patterns. We could make this less strict - for loads, but we prefer mem's to look the same so they are more - likely to be merged. */ -static int -address_needs_split (rtx mem) -{ - if (GET_MODE_SIZE (GET_MODE (mem)) < 16 - && (GET_MODE_SIZE (GET_MODE (mem)) < 4 - || !(store_with_one_insn_p (mem) - || mem_is_padded_component_ref (mem)))) - return 1; - - return 0; -} - -static GTY(()) rtx cache_fetch; /* __cache_fetch function */ -static GTY(()) rtx cache_fetch_dirty; /* __cache_fetch_dirty function */ -static alias_set_type ea_alias_set = -1; /* alias set for __ea memory */ - -/* MEM is known to be an __ea qualified memory access. Emit a call to - fetch the ppu memory to local store, and return its address in local - store. */ - -static void -ea_load_store (rtx mem, bool is_store, rtx ea_addr, rtx data_addr) -{ - if (is_store) - { - rtx ndirty = GEN_INT (GET_MODE_SIZE (GET_MODE (mem))); - if (!cache_fetch_dirty) - cache_fetch_dirty = init_one_libfunc ("__cache_fetch_dirty"); - emit_library_call_value (cache_fetch_dirty, data_addr, LCT_NORMAL, Pmode, - ea_addr, EAmode, ndirty, SImode); - } - else - { - if (!cache_fetch) - cache_fetch = init_one_libfunc ("__cache_fetch"); - emit_library_call_value (cache_fetch, data_addr, LCT_NORMAL, Pmode, - ea_addr, EAmode); - } -} - -/* Like ea_load_store, but do the cache tag comparison and, for stores, - dirty bit marking, inline. - - The cache control data structure is an array of - - struct __cache_tag_array - { - unsigned int tag_lo[4]; - unsigned int tag_hi[4]; - void *data_pointer[4]; - int reserved[4]; - vector unsigned short dirty_bits[4]; - } */ - -static void -ea_load_store_inline (rtx mem, bool is_store, rtx ea_addr, rtx data_addr) -{ - rtx ea_addr_si; - HOST_WIDE_INT v; - rtx tag_size_sym = gen_rtx_SYMBOL_REF (Pmode, "__cache_tag_array_size"); - rtx tag_arr_sym = gen_rtx_SYMBOL_REF (Pmode, "__cache_tag_array"); - rtx index_mask = gen_reg_rtx (SImode); - rtx tag_arr = gen_reg_rtx (Pmode); - rtx splat_mask = gen_reg_rtx (TImode); - rtx splat = gen_reg_rtx (V4SImode); - rtx splat_hi = NULL_RTX; - rtx tag_index = gen_reg_rtx (Pmode); - rtx block_off = gen_reg_rtx (SImode); - rtx tag_addr = gen_reg_rtx (Pmode); - rtx tag = gen_reg_rtx (V4SImode); - rtx cache_tag = gen_reg_rtx (V4SImode); - rtx cache_tag_hi = NULL_RTX; - rtx cache_ptrs = gen_reg_rtx (TImode); - rtx cache_ptrs_si = gen_reg_rtx (SImode); - rtx tag_equal = gen_reg_rtx (V4SImode); - rtx tag_equal_hi = NULL_RTX; - rtx tag_eq_pack = gen_reg_rtx (V4SImode); - rtx tag_eq_pack_si = gen_reg_rtx (SImode); - rtx eq_index = gen_reg_rtx (SImode); - rtx bcomp, hit_label, hit_ref, cont_label; - rtx_insn *insn; - - if (spu_ea_model != 32) - { - splat_hi = gen_reg_rtx (V4SImode); - cache_tag_hi = gen_reg_rtx (V4SImode); - tag_equal_hi = gen_reg_rtx (V4SImode); - } - - emit_move_insn (index_mask, plus_constant (Pmode, tag_size_sym, -128)); - emit_move_insn (tag_arr, tag_arr_sym); - v = 0x0001020300010203LL; - emit_move_insn (splat_mask, immed_double_const (v, v, TImode)); - ea_addr_si = ea_addr; - if (spu_ea_model != 32) - ea_addr_si = convert_to_mode (SImode, ea_addr, 1); - - /* tag_index = ea_addr & (tag_array_size - 128) */ - emit_insn (gen_andsi3 (tag_index, ea_addr_si, index_mask)); - - /* splat ea_addr to all 4 slots. */ - emit_insn (gen_shufb (splat, ea_addr_si, ea_addr_si, splat_mask)); - /* Similarly for high 32 bits of ea_addr. */ - if (spu_ea_model != 32) - emit_insn (gen_shufb (splat_hi, ea_addr, ea_addr, splat_mask)); - - /* block_off = ea_addr & 127 */ - emit_insn (gen_andsi3 (block_off, ea_addr_si, spu_const (SImode, 127))); - - /* tag_addr = tag_arr + tag_index */ - emit_insn (gen_addsi3 (tag_addr, tag_arr, tag_index)); - - /* Read cache tags. */ - emit_move_insn (cache_tag, gen_rtx_MEM (V4SImode, tag_addr)); - if (spu_ea_model != 32) - emit_move_insn (cache_tag_hi, gen_rtx_MEM (V4SImode, - plus_constant (Pmode, - tag_addr, 16))); - - /* tag = ea_addr & -128 */ - emit_insn (gen_andv4si3 (tag, splat, spu_const (V4SImode, -128))); - - /* Read all four cache data pointers. */ - emit_move_insn (cache_ptrs, gen_rtx_MEM (TImode, - plus_constant (Pmode, - tag_addr, 32))); - - /* Compare tags. */ - emit_insn (gen_ceq_v4si (tag_equal, tag, cache_tag)); - if (spu_ea_model != 32) - { - emit_insn (gen_ceq_v4si (tag_equal_hi, splat_hi, cache_tag_hi)); - emit_insn (gen_andv4si3 (tag_equal, tag_equal, tag_equal_hi)); - } - - /* At most one of the tags compare equal, so tag_equal has one - 32-bit slot set to all 1's, with the other slots all zero. - gbb picks off low bit from each byte in the 128-bit registers, - so tag_eq_pack is one of 0xf000, 0x0f00, 0x00f0, 0x000f, assuming - we have a hit. */ - emit_insn (gen_spu_gbb (tag_eq_pack, spu_gen_subreg (V16QImode, tag_equal))); - emit_insn (gen_spu_convert (tag_eq_pack_si, tag_eq_pack)); - - /* So counting leading zeros will set eq_index to 16, 20, 24 or 28. */ - emit_insn (gen_clzsi2 (eq_index, tag_eq_pack_si)); - - /* Allowing us to rotate the corresponding cache data pointer to slot0. - (rotating eq_index mod 16 bytes). */ - emit_insn (gen_rotqby_ti (cache_ptrs, cache_ptrs, eq_index)); - emit_insn (gen_spu_convert (cache_ptrs_si, cache_ptrs)); - - /* Add block offset to form final data address. */ - emit_insn (gen_addsi3 (data_addr, cache_ptrs_si, block_off)); - - /* Check that we did hit. */ - hit_label = gen_label_rtx (); - hit_ref = gen_rtx_LABEL_REF (VOIDmode, hit_label); - bcomp = gen_rtx_NE (SImode, tag_eq_pack_si, const0_rtx); - insn = emit_jump_insn (gen_rtx_SET (pc_rtx, - gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp, - hit_ref, pc_rtx))); - /* Say that this branch is very likely to happen. */ - add_reg_br_prob_note (insn, profile_probability::very_likely ()); - - ea_load_store (mem, is_store, ea_addr, data_addr); - cont_label = gen_label_rtx (); - emit_jump_insn (gen_jump (cont_label)); - emit_barrier (); - - emit_label (hit_label); - - if (is_store) - { - HOST_WIDE_INT v_hi; - rtx dirty_bits = gen_reg_rtx (TImode); - rtx dirty_off = gen_reg_rtx (SImode); - rtx dirty_128 = gen_reg_rtx (TImode); - rtx neg_block_off = gen_reg_rtx (SImode); - - /* Set up mask with one dirty bit per byte of the mem we are - writing, starting from top bit. */ - v_hi = v = -1; - v <<= (128 - GET_MODE_SIZE (GET_MODE (mem))) & 63; - if ((128 - GET_MODE_SIZE (GET_MODE (mem))) >= 64) - { - v_hi = v; - v = 0; - } - emit_move_insn (dirty_bits, immed_double_const (v, v_hi, TImode)); - - /* Form index into cache dirty_bits. eq_index is one of - 0x10, 0x14, 0x18 or 0x1c. Multiplying by 4 gives us - 0x40, 0x50, 0x60 or 0x70 which just happens to be the - offset to each of the four dirty_bits elements. */ - emit_insn (gen_ashlsi3 (dirty_off, eq_index, spu_const (SImode, 2))); - - emit_insn (gen_spu_lqx (dirty_128, tag_addr, dirty_off)); - - /* Rotate bit mask to proper bit. */ - emit_insn (gen_negsi2 (neg_block_off, block_off)); - emit_insn (gen_rotqbybi_ti (dirty_bits, dirty_bits, neg_block_off)); - emit_insn (gen_rotqbi_ti (dirty_bits, dirty_bits, neg_block_off)); - - /* Or in the new dirty bits. */ - emit_insn (gen_iorti3 (dirty_128, dirty_bits, dirty_128)); - - /* Store. */ - emit_insn (gen_spu_stqx (dirty_128, tag_addr, dirty_off)); - } - - emit_label (cont_label); -} - -static rtx -expand_ea_mem (rtx mem, bool is_store) -{ - rtx ea_addr; - rtx data_addr = gen_reg_rtx (Pmode); - rtx new_mem; - - ea_addr = force_reg (EAmode, XEXP (mem, 0)); - if (optimize_size || optimize == 0) - ea_load_store (mem, is_store, ea_addr, data_addr); - else - ea_load_store_inline (mem, is_store, ea_addr, data_addr); - - if (ea_alias_set == -1) - ea_alias_set = new_alias_set (); - - /* We generate a new MEM RTX to refer to the copy of the data - in the cache. We do not copy memory attributes (except the - alignment) from the original MEM, as they may no longer apply - to the cache copy. */ - new_mem = gen_rtx_MEM (GET_MODE (mem), data_addr); - set_mem_alias_set (new_mem, ea_alias_set); - set_mem_align (new_mem, MIN (MEM_ALIGN (mem), 128 * 8)); - - return new_mem; -} - -int -spu_expand_mov (rtx * ops, machine_mode mode) -{ - if (GET_CODE (ops[0]) == SUBREG && !valid_subreg (ops[0])) - { - /* Perform the move in the destination SUBREG's inner mode. */ - ops[0] = SUBREG_REG (ops[0]); - mode = GET_MODE (ops[0]); - ops[1] = gen_lowpart_common (mode, ops[1]); - gcc_assert (ops[1]); - } - - if (GET_CODE (ops[1]) == SUBREG && !valid_subreg (ops[1])) - { - rtx from = SUBREG_REG (ops[1]); - scalar_int_mode imode = int_mode_for_mode (GET_MODE (from)).require (); - - gcc_assert (GET_MODE_CLASS (mode) == MODE_INT - && GET_MODE_CLASS (imode) == MODE_INT - && subreg_lowpart_p (ops[1])); - - if (GET_MODE_SIZE (imode) < 4) - imode = SImode; - if (imode != GET_MODE (from)) - from = gen_rtx_SUBREG (imode, from, 0); - - if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (imode)) - { - enum insn_code icode = convert_optab_handler (trunc_optab, - mode, imode); - emit_insn (GEN_FCN (icode) (ops[0], from)); - } - else - emit_insn (gen_extend_insn (ops[0], from, mode, imode, 1)); - return 1; - } - - /* At least one of the operands needs to be a register. */ - if ((reload_in_progress | reload_completed) == 0 - && !register_operand (ops[0], mode) && !register_operand (ops[1], mode)) - { - rtx temp = force_reg (mode, ops[1]); - emit_move_insn (ops[0], temp); - return 1; - } - if (reload_in_progress || reload_completed) - { - if (CONSTANT_P (ops[1])) - return spu_split_immediate (ops); - return 0; - } - - /* Catch the SImode immediates greater than 0x7fffffff, and sign - extend them. */ - if (GET_CODE (ops[1]) == CONST_INT) - { - HOST_WIDE_INT val = trunc_int_for_mode (INTVAL (ops[1]), mode); - if (val != INTVAL (ops[1])) - { - emit_move_insn (ops[0], GEN_INT (val)); - return 1; - } - } - if (MEM_P (ops[0])) - { - if (MEM_ADDR_SPACE (ops[0])) - ops[0] = expand_ea_mem (ops[0], true); - return spu_split_store (ops); - } - if (MEM_P (ops[1])) - { - if (MEM_ADDR_SPACE (ops[1])) - ops[1] = expand_ea_mem (ops[1], false); - return spu_split_load (ops); - } - - return 0; -} - -static void -spu_convert_move (rtx dst, rtx src) -{ - machine_mode mode = GET_MODE (dst); - machine_mode int_mode = int_mode_for_mode (mode).require (); - rtx reg; - gcc_assert (GET_MODE (src) == TImode); - reg = int_mode != mode ? gen_reg_rtx (int_mode) : dst; - emit_insn (gen_rtx_SET (reg, - gen_rtx_TRUNCATE (int_mode, - gen_rtx_LSHIFTRT (TImode, src, - GEN_INT (int_mode == DImode ? 64 : 96))))); - if (int_mode != mode) - { - reg = simplify_gen_subreg (mode, reg, int_mode, 0); - emit_move_insn (dst, reg); - } -} - -/* Load TImode values into DST0 and DST1 (when it is non-NULL) using - the address from SRC and SRC+16. Return a REG or CONST_INT that - specifies how many bytes to rotate the loaded registers, plus any - extra from EXTRA_ROTQBY. The address and rotate amounts are - normalized to improve merging of loads and rotate computations. */ -static rtx -spu_expand_load (rtx dst0, rtx dst1, rtx src, int extra_rotby) -{ - rtx addr = XEXP (src, 0); - rtx p0, p1, rot, addr0, addr1; - int rot_amt; - - rot = 0; - rot_amt = 0; - - if (MEM_ALIGN (src) >= 128) - /* Address is already aligned; simply perform a TImode load. */ ; - else if (GET_CODE (addr) == PLUS) - { - /* 8 cases: - aligned reg + aligned reg => lqx - aligned reg + unaligned reg => lqx, rotqby - aligned reg + aligned const => lqd - aligned reg + unaligned const => lqd, rotqbyi - unaligned reg + aligned reg => lqx, rotqby - unaligned reg + unaligned reg => lqx, a, rotqby (1 scratch) - unaligned reg + aligned const => lqd, rotqby - unaligned reg + unaligned const -> not allowed by legitimate address - */ - p0 = XEXP (addr, 0); - p1 = XEXP (addr, 1); - if (!reg_aligned_for_addr (p0)) - { - if (REG_P (p1) && !reg_aligned_for_addr (p1)) - { - rot = gen_reg_rtx (SImode); - emit_insn (gen_addsi3 (rot, p0, p1)); - } - else if (GET_CODE (p1) == CONST_INT && (INTVAL (p1) & 15)) - { - if (INTVAL (p1) > 0 - && REG_POINTER (p0) - && INTVAL (p1) * BITS_PER_UNIT - < REGNO_POINTER_ALIGN (REGNO (p0))) - { - rot = gen_reg_rtx (SImode); - emit_insn (gen_addsi3 (rot, p0, p1)); - addr = p0; - } - else - { - rtx x = gen_reg_rtx (SImode); - emit_move_insn (x, p1); - if (!spu_arith_operand (p1, SImode)) - p1 = x; - rot = gen_reg_rtx (SImode); - emit_insn (gen_addsi3 (rot, p0, p1)); - addr = gen_rtx_PLUS (Pmode, p0, x); - } - } - else - rot = p0; - } - else - { - if (GET_CODE (p1) == CONST_INT && (INTVAL (p1) & 15)) - { - rot_amt = INTVAL (p1) & 15; - if (INTVAL (p1) & -16) - { - p1 = GEN_INT (INTVAL (p1) & -16); - addr = gen_rtx_PLUS (SImode, p0, p1); - } - else - addr = p0; - } - else if (REG_P (p1) && !reg_aligned_for_addr (p1)) - rot = p1; - } - } - else if (REG_P (addr)) - { - if (!reg_aligned_for_addr (addr)) - rot = addr; - } - else if (GET_CODE (addr) == CONST) - { - if (GET_CODE (XEXP (addr, 0)) == PLUS - && ALIGNED_SYMBOL_REF_P (XEXP (XEXP (addr, 0), 0)) - && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT) - { - rot_amt = INTVAL (XEXP (XEXP (addr, 0), 1)); - if (rot_amt & -16) - addr = gen_rtx_CONST (Pmode, - gen_rtx_PLUS (Pmode, - XEXP (XEXP (addr, 0), 0), - GEN_INT (rot_amt & -16))); - else - addr = XEXP (XEXP (addr, 0), 0); - } - else - { - rot = gen_reg_rtx (Pmode); - emit_move_insn (rot, addr); - } - } - else if (GET_CODE (addr) == CONST_INT) - { - rot_amt = INTVAL (addr); - addr = GEN_INT (rot_amt & -16); - } - else if (!ALIGNED_SYMBOL_REF_P (addr)) - { - rot = gen_reg_rtx (Pmode); - emit_move_insn (rot, addr); - } - - rot_amt += extra_rotby; - - rot_amt &= 15; - - if (rot && rot_amt) - { - rtx x = gen_reg_rtx (SImode); - emit_insn (gen_addsi3 (x, rot, GEN_INT (rot_amt))); - rot = x; - rot_amt = 0; - } - if (!rot && rot_amt) - rot = GEN_INT (rot_amt); - - addr0 = copy_rtx (addr); - addr0 = gen_rtx_AND (SImode, copy_rtx (addr), GEN_INT (-16)); - emit_insn (gen__movti (dst0, change_address (src, TImode, addr0))); - - if (dst1) - { - addr1 = plus_constant (SImode, copy_rtx (addr), 16); - addr1 = gen_rtx_AND (SImode, addr1, GEN_INT (-16)); - emit_insn (gen__movti (dst1, change_address (src, TImode, addr1))); - } - - return rot; -} - -int -spu_split_load (rtx * ops) -{ - machine_mode mode = GET_MODE (ops[0]); - rtx addr, load, rot; - int rot_amt; - - if (GET_MODE_SIZE (mode) >= 16) - return 0; - - addr = XEXP (ops[1], 0); - gcc_assert (GET_CODE (addr) != AND); - - if (!address_needs_split (ops[1])) - { - ops[1] = change_address (ops[1], TImode, addr); - load = gen_reg_rtx (TImode); - emit_insn (gen__movti (load, ops[1])); - spu_convert_move (ops[0], load); - return 1; - } - - rot_amt = GET_MODE_SIZE (mode) < 4 ? GET_MODE_SIZE (mode) - 4 : 0; - - load = gen_reg_rtx (TImode); - rot = spu_expand_load (load, 0, ops[1], rot_amt); - - if (rot) - emit_insn (gen_rotqby_ti (load, load, rot)); - - spu_convert_move (ops[0], load); - return 1; -} - -int -spu_split_store (rtx * ops) -{ - machine_mode mode = GET_MODE (ops[0]); - rtx reg; - rtx addr, p0, p1, p1_lo, smem; - int aform; - int scalar; - - if (GET_MODE_SIZE (mode) >= 16) - return 0; - - addr = XEXP (ops[0], 0); - gcc_assert (GET_CODE (addr) != AND); - - if (!address_needs_split (ops[0])) - { - reg = gen_reg_rtx (TImode); - emit_insn (gen_spu_convert (reg, ops[1])); - ops[0] = change_address (ops[0], TImode, addr); - emit_move_insn (ops[0], reg); - return 1; - } - - if (GET_CODE (addr) == PLUS) - { - /* 8 cases: - aligned reg + aligned reg => lqx, c?x, shuf, stqx - aligned reg + unaligned reg => lqx, c?x, shuf, stqx - aligned reg + aligned const => lqd, c?d, shuf, stqx - aligned reg + unaligned const => lqd, c?d, shuf, stqx - unaligned reg + aligned reg => lqx, c?x, shuf, stqx - unaligned reg + unaligned reg => lqx, c?x, shuf, stqx - unaligned reg + aligned const => lqd, c?d, shuf, stqx - unaligned reg + unaligned const -> lqx, c?d, shuf, stqx - */ - aform = 0; - p0 = XEXP (addr, 0); - p1 = p1_lo = XEXP (addr, 1); - if (REG_P (p0) && GET_CODE (p1) == CONST_INT) - { - p1_lo = GEN_INT (INTVAL (p1) & 15); - if (reg_aligned_for_addr (p0)) - { - p1 = GEN_INT (INTVAL (p1) & -16); - if (p1 == const0_rtx) - addr = p0; - else - addr = gen_rtx_PLUS (SImode, p0, p1); - } - else - { - rtx x = gen_reg_rtx (SImode); - emit_move_insn (x, p1); - addr = gen_rtx_PLUS (SImode, p0, x); - } - } - } - else if (REG_P (addr)) - { - aform = 0; - p0 = addr; - p1 = p1_lo = const0_rtx; - } - else - { - aform = 1; - p0 = gen_rtx_REG (SImode, STACK_POINTER_REGNUM); - p1 = 0; /* aform doesn't use p1 */ - p1_lo = addr; - if (ALIGNED_SYMBOL_REF_P (addr)) - p1_lo = const0_rtx; - else if (GET_CODE (addr) == CONST - && GET_CODE (XEXP (addr, 0)) == PLUS - && ALIGNED_SYMBOL_REF_P (XEXP (XEXP (addr, 0), 0)) - && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT) - { - HOST_WIDE_INT v = INTVAL (XEXP (XEXP (addr, 0), 1)); - if ((v & -16) != 0) - addr = gen_rtx_CONST (Pmode, - gen_rtx_PLUS (Pmode, - XEXP (XEXP (addr, 0), 0), - GEN_INT (v & -16))); - else - addr = XEXP (XEXP (addr, 0), 0); - p1_lo = GEN_INT (v & 15); - } - else if (GET_CODE (addr) == CONST_INT) - { - p1_lo = GEN_INT (INTVAL (addr) & 15); - addr = GEN_INT (INTVAL (addr) & -16); - } - else - { - p1_lo = gen_reg_rtx (SImode); - emit_move_insn (p1_lo, addr); - } - } - - gcc_assert (aform == 0 || aform == 1); - reg = gen_reg_rtx (TImode); - - scalar = store_with_one_insn_p (ops[0]); - if (!scalar) - { - /* We could copy the flags from the ops[0] MEM to mem here, - We don't because we want this load to be optimized away if - possible, and copying the flags will prevent that in certain - cases, e.g. consider the volatile flag. */ - - rtx pat = gen_reg_rtx (TImode); - rtx lmem = change_address (ops[0], TImode, copy_rtx (addr)); - set_mem_alias_set (lmem, 0); - emit_insn (gen_movti (reg, lmem)); - - if (!p0 || reg_aligned_for_addr (p0)) - p0 = stack_pointer_rtx; - if (!p1_lo) - p1_lo = const0_rtx; - - emit_insn (gen_cpat (pat, p0, p1_lo, GEN_INT (GET_MODE_SIZE (mode)))); - emit_insn (gen_shufb (reg, ops[1], reg, pat)); - } - else - { - if (GET_CODE (ops[1]) == REG) - emit_insn (gen_spu_convert (reg, ops[1])); - else if (GET_CODE (ops[1]) == SUBREG) - emit_insn (gen_spu_convert (reg, SUBREG_REG (ops[1]))); - else - abort (); - } - - if (GET_MODE_SIZE (mode) < 4 && scalar) - emit_insn (gen_ashlti3 - (reg, reg, GEN_INT (32 - GET_MODE_BITSIZE (mode)))); - - smem = change_address (ops[0], TImode, copy_rtx (addr)); - /* We can't use the previous alias set because the memory has changed - size and can potentially overlap objects of other types. */ - set_mem_alias_set (smem, 0); - - emit_insn (gen_movti (smem, reg)); - return 1; -} - -/* Return TRUE if X is MEM which is a struct member reference - and the member can safely be loaded and stored with a single - instruction because it is padded. */ -static int -mem_is_padded_component_ref (rtx x) -{ - tree t = MEM_EXPR (x); - tree r; - if (!t || TREE_CODE (t) != COMPONENT_REF) - return 0; - t = TREE_OPERAND (t, 1); - if (!t || TREE_CODE (t) != FIELD_DECL - || DECL_ALIGN (t) < 128 || AGGREGATE_TYPE_P (TREE_TYPE (t))) - return 0; - /* Only do this for RECORD_TYPEs, not UNION_TYPEs. */ - r = DECL_FIELD_CONTEXT (t); - if (!r || TREE_CODE (r) != RECORD_TYPE) - return 0; - /* Make sure they are the same mode */ - if (GET_MODE (x) != TYPE_MODE (TREE_TYPE (t))) - return 0; - /* If there are no following fields then the field alignment assures - the structure is padded to the alignment which means this field is - padded too. */ - if (TREE_CHAIN (t) == 0) - return 1; - /* If the following field is also aligned then this field will be - padded. */ - t = TREE_CHAIN (t); - if (TREE_CODE (t) == FIELD_DECL && DECL_ALIGN (t) >= 128) - return 1; - return 0; -} - -/* Parse the -mfixed-range= option string. */ -static void -fix_range (const char *const_str) -{ - int i, first, last; - char *str, *dash, *comma; - - /* str must be of the form REG1'-'REG2{,REG1'-'REG} where REG1 and - REG2 are either register names or register numbers. The effect - of this option is to mark the registers in the range from REG1 to - REG2 as ``fixed'' so they won't be used by the compiler. */ - - i = strlen (const_str); - str = (char *) alloca (i + 1); - memcpy (str, const_str, i + 1); - - while (1) - { - dash = strchr (str, '-'); - if (!dash) - { - warning (0, "value of %<-mfixed-range%> must have form REG1-REG2"); - return; - } - *dash = '\0'; - comma = strchr (dash + 1, ','); - if (comma) - *comma = '\0'; - - first = decode_reg_name (str); - if (first < 0) - { - warning (0, "unknown register name: %s", str); - return; - } - - last = decode_reg_name (dash + 1); - if (last < 0) - { - warning (0, "unknown register name: %s", dash + 1); - return; - } - - *dash = '-'; - - if (first > last) - { - warning (0, "%s-%s is an empty range", str, dash + 1); - return; - } - - for (i = first; i <= last; ++i) - fixed_regs[i] = call_used_regs[i] = 1; - - if (!comma) - break; - - *comma = ','; - str = comma + 1; - } -} - -/* Return TRUE if x is a CONST_INT, CONST_DOUBLE or CONST_VECTOR that - can be generated using the fsmbi instruction. */ -int -fsmbi_const_p (rtx x) -{ - if (CONSTANT_P (x)) - { - /* We can always choose TImode for CONST_INT because the high bits - of an SImode will always be all 1s, i.e., valid for fsmbi. */ - enum immediate_class c = classify_immediate (x, TImode); - return c == IC_FSMBI || (!epilogue_completed && c == IC_FSMBI2); - } - return 0; -} - -/* Return TRUE if x is a CONST_INT, CONST_DOUBLE or CONST_VECTOR that - can be generated using the cbd, chd, cwd or cdd instruction. */ -int -cpat_const_p (rtx x, machine_mode mode) -{ - if (CONSTANT_P (x)) - { - enum immediate_class c = classify_immediate (x, mode); - return c == IC_CPAT; - } - return 0; -} - -rtx -gen_cpat_const (rtx * ops) -{ - unsigned char dst[16]; - int i, offset, shift, isize; - if (GET_CODE (ops[3]) != CONST_INT - || GET_CODE (ops[2]) != CONST_INT - || (GET_CODE (ops[1]) != CONST_INT - && GET_CODE (ops[1]) != REG)) - return 0; - if (GET_CODE (ops[1]) == REG - && (!REG_POINTER (ops[1]) - || REGNO_POINTER_ALIGN (ORIGINAL_REGNO (ops[1])) < 128)) - return 0; - - for (i = 0; i < 16; i++) - dst[i] = i + 16; - isize = INTVAL (ops[3]); - if (isize == 1) - shift = 3; - else if (isize == 2) - shift = 2; - else - shift = 0; - offset = (INTVAL (ops[2]) + - (GET_CODE (ops[1]) == - CONST_INT ? INTVAL (ops[1]) : 0)) & 15; - for (i = 0; i < isize; i++) - dst[offset + i] = i + shift; - return array_to_constant (TImode, dst); -} - -/* Convert a CONST_INT, CONST_DOUBLE, or CONST_VECTOR into a 16 byte - array. Use MODE for CONST_INT's. When the constant's mode is smaller - than 16 bytes, the value is repeated across the rest of the array. */ -void -constant_to_array (machine_mode mode, rtx x, unsigned char arr[16]) -{ - HOST_WIDE_INT val; - int i, j, first; - - memset (arr, 0, 16); - mode = GET_MODE (x) != VOIDmode ? GET_MODE (x) : mode; - if (GET_CODE (x) == CONST_INT - || (GET_CODE (x) == CONST_DOUBLE - && (mode == SFmode || mode == DFmode))) - { - gcc_assert (mode != VOIDmode && mode != BLKmode); - - if (GET_CODE (x) == CONST_DOUBLE) - val = const_double_to_hwint (x); - else - val = INTVAL (x); - first = GET_MODE_SIZE (mode) - 1; - for (i = first; i >= 0; i--) - { - arr[i] = val & 0xff; - val >>= 8; - } - /* Splat the constant across the whole array. */ - for (j = 0, i = first + 1; i < 16; i++) - { - arr[i] = arr[j]; - j = (j == first) ? 0 : j + 1; - } - } - else if (GET_CODE (x) == CONST_DOUBLE) - { - val = CONST_DOUBLE_LOW (x); - for (i = 15; i >= 8; i--) - { - arr[i] = val & 0xff; - val >>= 8; - } - val = CONST_DOUBLE_HIGH (x); - for (i = 7; i >= 0; i--) - { - arr[i] = val & 0xff; - val >>= 8; - } - } - else if (GET_CODE (x) == CONST_VECTOR) - { - int units; - rtx elt; - mode = GET_MODE_INNER (mode); - units = CONST_VECTOR_NUNITS (x); - for (i = 0; i < units; i++) - { - elt = CONST_VECTOR_ELT (x, i); - if (GET_CODE (elt) == CONST_INT || GET_CODE (elt) == CONST_DOUBLE) - { - if (GET_CODE (elt) == CONST_DOUBLE) - val = const_double_to_hwint (elt); - else - val = INTVAL (elt); - first = GET_MODE_SIZE (mode) - 1; - if (first + i * GET_MODE_SIZE (mode) > 16) - abort (); - for (j = first; j >= 0; j--) - { - arr[j + i * GET_MODE_SIZE (mode)] = val & 0xff; - val >>= 8; - } - } - } - } - else - gcc_unreachable(); -} - -/* Convert a 16 byte array to a constant of mode MODE. When MODE is - smaller than 16 bytes, use the bytes that would represent that value - in a register, e.g., for QImode return the value of arr[3]. */ -rtx -array_to_constant (machine_mode mode, const unsigned char arr[16]) -{ - machine_mode inner_mode; - rtvec v; - int units, size, i, j, k; - HOST_WIDE_INT val; - - if (GET_MODE_CLASS (mode) == MODE_INT - && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT) - { - j = GET_MODE_SIZE (mode); - i = j < 4 ? 4 - j : 0; - for (val = 0; i < j; i++) - val = (val << 8) | arr[i]; - val = trunc_int_for_mode (val, mode); - return GEN_INT (val); - } - - if (mode == TImode) - { - HOST_WIDE_INT high; - for (i = high = 0; i < 8; i++) - high = (high << 8) | arr[i]; - for (i = 8, val = 0; i < 16; i++) - val = (val << 8) | arr[i]; - return immed_double_const (val, high, TImode); - } - if (mode == SFmode) - { - val = (arr[0] << 24) | (arr[1] << 16) | (arr[2] << 8) | arr[3]; - val = trunc_int_for_mode (val, SImode); - return hwint_to_const_double (SFmode, val); - } - if (mode == DFmode) - { - for (i = 0, val = 0; i < 8; i++) - val = (val << 8) | arr[i]; - return hwint_to_const_double (DFmode, val); - } - - if (!VECTOR_MODE_P (mode)) - abort (); - - units = GET_MODE_NUNITS (mode); - size = GET_MODE_UNIT_SIZE (mode); - inner_mode = GET_MODE_INNER (mode); - v = rtvec_alloc (units); - - for (k = i = 0; i < units; ++i) - { - val = 0; - for (j = 0; j < size; j++, k++) - val = (val << 8) | arr[k]; - - if (GET_MODE_CLASS (inner_mode) == MODE_FLOAT) - RTVEC_ELT (v, i) = hwint_to_const_double (inner_mode, val); - else - RTVEC_ELT (v, i) = GEN_INT (trunc_int_for_mode (val, inner_mode)); - } - if (k > 16) - abort (); - - return gen_rtx_CONST_VECTOR (mode, v); -} - -static void -reloc_diagnostic (rtx x) -{ - tree decl = 0; - if (!flag_pic || !(TARGET_WARN_RELOC || TARGET_ERROR_RELOC)) - return; - - if (GET_CODE (x) == SYMBOL_REF) - decl = SYMBOL_REF_DECL (x); - else if (GET_CODE (x) == CONST - && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF) - decl = SYMBOL_REF_DECL (XEXP (XEXP (x, 0), 0)); - - /* SYMBOL_REF_DECL is not necessarily a DECL. */ - if (decl && !DECL_P (decl)) - decl = 0; - - /* The decl could be a string constant. */ - if (decl && DECL_P (decl)) - { - location_t loc; - /* We use last_assemble_variable_decl to get line information. It's - not always going to be right and might not even be close, but will - be right for the more common cases. */ - if (!last_assemble_variable_decl || in_section == ctors_section) - loc = DECL_SOURCE_LOCATION (decl); - else - loc = DECL_SOURCE_LOCATION (last_assemble_variable_decl); - - if (TARGET_WARN_RELOC) - warning_at (loc, 0, - "creating run-time relocation for %qD", decl); - else - error_at (loc, - "creating run-time relocation for %qD", decl); - } - else - { - if (TARGET_WARN_RELOC) - warning_at (input_location, 0, "creating run-time relocation"); - else - error_at (input_location, "creating run-time relocation"); - } -} - -/* Hook into assemble_integer so we can generate an error for run-time - relocations. The SPU ABI disallows them. */ -static bool -spu_assemble_integer (rtx x, unsigned int size, int aligned_p) -{ - /* By default run-time relocations aren't supported, but we allow them - in case users support it in their own run-time loader. And we provide - a warning for those users that don't. */ - if ((GET_CODE (x) == SYMBOL_REF) - || GET_CODE (x) == LABEL_REF || GET_CODE (x) == CONST) - reloc_diagnostic (x); - - return default_assemble_integer (x, size, aligned_p); -} - -static void -spu_asm_globalize_label (FILE * file, const char *name) -{ - fputs ("\t.global\t", file); - assemble_name (file, name); - fputs ("\n", file); -} - -static bool -spu_rtx_costs (rtx x, machine_mode mode, int outer_code ATTRIBUTE_UNUSED, - int opno ATTRIBUTE_UNUSED, int *total, - bool speed ATTRIBUTE_UNUSED) -{ - int code = GET_CODE (x); - int cost = COSTS_N_INSNS (2); - - /* Folding to a CONST_VECTOR will use extra space but there might - be only a small savings in cycles. We'd like to use a CONST_VECTOR - only if it allows us to fold away multiple insns. Changing the cost - of a CONST_VECTOR here (or in CONST_COSTS) doesn't help though - because this cost will only be compared against a single insn. - if (code == CONST_VECTOR) - return spu_legitimate_constant_p (mode, x) ? cost : COSTS_N_INSNS (6); - */ - - /* Use defaults for float operations. Not accurate but good enough. */ - if (mode == DFmode) - { - *total = COSTS_N_INSNS (13); - return true; - } - if (mode == SFmode) - { - *total = COSTS_N_INSNS (6); - return true; - } - switch (code) - { - case CONST_INT: - if (satisfies_constraint_K (x)) - *total = 0; - else if (INTVAL (x) >= -0x80000000ll && INTVAL (x) <= 0xffffffffll) - *total = COSTS_N_INSNS (1); - else - *total = COSTS_N_INSNS (3); - return true; - - case CONST: - *total = COSTS_N_INSNS (3); - return true; - - case LABEL_REF: - case SYMBOL_REF: - *total = COSTS_N_INSNS (0); - return true; - - case CONST_DOUBLE: - *total = COSTS_N_INSNS (5); - return true; - - case FLOAT_EXTEND: - case FLOAT_TRUNCATE: - case FLOAT: - case UNSIGNED_FLOAT: - case FIX: - case UNSIGNED_FIX: - *total = COSTS_N_INSNS (7); - return true; - - case PLUS: - if (mode == TImode) - { - *total = COSTS_N_INSNS (9); - return true; - } - break; - - case MULT: - cost = - GET_CODE (XEXP (x, 0)) == - REG ? COSTS_N_INSNS (12) : COSTS_N_INSNS (7); - if (mode == SImode && GET_CODE (XEXP (x, 0)) == REG) - { - if (GET_CODE (XEXP (x, 1)) == CONST_INT) - { - HOST_WIDE_INT val = INTVAL (XEXP (x, 1)); - cost = COSTS_N_INSNS (14); - if ((val & 0xffff) == 0) - cost = COSTS_N_INSNS (9); - else if (val > 0 && val < 0x10000) - cost = COSTS_N_INSNS (11); - } - } - *total = cost; - return true; - case DIV: - case UDIV: - case MOD: - case UMOD: - *total = COSTS_N_INSNS (20); - return true; - case ROTATE: - case ROTATERT: - case ASHIFT: - case ASHIFTRT: - case LSHIFTRT: - *total = COSTS_N_INSNS (4); - return true; - case UNSPEC: - if (XINT (x, 1) == UNSPEC_CONVERT) - *total = COSTS_N_INSNS (0); - else - *total = COSTS_N_INSNS (4); - return true; - } - /* Scale cost by mode size. Except when initializing (cfun->decl == 0). */ - if (GET_MODE_CLASS (mode) == MODE_INT - && GET_MODE_SIZE (mode) > GET_MODE_SIZE (SImode) && cfun && cfun->decl) - cost = cost * (GET_MODE_SIZE (mode) / GET_MODE_SIZE (SImode)) - * (GET_MODE_SIZE (mode) / GET_MODE_SIZE (SImode)); - *total = cost; - return true; -} - -static scalar_int_mode -spu_unwind_word_mode (void) -{ - return SImode; -} - -/* Decide whether we can make a sibling call to a function. DECL is the - declaration of the function being targeted by the call and EXP is the - CALL_EXPR representing the call. */ -static bool -spu_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED) -{ - return decl && !TARGET_LARGE_MEM; -} - -/* We need to correctly update the back chain pointer and the Available - Stack Size (which is in the second slot of the sp register.) */ -void -spu_allocate_stack (rtx op0, rtx op1) -{ - HOST_WIDE_INT v; - rtx chain = gen_reg_rtx (V4SImode); - rtx stack_bot = gen_frame_mem (V4SImode, stack_pointer_rtx); - rtx sp = gen_reg_rtx (V4SImode); - rtx splatted = gen_reg_rtx (V4SImode); - rtx pat = gen_reg_rtx (TImode); - - /* copy the back chain so we can save it back again. */ - emit_move_insn (chain, stack_bot); - - op1 = force_reg (SImode, op1); - - v = 0x1020300010203ll; - emit_move_insn (pat, immed_double_const (v, v, TImode)); - emit_insn (gen_shufb (splatted, op1, op1, pat)); - - emit_insn (gen_spu_convert (sp, stack_pointer_rtx)); - emit_insn (gen_subv4si3 (sp, sp, splatted)); - - if (flag_stack_check || flag_stack_clash_protection) - { - rtx avail = gen_reg_rtx(SImode); - rtx result = gen_reg_rtx(SImode); - emit_insn (gen_vec_extractv4sisi (avail, sp, GEN_INT (1))); - emit_insn (gen_cgt_si(result, avail, GEN_INT (-1))); - emit_insn (gen_spu_heq (result, GEN_INT(0) )); - } - - emit_insn (gen_spu_convert (stack_pointer_rtx, sp)); - - emit_move_insn (stack_bot, chain); - - emit_move_insn (op0, virtual_stack_dynamic_rtx); -} - -void -spu_restore_stack_nonlocal (rtx op0 ATTRIBUTE_UNUSED, rtx op1) -{ - static unsigned char arr[16] = - { 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3 }; - rtx temp = gen_reg_rtx (SImode); - rtx temp2 = gen_reg_rtx (SImode); - rtx temp3 = gen_reg_rtx (V4SImode); - rtx temp4 = gen_reg_rtx (V4SImode); - rtx pat = gen_reg_rtx (TImode); - rtx sp = gen_rtx_REG (V4SImode, STACK_POINTER_REGNUM); - - /* Restore the backchain from the first word, sp from the second. */ - emit_move_insn (temp2, adjust_address_nv (op1, SImode, 0)); - emit_move_insn (temp, adjust_address_nv (op1, SImode, 4)); - - emit_move_insn (pat, array_to_constant (TImode, arr)); - - /* Compute Available Stack Size for sp */ - emit_insn (gen_subsi3 (temp, temp, stack_pointer_rtx)); - emit_insn (gen_shufb (temp3, temp, temp, pat)); - - /* Compute Available Stack Size for back chain */ - emit_insn (gen_subsi3 (temp2, temp2, stack_pointer_rtx)); - emit_insn (gen_shufb (temp4, temp2, temp2, pat)); - emit_insn (gen_addv4si3 (temp4, sp, temp4)); - - emit_insn (gen_addv4si3 (sp, sp, temp3)); - emit_move_insn (gen_frame_mem (V4SImode, stack_pointer_rtx), temp4); -} - -static void -spu_init_libfuncs (void) -{ - set_optab_libfunc (smul_optab, DImode, "__muldi3"); - set_optab_libfunc (sdiv_optab, DImode, "__divdi3"); - set_optab_libfunc (smod_optab, DImode, "__moddi3"); - set_optab_libfunc (udiv_optab, DImode, "__udivdi3"); - set_optab_libfunc (umod_optab, DImode, "__umoddi3"); - set_optab_libfunc (udivmod_optab, DImode, "__udivmoddi4"); - set_optab_libfunc (ffs_optab, DImode, "__ffsdi2"); - set_optab_libfunc (clz_optab, DImode, "__clzdi2"); - set_optab_libfunc (ctz_optab, DImode, "__ctzdi2"); - set_optab_libfunc (clrsb_optab, DImode, "__clrsbdi2"); - set_optab_libfunc (popcount_optab, DImode, "__popcountdi2"); - set_optab_libfunc (parity_optab, DImode, "__paritydi2"); - - set_conv_libfunc (ufloat_optab, DFmode, SImode, "__float_unssidf"); - set_conv_libfunc (ufloat_optab, DFmode, DImode, "__float_unsdidf"); - - set_optab_libfunc (addv_optab, SImode, "__addvsi3"); - set_optab_libfunc (subv_optab, SImode, "__subvsi3"); - set_optab_libfunc (smulv_optab, SImode, "__mulvsi3"); - set_optab_libfunc (sdivv_optab, SImode, "__divvsi3"); - set_optab_libfunc (negv_optab, SImode, "__negvsi2"); - set_optab_libfunc (absv_optab, SImode, "__absvsi2"); - set_optab_libfunc (addv_optab, DImode, "__addvdi3"); - set_optab_libfunc (subv_optab, DImode, "__subvdi3"); - set_optab_libfunc (smulv_optab, DImode, "__mulvdi3"); - set_optab_libfunc (sdivv_optab, DImode, "__divvdi3"); - set_optab_libfunc (negv_optab, DImode, "__negvdi2"); - set_optab_libfunc (absv_optab, DImode, "__absvdi2"); - - set_optab_libfunc (smul_optab, TImode, "__multi3"); - set_optab_libfunc (sdiv_optab, TImode, "__divti3"); - set_optab_libfunc (smod_optab, TImode, "__modti3"); - set_optab_libfunc (udiv_optab, TImode, "__udivti3"); - set_optab_libfunc (umod_optab, TImode, "__umodti3"); - set_optab_libfunc (udivmod_optab, TImode, "__udivmodti4"); -} - -/* Make a subreg, stripping any existing subreg. We could possibly just - call simplify_subreg, but in this case we know what we want. */ -rtx -spu_gen_subreg (machine_mode mode, rtx x) -{ - if (GET_CODE (x) == SUBREG) - x = SUBREG_REG (x); - if (GET_MODE (x) == mode) - return x; - return gen_rtx_SUBREG (mode, x, 0); -} - -static bool -spu_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) -{ - return (TYPE_MODE (type) == BLKmode - && ((type) == 0 - || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST - || int_size_in_bytes (type) > - (MAX_REGISTER_RETURN * UNITS_PER_WORD))); -} - -/* Create the built-in types and functions */ - -enum spu_function_code -{ -#define DEF_BUILTIN(fcode, icode, name, type, params) fcode, -#include "spu-builtins.def" -#undef DEF_BUILTIN - NUM_SPU_BUILTINS -}; - -extern GTY(()) struct spu_builtin_description spu_builtins[NUM_SPU_BUILTINS]; - -struct spu_builtin_description spu_builtins[] = { -#define DEF_BUILTIN(fcode, icode, name, type, params) \ - {fcode, icode, name, type, params}, -#include "spu-builtins.def" -#undef DEF_BUILTIN -}; - -static GTY(()) tree spu_builtin_decls[NUM_SPU_BUILTINS]; - -/* Returns the spu builtin decl for CODE. */ - -static tree -spu_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED) -{ - if (code >= NUM_SPU_BUILTINS) - return error_mark_node; - - return spu_builtin_decls[code]; -} - - -static void -spu_init_builtins (void) -{ - struct spu_builtin_description *d; - unsigned int i; - - V16QI_type_node = build_vector_type (intQI_type_node, 16); - V8HI_type_node = build_vector_type (intHI_type_node, 8); - V4SI_type_node = build_vector_type (intSI_type_node, 4); - V2DI_type_node = build_vector_type (intDI_type_node, 2); - V4SF_type_node = build_vector_type (float_type_node, 4); - V2DF_type_node = build_vector_type (double_type_node, 2); - - unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16); - unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8); - unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4); - unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2); - - spu_builtin_types[SPU_BTI_QUADWORD] = V16QI_type_node; - - spu_builtin_types[SPU_BTI_7] = global_trees[TI_INTSI_TYPE]; - spu_builtin_types[SPU_BTI_S7] = global_trees[TI_INTSI_TYPE]; - spu_builtin_types[SPU_BTI_U7] = global_trees[TI_INTSI_TYPE]; - spu_builtin_types[SPU_BTI_S10] = global_trees[TI_INTSI_TYPE]; - spu_builtin_types[SPU_BTI_S10_4] = global_trees[TI_INTSI_TYPE]; - spu_builtin_types[SPU_BTI_U14] = global_trees[TI_INTSI_TYPE]; - spu_builtin_types[SPU_BTI_16] = global_trees[TI_INTSI_TYPE]; - spu_builtin_types[SPU_BTI_S16] = global_trees[TI_INTSI_TYPE]; - spu_builtin_types[SPU_BTI_S16_2] = global_trees[TI_INTSI_TYPE]; - spu_builtin_types[SPU_BTI_U16] = global_trees[TI_INTSI_TYPE]; - spu_builtin_types[SPU_BTI_U16_2] = global_trees[TI_INTSI_TYPE]; - spu_builtin_types[SPU_BTI_U18] = global_trees[TI_INTSI_TYPE]; - - spu_builtin_types[SPU_BTI_INTQI] = global_trees[TI_INTQI_TYPE]; - spu_builtin_types[SPU_BTI_INTHI] = global_trees[TI_INTHI_TYPE]; - spu_builtin_types[SPU_BTI_INTSI] = global_trees[TI_INTSI_TYPE]; - spu_builtin_types[SPU_BTI_INTDI] = global_trees[TI_INTDI_TYPE]; - spu_builtin_types[SPU_BTI_UINTQI] = global_trees[TI_UINTQI_TYPE]; - spu_builtin_types[SPU_BTI_UINTHI] = global_trees[TI_UINTHI_TYPE]; - spu_builtin_types[SPU_BTI_UINTSI] = global_trees[TI_UINTSI_TYPE]; - spu_builtin_types[SPU_BTI_UINTDI] = global_trees[TI_UINTDI_TYPE]; - - spu_builtin_types[SPU_BTI_FLOAT] = global_trees[TI_FLOAT_TYPE]; - spu_builtin_types[SPU_BTI_DOUBLE] = global_trees[TI_DOUBLE_TYPE]; - - spu_builtin_types[SPU_BTI_VOID] = global_trees[TI_VOID_TYPE]; - - spu_builtin_types[SPU_BTI_PTR] = - build_pointer_type (build_qualified_type - (void_type_node, - TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)); - - /* For each builtin we build a new prototype. The tree code will make - sure nodes are shared. */ - for (i = 0, d = spu_builtins; i < NUM_SPU_BUILTINS; i++, d++) - { - tree p; - char name[64]; /* build_function will make a copy. */ - int parm; - - if (d->name == 0) - continue; - - /* Find last parm. */ - for (parm = 1; d->parm[parm] != SPU_BTI_END_OF_PARAMS; parm++) - ; - - p = void_list_node; - while (parm > 1) - p = tree_cons (NULL_TREE, spu_builtin_types[d->parm[--parm]], p); - - p = build_function_type (spu_builtin_types[d->parm[0]], p); - - sprintf (name, "__builtin_%s", d->name); - spu_builtin_decls[i] = - add_builtin_function (name, p, i, BUILT_IN_MD, NULL, NULL_TREE); - if (d->fcode == SPU_MASK_FOR_LOAD) - TREE_READONLY (spu_builtin_decls[i]) = 1; - - /* These builtins don't throw. */ - TREE_NOTHROW (spu_builtin_decls[i]) = 1; - } -} - -void -spu_restore_stack_block (rtx op0 ATTRIBUTE_UNUSED, rtx op1) -{ - static unsigned char arr[16] = - { 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3 }; - - rtx temp = gen_reg_rtx (Pmode); - rtx temp2 = gen_reg_rtx (V4SImode); - rtx temp3 = gen_reg_rtx (V4SImode); - rtx pat = gen_reg_rtx (TImode); - rtx sp = gen_rtx_REG (V4SImode, STACK_POINTER_REGNUM); - - emit_move_insn (pat, array_to_constant (TImode, arr)); - - /* Restore the sp. */ - emit_move_insn (temp, op1); - emit_move_insn (temp2, gen_frame_mem (V4SImode, stack_pointer_rtx)); - - /* Compute available stack size for sp. */ - emit_insn (gen_subsi3 (temp, temp, stack_pointer_rtx)); - emit_insn (gen_shufb (temp3, temp, temp, pat)); - - emit_insn (gen_addv4si3 (sp, sp, temp3)); - emit_move_insn (gen_frame_mem (V4SImode, stack_pointer_rtx), temp2); -} - -int -spu_safe_dma (HOST_WIDE_INT channel) -{ - return TARGET_SAFE_DMA && channel >= 21 && channel <= 27; -} - -void -spu_builtin_splats (rtx ops[]) -{ - machine_mode mode = GET_MODE (ops[0]); - if (GET_CODE (ops[1]) == CONST_INT || GET_CODE (ops[1]) == CONST_DOUBLE) - { - unsigned char arr[16]; - constant_to_array (GET_MODE_INNER (mode), ops[1], arr); - emit_move_insn (ops[0], array_to_constant (mode, arr)); - } - else - { - rtx reg = gen_reg_rtx (TImode); - rtx shuf; - if (GET_CODE (ops[1]) != REG - && GET_CODE (ops[1]) != SUBREG) - ops[1] = force_reg (GET_MODE_INNER (mode), ops[1]); - switch (mode) - { - case E_V2DImode: - case E_V2DFmode: - shuf = - immed_double_const (0x0001020304050607ll, 0x1011121314151617ll, - TImode); - break; - case E_V4SImode: - case E_V4SFmode: - shuf = - immed_double_const (0x0001020300010203ll, 0x0001020300010203ll, - TImode); - break; - case E_V8HImode: - shuf = - immed_double_const (0x0203020302030203ll, 0x0203020302030203ll, - TImode); - break; - case E_V16QImode: - shuf = - immed_double_const (0x0303030303030303ll, 0x0303030303030303ll, - TImode); - break; - default: - abort (); - } - emit_move_insn (reg, shuf); - emit_insn (gen_shufb (ops[0], ops[1], ops[1], reg)); - } -} - -void -spu_builtin_extract (rtx ops[]) -{ - machine_mode mode; - rtx rot, from, tmp; - - mode = GET_MODE (ops[1]); - - if (GET_CODE (ops[2]) == CONST_INT) - { - switch (mode) - { - case E_V16QImode: - emit_insn (gen_vec_extractv16qiqi (ops[0], ops[1], ops[2])); - break; - case E_V8HImode: - emit_insn (gen_vec_extractv8hihi (ops[0], ops[1], ops[2])); - break; - case E_V4SFmode: - emit_insn (gen_vec_extractv4sfsf (ops[0], ops[1], ops[2])); - break; - case E_V4SImode: - emit_insn (gen_vec_extractv4sisi (ops[0], ops[1], ops[2])); - break; - case E_V2DImode: - emit_insn (gen_vec_extractv2didi (ops[0], ops[1], ops[2])); - break; - case E_V2DFmode: - emit_insn (gen_vec_extractv2dfdf (ops[0], ops[1], ops[2])); - break; - default: - abort (); - } - return; - } - - from = spu_gen_subreg (TImode, ops[1]); - rot = gen_reg_rtx (TImode); - tmp = gen_reg_rtx (SImode); - - switch (mode) - { - case E_V16QImode: - emit_insn (gen_addsi3 (tmp, ops[2], GEN_INT (-3))); - break; - case E_V8HImode: - emit_insn (gen_addsi3 (tmp, ops[2], ops[2])); - emit_insn (gen_addsi3 (tmp, tmp, GEN_INT (-2))); - break; - case E_V4SFmode: - case E_V4SImode: - emit_insn (gen_ashlsi3 (tmp, ops[2], GEN_INT (2))); - break; - case E_V2DImode: - case E_V2DFmode: - emit_insn (gen_ashlsi3 (tmp, ops[2], GEN_INT (3))); - break; - default: - abort (); - } - emit_insn (gen_rotqby_ti (rot, from, tmp)); - - emit_insn (gen_spu_convert (ops[0], rot)); -} - -void -spu_builtin_insert (rtx ops[]) -{ - machine_mode mode = GET_MODE (ops[0]); - machine_mode imode = GET_MODE_INNER (mode); - rtx mask = gen_reg_rtx (TImode); - rtx offset; - - if (GET_CODE (ops[3]) == CONST_INT) - offset = GEN_INT (INTVAL (ops[3]) * GET_MODE_SIZE (imode)); - else - { - offset = gen_reg_rtx (SImode); - emit_insn (gen_mulsi3 - (offset, ops[3], GEN_INT (GET_MODE_SIZE (imode)))); - } - emit_insn (gen_cpat - (mask, stack_pointer_rtx, offset, - GEN_INT (GET_MODE_SIZE (imode)))); - emit_insn (gen_shufb (ops[0], ops[1], ops[2], mask)); -} - -void -spu_builtin_promote (rtx ops[]) -{ - machine_mode mode, imode; - rtx rot, from, offset; - HOST_WIDE_INT pos; - - mode = GET_MODE (ops[0]); - imode = GET_MODE_INNER (mode); - - from = gen_reg_rtx (TImode); - rot = spu_gen_subreg (TImode, ops[0]); - - emit_insn (gen_spu_convert (from, ops[1])); - - if (GET_CODE (ops[2]) == CONST_INT) - { - pos = -GET_MODE_SIZE (imode) * INTVAL (ops[2]); - if (GET_MODE_SIZE (imode) < 4) - pos += 4 - GET_MODE_SIZE (imode); - offset = GEN_INT (pos & 15); - } - else - { - offset = gen_reg_rtx (SImode); - switch (mode) - { - case E_V16QImode: - emit_insn (gen_subsi3 (offset, GEN_INT (3), ops[2])); - break; - case E_V8HImode: - emit_insn (gen_subsi3 (offset, GEN_INT (1), ops[2])); - emit_insn (gen_addsi3 (offset, offset, offset)); - break; - case E_V4SFmode: - case E_V4SImode: - emit_insn (gen_subsi3 (offset, GEN_INT (0), ops[2])); - emit_insn (gen_ashlsi3 (offset, offset, GEN_INT (2))); - break; - case E_V2DImode: - case E_V2DFmode: - emit_insn (gen_ashlsi3 (offset, ops[2], GEN_INT (3))); - break; - default: - abort (); - } - } - emit_insn (gen_rotqby_ti (rot, from, offset)); -} - -static void -spu_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt) -{ - rtx fnaddr = XEXP (DECL_RTL (fndecl), 0); - rtx shuf = gen_reg_rtx (V4SImode); - rtx insn = gen_reg_rtx (V4SImode); - rtx shufc; - rtx insnc; - rtx mem; - - fnaddr = force_reg (SImode, fnaddr); - cxt = force_reg (SImode, cxt); - - if (TARGET_LARGE_MEM) - { - rtx rotl = gen_reg_rtx (V4SImode); - rtx mask = gen_reg_rtx (V4SImode); - rtx bi = gen_reg_rtx (SImode); - static unsigned char const shufa[16] = { - 2, 3, 0, 1, 18, 19, 16, 17, - 0, 1, 2, 3, 16, 17, 18, 19 - }; - static unsigned char const insna[16] = { - 0x41, 0, 0, 79, - 0x41, 0, 0, STATIC_CHAIN_REGNUM, - 0x60, 0x80, 0, 79, - 0x60, 0x80, 0, STATIC_CHAIN_REGNUM - }; - - shufc = force_reg (TImode, array_to_constant (TImode, shufa)); - insnc = force_reg (V4SImode, array_to_constant (V4SImode, insna)); - - emit_insn (gen_shufb (shuf, fnaddr, cxt, shufc)); - emit_insn (gen_vrotlv4si3 (rotl, shuf, spu_const (V4SImode, 7))); - emit_insn (gen_movv4si (mask, spu_const (V4SImode, 0xffff << 7))); - emit_insn (gen_selb (insn, insnc, rotl, mask)); - - mem = adjust_address (m_tramp, V4SImode, 0); - emit_move_insn (mem, insn); - - emit_move_insn (bi, GEN_INT (0x35000000 + (79 << 7))); - mem = adjust_address (m_tramp, Pmode, 16); - emit_move_insn (mem, bi); - } - else - { - rtx scxt = gen_reg_rtx (SImode); - rtx sfnaddr = gen_reg_rtx (SImode); - static unsigned char const insna[16] = { - 0x42, 0, 0, STATIC_CHAIN_REGNUM, - 0x30, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0 - }; - - shufc = gen_reg_rtx (TImode); - insnc = force_reg (V4SImode, array_to_constant (V4SImode, insna)); - - /* By or'ing all of cxt with the ila opcode we are assuming cxt - fits 18 bits and the last 4 are zeros. This will be true if - the stack pointer is initialized to 0x3fff0 at program start, - otherwise the ila instruction will be garbage. */ - - emit_insn (gen_ashlsi3 (scxt, cxt, GEN_INT (7))); - emit_insn (gen_ashlsi3 (sfnaddr, fnaddr, GEN_INT (5))); - emit_insn (gen_cpat - (shufc, stack_pointer_rtx, GEN_INT (4), GEN_INT (4))); - emit_insn (gen_shufb (shuf, sfnaddr, scxt, shufc)); - emit_insn (gen_iorv4si3 (insn, insnc, shuf)); - - mem = adjust_address (m_tramp, V4SImode, 0); - emit_move_insn (mem, insn); - } - emit_insn (gen_sync ()); -} - -static bool -spu_warn_func_return (tree decl) -{ - /* Naked functions are implemented entirely in assembly, including the - return sequence, so suppress warnings about this. */ - return !spu_naked_function_p (decl); -} - -void -spu_expand_sign_extend (rtx ops[]) -{ - unsigned char arr[16]; - rtx pat = gen_reg_rtx (TImode); - rtx sign, c; - int i, last; - last = GET_MODE (ops[0]) == DImode ? 7 : 15; - if (GET_MODE (ops[1]) == QImode) - { - sign = gen_reg_rtx (HImode); - emit_insn (gen_extendqihi2 (sign, ops[1])); - for (i = 0; i < 16; i++) - arr[i] = 0x12; - arr[last] = 0x13; - } - else - { - for (i = 0; i < 16; i++) - arr[i] = 0x10; - switch (GET_MODE (ops[1])) - { - case E_HImode: - sign = gen_reg_rtx (SImode); - emit_insn (gen_extendhisi2 (sign, ops[1])); - arr[last] = 0x03; - arr[last - 1] = 0x02; - break; - case E_SImode: - sign = gen_reg_rtx (SImode); - emit_insn (gen_ashrsi3 (sign, ops[1], GEN_INT (31))); - for (i = 0; i < 4; i++) - arr[last - i] = 3 - i; - break; - case E_DImode: - sign = gen_reg_rtx (SImode); - c = gen_reg_rtx (SImode); - emit_insn (gen_spu_convert (c, ops[1])); - emit_insn (gen_ashrsi3 (sign, c, GEN_INT (31))); - for (i = 0; i < 8; i++) - arr[last - i] = 7 - i; - break; - default: - abort (); - } - } - emit_move_insn (pat, array_to_constant (TImode, arr)); - emit_insn (gen_shufb (ops[0], ops[1], sign, pat)); -} - -/* expand vector initialization. If there are any constant parts, - load constant parts first. Then load any non-constant parts. */ -void -spu_expand_vector_init (rtx target, rtx vals) -{ - machine_mode mode = GET_MODE (target); - int n_elts = GET_MODE_NUNITS (mode); - int n_var = 0; - bool all_same = true; - rtx first, x = NULL_RTX, first_constant = NULL_RTX; - int i; - - first = XVECEXP (vals, 0, 0); - for (i = 0; i < n_elts; ++i) - { - x = XVECEXP (vals, 0, i); - if (!(CONST_INT_P (x) - || GET_CODE (x) == CONST_DOUBLE - || GET_CODE (x) == CONST_FIXED)) - ++n_var; - else - { - if (first_constant == NULL_RTX) - first_constant = x; - } - if (i > 0 && !rtx_equal_p (x, first)) - all_same = false; - } - - /* if all elements are the same, use splats to repeat elements */ - if (all_same) - { - if (!CONSTANT_P (first) - && !register_operand (first, GET_MODE (x))) - first = force_reg (GET_MODE (first), first); - emit_insn (gen_spu_splats (target, first)); - return; - } - - /* load constant parts */ - if (n_var != n_elts) - { - if (n_var == 0) - { - emit_move_insn (target, - gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0))); - } - else - { - rtx constant_parts_rtx = copy_rtx (vals); - - gcc_assert (first_constant != NULL_RTX); - /* fill empty slots with the first constant, this increases - our chance of using splats in the recursive call below. */ - for (i = 0; i < n_elts; ++i) - { - x = XVECEXP (constant_parts_rtx, 0, i); - if (!(CONST_INT_P (x) - || GET_CODE (x) == CONST_DOUBLE - || GET_CODE (x) == CONST_FIXED)) - XVECEXP (constant_parts_rtx, 0, i) = first_constant; - } - - spu_expand_vector_init (target, constant_parts_rtx); - } - } - - /* load variable parts */ - if (n_var != 0) - { - rtx insert_operands[4]; - - insert_operands[0] = target; - insert_operands[2] = target; - for (i = 0; i < n_elts; ++i) - { - x = XVECEXP (vals, 0, i); - if (!(CONST_INT_P (x) - || GET_CODE (x) == CONST_DOUBLE - || GET_CODE (x) == CONST_FIXED)) - { - if (!register_operand (x, GET_MODE (x))) - x = force_reg (GET_MODE (x), x); - insert_operands[1] = x; - insert_operands[3] = GEN_INT (i); - spu_builtin_insert (insert_operands); - } - } - } -} - -/* Return insn index for the vector compare instruction for given CODE, - and DEST_MODE, OP_MODE. Return -1 if valid insn is not available. */ - -static int -get_vec_cmp_insn (enum rtx_code code, - machine_mode dest_mode, - machine_mode op_mode) - -{ - switch (code) - { - case EQ: - if (dest_mode == V16QImode && op_mode == V16QImode) - return CODE_FOR_ceq_v16qi; - if (dest_mode == V8HImode && op_mode == V8HImode) - return CODE_FOR_ceq_v8hi; - if (dest_mode == V4SImode && op_mode == V4SImode) - return CODE_FOR_ceq_v4si; - if (dest_mode == V4SImode && op_mode == V4SFmode) - return CODE_FOR_ceq_v4sf; - if (dest_mode == V2DImode && op_mode == V2DFmode) - return CODE_FOR_ceq_v2df; - break; - case GT: - if (dest_mode == V16QImode && op_mode == V16QImode) - return CODE_FOR_cgt_v16qi; - if (dest_mode == V8HImode && op_mode == V8HImode) - return CODE_FOR_cgt_v8hi; - if (dest_mode == V4SImode && op_mode == V4SImode) - return CODE_FOR_cgt_v4si; - if (dest_mode == V4SImode && op_mode == V4SFmode) - return CODE_FOR_cgt_v4sf; - if (dest_mode == V2DImode && op_mode == V2DFmode) - return CODE_FOR_cgt_v2df; - break; - case GTU: - if (dest_mode == V16QImode && op_mode == V16QImode) - return CODE_FOR_clgt_v16qi; - if (dest_mode == V8HImode && op_mode == V8HImode) - return CODE_FOR_clgt_v8hi; - if (dest_mode == V4SImode && op_mode == V4SImode) - return CODE_FOR_clgt_v4si; - break; - default: - break; - } - return -1; -} - -/* Emit vector compare for operands OP0 and OP1 using code RCODE. - DMODE is expected destination mode. This is a recursive function. */ - -static rtx -spu_emit_vector_compare (enum rtx_code rcode, - rtx op0, rtx op1, - machine_mode dmode) -{ - int vec_cmp_insn; - rtx mask; - machine_mode dest_mode; - machine_mode op_mode = GET_MODE (op1); - - gcc_assert (GET_MODE (op0) == GET_MODE (op1)); - - /* Floating point vector compare instructions uses destination V4SImode. - Double floating point vector compare instructions uses destination V2DImode. - Move destination to appropriate mode later. */ - if (dmode == V4SFmode) - dest_mode = V4SImode; - else if (dmode == V2DFmode) - dest_mode = V2DImode; - else - dest_mode = dmode; - - mask = gen_reg_rtx (dest_mode); - vec_cmp_insn = get_vec_cmp_insn (rcode, dest_mode, op_mode); - - if (vec_cmp_insn == -1) - { - bool swap_operands = false; - bool try_again = false; - switch (rcode) - { - case LT: - rcode = GT; - swap_operands = true; - try_again = true; - break; - case LTU: - rcode = GTU; - swap_operands = true; - try_again = true; - break; - case NE: - case UNEQ: - case UNLE: - case UNLT: - case UNGE: - case UNGT: - case UNORDERED: - /* Treat A != B as ~(A==B). */ - { - enum rtx_code rev_code; - enum insn_code nor_code; - rtx rev_mask; - - rev_code = reverse_condition_maybe_unordered (rcode); - rev_mask = spu_emit_vector_compare (rev_code, op0, op1, dest_mode); - - nor_code = optab_handler (one_cmpl_optab, dest_mode); - gcc_assert (nor_code != CODE_FOR_nothing); - emit_insn (GEN_FCN (nor_code) (mask, rev_mask)); - if (dmode != dest_mode) - { - rtx temp = gen_reg_rtx (dest_mode); - convert_move (temp, mask, 0); - return temp; - } - return mask; - } - break; - case GE: - case GEU: - case LE: - case LEU: - /* Try GT/GTU/LT/LTU OR EQ */ - { - rtx c_rtx, eq_rtx; - enum insn_code ior_code; - enum rtx_code new_code; - - switch (rcode) - { - case GE: new_code = GT; break; - case GEU: new_code = GTU; break; - case LE: new_code = LT; break; - case LEU: new_code = LTU; break; - default: - gcc_unreachable (); - } - - c_rtx = spu_emit_vector_compare (new_code, op0, op1, dest_mode); - eq_rtx = spu_emit_vector_compare (EQ, op0, op1, dest_mode); - - ior_code = optab_handler (ior_optab, dest_mode); - gcc_assert (ior_code != CODE_FOR_nothing); - emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx)); - if (dmode != dest_mode) - { - rtx temp = gen_reg_rtx (dest_mode); - convert_move (temp, mask, 0); - return temp; - } - return mask; - } - break; - case LTGT: - /* Try LT OR GT */ - { - rtx lt_rtx, gt_rtx; - enum insn_code ior_code; - - lt_rtx = spu_emit_vector_compare (LT, op0, op1, dest_mode); - gt_rtx = spu_emit_vector_compare (GT, op0, op1, dest_mode); - - ior_code = optab_handler (ior_optab, dest_mode); - gcc_assert (ior_code != CODE_FOR_nothing); - emit_insn (GEN_FCN (ior_code) (mask, lt_rtx, gt_rtx)); - if (dmode != dest_mode) - { - rtx temp = gen_reg_rtx (dest_mode); - convert_move (temp, mask, 0); - return temp; - } - return mask; - } - break; - case ORDERED: - /* Implement as (A==A) & (B==B) */ - { - rtx a_rtx, b_rtx; - enum insn_code and_code; - - a_rtx = spu_emit_vector_compare (EQ, op0, op0, dest_mode); - b_rtx = spu_emit_vector_compare (EQ, op1, op1, dest_mode); - - and_code = optab_handler (and_optab, dest_mode); - gcc_assert (and_code != CODE_FOR_nothing); - emit_insn (GEN_FCN (and_code) (mask, a_rtx, b_rtx)); - if (dmode != dest_mode) - { - rtx temp = gen_reg_rtx (dest_mode); - convert_move (temp, mask, 0); - return temp; - } - return mask; - } - break; - default: - gcc_unreachable (); - } - - /* You only get two chances. */ - if (try_again) - vec_cmp_insn = get_vec_cmp_insn (rcode, dest_mode, op_mode); - - gcc_assert (vec_cmp_insn != -1); - - if (swap_operands) - { - rtx tmp; - tmp = op0; - op0 = op1; - op1 = tmp; - } - } - - emit_insn (GEN_FCN (vec_cmp_insn) (mask, op0, op1)); - if (dmode != dest_mode) - { - rtx temp = gen_reg_rtx (dest_mode); - convert_move (temp, mask, 0); - return temp; - } - return mask; -} - - -/* Emit vector conditional expression. - DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands. - CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */ - -int -spu_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2, - rtx cond, rtx cc_op0, rtx cc_op1) -{ - machine_mode dest_mode = GET_MODE (dest); - enum rtx_code rcode = GET_CODE (cond); - rtx mask; - - /* Get the vector mask for the given relational operations. */ - mask = spu_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode); - - emit_insn(gen_selb (dest, op2, op1, mask)); - - return 1; -} - -static rtx -spu_force_reg (machine_mode mode, rtx op) -{ - rtx x, r; - if (GET_MODE (op) == VOIDmode || GET_MODE (op) == BLKmode) - { - if ((SCALAR_INT_MODE_P (mode) && GET_CODE (op) == CONST_INT) - || GET_MODE (op) == BLKmode) - return force_reg (mode, convert_to_mode (mode, op, 0)); - abort (); - } - - r = force_reg (GET_MODE (op), op); - if (GET_MODE_SIZE (GET_MODE (op)) == GET_MODE_SIZE (mode)) - { - x = simplify_gen_subreg (mode, r, GET_MODE (op), 0); - if (x) - return x; - } - - x = gen_reg_rtx (mode); - emit_insn (gen_spu_convert (x, r)); - return x; -} - -static void -spu_check_builtin_parm (struct spu_builtin_description *d, rtx op, int p) -{ - HOST_WIDE_INT v = 0; - int lsbits; - /* Check the range of immediate operands. */ - if (p >= SPU_BTI_7 && p <= SPU_BTI_U18) - { - int range = p - SPU_BTI_7; - - if (!CONSTANT_P (op)) - error ("%s expects an integer literal in the range [%d, %d]", - d->name, - spu_builtin_range[range].low, spu_builtin_range[range].high); - - if (GET_CODE (op) == CONST - && (GET_CODE (XEXP (op, 0)) == PLUS - || GET_CODE (XEXP (op, 0)) == MINUS)) - { - v = INTVAL (XEXP (XEXP (op, 0), 1)); - op = XEXP (XEXP (op, 0), 0); - } - else if (GET_CODE (op) == CONST_INT) - v = INTVAL (op); - else if (GET_CODE (op) == CONST_VECTOR - && GET_CODE (CONST_VECTOR_ELT (op, 0)) == CONST_INT) - v = INTVAL (CONST_VECTOR_ELT (op, 0)); - - /* The default for v is 0 which is valid in every range. */ - if (v < spu_builtin_range[range].low - || v > spu_builtin_range[range].high) - error ("%s expects an integer literal in the range [%d, %d]. (%wd)", - d->name, - spu_builtin_range[range].low, spu_builtin_range[range].high, - v); - - switch (p) - { - case SPU_BTI_S10_4: - lsbits = 4; - break; - case SPU_BTI_U16_2: - /* This is only used in lqa, and stqa. Even though the insns - encode 16 bits of the address (all but the 2 least - significant), only 14 bits are used because it is masked to - be 16 byte aligned. */ - lsbits = 4; - break; - case SPU_BTI_S16_2: - /* This is used for lqr and stqr. */ - lsbits = 2; - break; - default: - lsbits = 0; - } - - if (GET_CODE (op) == LABEL_REF - || (GET_CODE (op) == SYMBOL_REF - && SYMBOL_REF_FUNCTION_P (op)) - || (v & ((1 << lsbits) - 1)) != 0) - warning (0, "%d least significant bits of %s are ignored", lsbits, - d->name); - } -} - - -static int -expand_builtin_args (struct spu_builtin_description *d, tree exp, - rtx target, rtx ops[]) -{ - enum insn_code icode = (enum insn_code) d->icode; - int i = 0, a; - - /* Expand the arguments into rtl. */ - - if (d->parm[0] != SPU_BTI_VOID) - ops[i++] = target; - - for (a = 0; d->parm[a+1] != SPU_BTI_END_OF_PARAMS; i++, a++) - { - tree arg = CALL_EXPR_ARG (exp, a); - if (arg == 0) - abort (); - ops[i] = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL); - } - - gcc_assert (i == insn_data[icode].n_generator_args); - return i; -} - -static rtx -spu_expand_builtin_1 (struct spu_builtin_description *d, - tree exp, rtx target) -{ - rtx pat; - rtx ops[8]; - enum insn_code icode = (enum insn_code) d->icode; - machine_mode mode, tmode; - int i, p; - int n_operands; - tree return_type; - - /* Set up ops[] with values from arglist. */ - n_operands = expand_builtin_args (d, exp, target, ops); - - /* Handle the target operand which must be operand 0. */ - i = 0; - if (d->parm[0] != SPU_BTI_VOID) - { - - /* We prefer the mode specified for the match_operand otherwise - use the mode from the builtin function prototype. */ - tmode = insn_data[d->icode].operand[0].mode; - if (tmode == VOIDmode) - tmode = TYPE_MODE (spu_builtin_types[d->parm[0]]); - - /* Try to use target because not using it can lead to extra copies - and when we are using all of the registers extra copies leads - to extra spills. */ - if (target && GET_CODE (target) == REG && GET_MODE (target) == tmode) - ops[0] = target; - else - target = ops[0] = gen_reg_rtx (tmode); - - if (!(*insn_data[icode].operand[0].predicate) (ops[0], tmode)) - abort (); - - i++; - } - - if (d->fcode == SPU_MASK_FOR_LOAD) - { - machine_mode mode = insn_data[icode].operand[1].mode; - tree arg; - rtx addr, op, pat; - - /* get addr */ - arg = CALL_EXPR_ARG (exp, 0); - gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg))); - op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL); - addr = memory_address (mode, op); - - /* negate addr */ - op = gen_reg_rtx (GET_MODE (addr)); - emit_insn (gen_rtx_SET (op, gen_rtx_NEG (GET_MODE (addr), addr))); - op = gen_rtx_MEM (mode, op); - - pat = GEN_FCN (icode) (target, op); - if (!pat) - return 0; - emit_insn (pat); - return target; - } - - /* Ignore align_hint, but still expand it's args in case they have - side effects. */ - if (icode == CODE_FOR_spu_align_hint) - return 0; - - /* Handle the rest of the operands. */ - for (p = 1; i < n_operands; i++, p++) - { - if (insn_data[d->icode].operand[i].mode != VOIDmode) - mode = insn_data[d->icode].operand[i].mode; - else - mode = TYPE_MODE (spu_builtin_types[d->parm[i]]); - - /* mode can be VOIDmode here for labels */ - - /* For specific intrinsics with an immediate operand, e.g., - si_ai(), we sometimes need to convert the scalar argument to a - vector argument by splatting the scalar. */ - if (VECTOR_MODE_P (mode) - && (GET_CODE (ops[i]) == CONST_INT - || GET_MODE_CLASS (GET_MODE (ops[i])) == MODE_INT - || GET_MODE_CLASS (GET_MODE (ops[i])) == MODE_FLOAT)) - { - if (GET_CODE (ops[i]) == CONST_INT) - ops[i] = spu_const (mode, INTVAL (ops[i])); - else - { - rtx reg = gen_reg_rtx (mode); - machine_mode imode = GET_MODE_INNER (mode); - if (!spu_nonmem_operand (ops[i], GET_MODE (ops[i]))) - ops[i] = force_reg (GET_MODE (ops[i]), ops[i]); - if (imode != GET_MODE (ops[i])) - ops[i] = convert_to_mode (imode, ops[i], - TYPE_UNSIGNED (spu_builtin_types - [d->parm[i]])); - emit_insn (gen_spu_splats (reg, ops[i])); - ops[i] = reg; - } - } - - spu_check_builtin_parm (d, ops[i], d->parm[p]); - - if (!(*insn_data[icode].operand[i].predicate) (ops[i], mode)) - ops[i] = spu_force_reg (mode, ops[i]); - } - - switch (n_operands) - { - case 0: - pat = GEN_FCN (icode) (0); - break; - case 1: - pat = GEN_FCN (icode) (ops[0]); - break; - case 2: - pat = GEN_FCN (icode) (ops[0], ops[1]); - break; - case 3: - pat = GEN_FCN (icode) (ops[0], ops[1], ops[2]); - break; - case 4: - pat = GEN_FCN (icode) (ops[0], ops[1], ops[2], ops[3]); - break; - case 5: - pat = GEN_FCN (icode) (ops[0], ops[1], ops[2], ops[3], ops[4]); - break; - case 6: - pat = GEN_FCN (icode) (ops[0], ops[1], ops[2], ops[3], ops[4], ops[5]); - break; - default: - abort (); - } - - if (!pat) - abort (); - - if (d->type == B_CALL || d->type == B_BISLED) - emit_call_insn (pat); - else if (d->type == B_JUMP) - { - emit_jump_insn (pat); - emit_barrier (); - } - else - emit_insn (pat); - - return_type = spu_builtin_types[d->parm[0]]; - if (d->parm[0] != SPU_BTI_VOID - && GET_MODE (target) != TYPE_MODE (return_type)) - { - /* target is the return value. It should always be the mode of - the builtin function prototype. */ - target = spu_force_reg (TYPE_MODE (return_type), target); - } - - return target; -} - -rtx -spu_expand_builtin (tree exp, - rtx target, - rtx subtarget ATTRIBUTE_UNUSED, - machine_mode mode ATTRIBUTE_UNUSED, - int ignore ATTRIBUTE_UNUSED) -{ - tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); - unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl); - struct spu_builtin_description *d; - - if (fcode < NUM_SPU_BUILTINS) - { - d = &spu_builtins[fcode]; - - return spu_expand_builtin_1 (d, exp, target); - } - abort (); -} - -/* Implement targetm.vectorize.builtin_mask_for_load. */ -static tree -spu_builtin_mask_for_load (void) -{ - return spu_builtin_decls[SPU_MASK_FOR_LOAD]; -} - -/* Implement targetm.vectorize.builtin_vectorization_cost. */ -static int -spu_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost, - tree vectype, - int misalign ATTRIBUTE_UNUSED) -{ - unsigned elements; - - switch (type_of_cost) - { - case scalar_stmt: - case vector_stmt: - case vector_load: - case vector_store: - case vec_to_scalar: - case scalar_to_vec: - case cond_branch_not_taken: - case vec_perm: - case vec_promote_demote: - return 1; - - case scalar_store: - return 10; - - case scalar_load: - /* Load + rotate. */ - return 2; - - case unaligned_load: - case vector_gather_load: - case vector_scatter_store: - return 2; - - case cond_branch_taken: - return 6; - - case vec_construct: - elements = TYPE_VECTOR_SUBPARTS (vectype); - return elements / 2 + 1; - - default: - gcc_unreachable (); - } -} - -/* Implement targetm.vectorize.init_cost. */ - -static void * -spu_init_cost (struct loop *loop_info ATTRIBUTE_UNUSED) -{ - unsigned *cost = XNEWVEC (unsigned, 3); - cost[vect_prologue] = cost[vect_body] = cost[vect_epilogue] = 0; - return cost; -} - -/* Implement targetm.vectorize.add_stmt_cost. */ - -static unsigned -spu_add_stmt_cost (void *data, int count, enum vect_cost_for_stmt kind, - struct _stmt_vec_info *stmt_info, int misalign, - enum vect_cost_model_location where) -{ - unsigned *cost = (unsigned *) data; - unsigned retval = 0; - - if (flag_vect_cost_model) - { - tree vectype = stmt_info ? stmt_vectype (stmt_info) : NULL_TREE; - int stmt_cost = spu_builtin_vectorization_cost (kind, vectype, misalign); - - /* Statements in an inner loop relative to the loop being - vectorized are weighted more heavily. The value here is - arbitrary and could potentially be improved with analysis. */ - if (where == vect_body && stmt_info && stmt_in_inner_loop_p (stmt_info)) - count *= 50; /* FIXME. */ - - retval = (unsigned) (count * stmt_cost); - cost[where] += retval; - } - - return retval; -} - -/* Implement targetm.vectorize.finish_cost. */ - -static void -spu_finish_cost (void *data, unsigned *prologue_cost, - unsigned *body_cost, unsigned *epilogue_cost) -{ - unsigned *cost = (unsigned *) data; - *prologue_cost = cost[vect_prologue]; - *body_cost = cost[vect_body]; - *epilogue_cost = cost[vect_epilogue]; -} - -/* Implement targetm.vectorize.destroy_cost_data. */ - -static void -spu_destroy_cost_data (void *data) -{ - free (data); -} - -/* Return true iff, data reference of TYPE can reach vector alignment (16) - after applying N number of iterations. This routine does not determine - how may iterations are required to reach desired alignment. */ - -static bool -spu_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed) -{ - if (is_packed) - return false; - - /* All other types are naturally aligned. */ - return true; -} - -/* Return the appropriate mode for a named address pointer. */ -static scalar_int_mode -spu_addr_space_pointer_mode (addr_space_t addrspace) -{ - switch (addrspace) - { - case ADDR_SPACE_GENERIC: - return ptr_mode; - case ADDR_SPACE_EA: - return EAmode; - default: - gcc_unreachable (); - } -} - -/* Return the appropriate mode for a named address address. */ -static scalar_int_mode -spu_addr_space_address_mode (addr_space_t addrspace) -{ - switch (addrspace) - { - case ADDR_SPACE_GENERIC: - return Pmode; - case ADDR_SPACE_EA: - return EAmode; - default: - gcc_unreachable (); - } -} - -/* Determine if one named address space is a subset of another. */ - -static bool -spu_addr_space_subset_p (addr_space_t subset, addr_space_t superset) -{ - gcc_assert (subset == ADDR_SPACE_GENERIC || subset == ADDR_SPACE_EA); - gcc_assert (superset == ADDR_SPACE_GENERIC || superset == ADDR_SPACE_EA); - - if (subset == superset) - return true; - - /* If we have -mno-address-space-conversion, treat __ea and generic as not - being subsets but instead as disjoint address spaces. */ - else if (!TARGET_ADDRESS_SPACE_CONVERSION) - return false; - - else - return (subset == ADDR_SPACE_GENERIC && superset == ADDR_SPACE_EA); -} - -/* Convert from one address space to another. */ -static rtx -spu_addr_space_convert (rtx op, tree from_type, tree to_type) -{ - addr_space_t from_as = TYPE_ADDR_SPACE (TREE_TYPE (from_type)); - addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (to_type)); - - gcc_assert (from_as == ADDR_SPACE_GENERIC || from_as == ADDR_SPACE_EA); - gcc_assert (to_as == ADDR_SPACE_GENERIC || to_as == ADDR_SPACE_EA); - - if (to_as == ADDR_SPACE_GENERIC && from_as == ADDR_SPACE_EA) - { - rtx result, ls; - - ls = gen_const_mem (DImode, - gen_rtx_SYMBOL_REF (Pmode, "__ea_local_store")); - set_mem_align (ls, 128); - - result = gen_reg_rtx (Pmode); - ls = force_reg (Pmode, convert_modes (Pmode, DImode, ls, 1)); - op = force_reg (Pmode, convert_modes (Pmode, EAmode, op, 1)); - ls = emit_conditional_move (ls, NE, op, const0_rtx, Pmode, - ls, const0_rtx, Pmode, 1); - - emit_insn (gen_subsi3 (result, op, ls)); - - return result; - } - - else if (to_as == ADDR_SPACE_EA && from_as == ADDR_SPACE_GENERIC) - { - rtx result, ls; - - ls = gen_const_mem (DImode, - gen_rtx_SYMBOL_REF (Pmode, "__ea_local_store")); - set_mem_align (ls, 128); - - result = gen_reg_rtx (EAmode); - ls = force_reg (EAmode, convert_modes (EAmode, DImode, ls, 1)); - op = force_reg (Pmode, op); - ls = emit_conditional_move (ls, NE, op, const0_rtx, Pmode, - ls, const0_rtx, EAmode, 1); - op = force_reg (EAmode, convert_modes (EAmode, Pmode, op, 1)); - - if (EAmode == SImode) - emit_insn (gen_addsi3 (result, op, ls)); - else - emit_insn (gen_adddi3 (result, op, ls)); - - return result; - } - - else - gcc_unreachable (); -} - - -/* Count the total number of instructions in each pipe and return the - maximum, which is used as the Minimum Iteration Interval (MII) - in the modulo scheduler. get_pipe() will return -2, -1, 0, or 1. - -2 are instructions that can go in pipe0 or pipe1. */ -static int -spu_sms_res_mii (struct ddg *g) -{ - int i; - unsigned t[4] = {0, 0, 0, 0}; - - for (i = 0; i < g->num_nodes; i++) - { - rtx_insn *insn = g->nodes[i].insn; - int p = get_pipe (insn) + 2; - - gcc_assert (p >= 0); - gcc_assert (p < 4); - - t[p]++; - if (dump_file && INSN_P (insn)) - fprintf (dump_file, "i%d %s %d %d\n", - INSN_UID (insn), - insn_data[INSN_CODE(insn)].name, - p, t[p]); - } - if (dump_file) - fprintf (dump_file, "%d %d %d %d\n", t[0], t[1], t[2], t[3]); - - return MAX ((t[0] + t[2] + t[3] + 1) / 2, MAX (t[2], t[3])); -} - - -void -spu_init_expanders (void) -{ - if (cfun) - { - rtx r0, r1; - /* HARD_FRAME_REGISTER is only 128 bit aligned when - frame_pointer_needed is true. We don't know that until we're - expanding the prologue. */ - REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = 8; - - /* A number of passes use LAST_VIRTUAL_REGISTER+1 and - LAST_VIRTUAL_REGISTER+2 to test the back-end. We want them - to be treated as aligned, so generate them here. */ - r0 = gen_reg_rtx (SImode); - r1 = gen_reg_rtx (SImode); - mark_reg_pointer (r0, 128); - mark_reg_pointer (r1, 128); - gcc_assert (REGNO (r0) == LAST_VIRTUAL_REGISTER + 1 - && REGNO (r1) == LAST_VIRTUAL_REGISTER + 2); - } -} - -static scalar_int_mode -spu_libgcc_cmp_return_mode (void) -{ - -/* For SPU word mode is TI mode so it is better to use SImode - for compare returns. */ - return SImode; -} - -static scalar_int_mode -spu_libgcc_shift_count_mode (void) -{ -/* For SPU word mode is TI mode so it is better to use SImode - for shift counts. */ - return SImode; -} - -/* Implement targetm.section_type_flags. */ -static unsigned int -spu_section_type_flags (tree decl, const char *name, int reloc) -{ - /* .toe needs to have type @nobits. */ - if (strcmp (name, ".toe") == 0) - return SECTION_BSS; - /* Don't load _ea into the current address space. */ - if (strcmp (name, "._ea") == 0) - return SECTION_WRITE | SECTION_DEBUG; - return default_section_type_flags (decl, name, reloc); -} - -/* Implement targetm.select_section. */ -static section * -spu_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align) -{ - /* Variables and constants defined in the __ea address space - go into a special section named "._ea". */ - if (TREE_TYPE (decl) != error_mark_node - && TYPE_ADDR_SPACE (TREE_TYPE (decl)) == ADDR_SPACE_EA) - { - /* We might get called with string constants, but get_named_section - doesn't like them as they are not DECLs. Also, we need to set - flags in that case. */ - if (!DECL_P (decl)) - return get_section ("._ea", SECTION_WRITE | SECTION_DEBUG, NULL); - - return get_named_section (decl, "._ea", reloc); - } - - return default_elf_select_section (decl, reloc, align); -} - -/* Implement targetm.unique_section. */ -static void -spu_unique_section (tree decl, int reloc) -{ - /* We don't support unique section names in the __ea address - space for now. */ - if (TREE_TYPE (decl) != error_mark_node - && TYPE_ADDR_SPACE (TREE_TYPE (decl)) != 0) - return; - - default_unique_section (decl, reloc); -} - -/* Generate a constant or register which contains 2^SCALE. We assume - the result is valid for MODE. Currently, MODE must be V4SFmode and - SCALE must be SImode. */ -rtx -spu_gen_exp2 (machine_mode mode, rtx scale) -{ - gcc_assert (mode == V4SFmode); - gcc_assert (GET_MODE (scale) == SImode || GET_CODE (scale) == CONST_INT); - if (GET_CODE (scale) != CONST_INT) - { - /* unsigned int exp = (127 + scale) << 23; - __vector float m = (__vector float) spu_splats (exp); */ - rtx reg = force_reg (SImode, scale); - rtx exp = gen_reg_rtx (SImode); - rtx mul = gen_reg_rtx (mode); - emit_insn (gen_addsi3 (exp, reg, GEN_INT (127))); - emit_insn (gen_ashlsi3 (exp, exp, GEN_INT (23))); - emit_insn (gen_spu_splats (mul, gen_rtx_SUBREG (GET_MODE_INNER (mode), exp, 0))); - return mul; - } - else - { - HOST_WIDE_INT exp = 127 + INTVAL (scale); - unsigned char arr[16]; - arr[0] = arr[4] = arr[8] = arr[12] = exp >> 1; - arr[1] = arr[5] = arr[9] = arr[13] = exp << 7; - arr[2] = arr[6] = arr[10] = arr[14] = 0; - arr[3] = arr[7] = arr[11] = arr[15] = 0; - return array_to_constant (mode, arr); - } -} - -/* After reload, just change the convert into a move instruction - or a dead instruction. */ -void -spu_split_convert (rtx ops[]) -{ - if (REGNO (ops[0]) == REGNO (ops[1])) - emit_note (NOTE_INSN_DELETED); - else - { - /* Use TImode always as this might help hard reg copyprop. */ - rtx op0 = gen_rtx_REG (TImode, REGNO (ops[0])); - rtx op1 = gen_rtx_REG (TImode, REGNO (ops[1])); - emit_insn (gen_move_insn (op0, op1)); - } -} - -void -spu_function_profiler (FILE * file, int labelno ATTRIBUTE_UNUSED) -{ - fprintf (file, "# profile\n"); - fprintf (file, "brsl $75, _mcount\n"); -} - -/* Implement targetm.ref_may_alias_errno. */ -static bool -spu_ref_may_alias_errno (ao_ref *ref) -{ - tree base = ao_ref_base (ref); - - /* With SPU newlib, errno is defined as something like - _impure_data._errno - The default implementation of this target macro does not - recognize such expressions, so special-code for it here. */ - - if (TREE_CODE (base) == VAR_DECL - && !TREE_STATIC (base) - && DECL_EXTERNAL (base) - && TREE_CODE (TREE_TYPE (base)) == RECORD_TYPE - && strcmp (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (base)), - "_impure_data") == 0 - /* _errno is the first member of _impure_data. */ - && ref->offset == 0) - return true; - - return default_ref_may_alias_errno (ref); -} - -/* Output thunk to FILE that implements a C++ virtual function call (with - multiple inheritance) to FUNCTION. The thunk adjusts the this pointer - by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment - stored at VCALL_OFFSET in the vtable whose address is located at offset 0 - relative to the resulting this pointer. */ - -static void -spu_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED, - HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset, - tree function) -{ - const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk)); - rtx op[8]; - - assemble_start_function (thunk, fnname); - /* Make sure unwind info is emitted for the thunk if needed. */ - final_start_function (emit_barrier (), file, 1); - - /* Operand 0 is the target function. */ - op[0] = XEXP (DECL_RTL (function), 0); - - /* Operand 1 is the 'this' pointer. */ - if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function)) - op[1] = gen_rtx_REG (Pmode, FIRST_ARG_REGNUM + 1); - else - op[1] = gen_rtx_REG (Pmode, FIRST_ARG_REGNUM); - - /* Operands 2/3 are the low/high halfwords of delta. */ - op[2] = GEN_INT (trunc_int_for_mode (delta, HImode)); - op[3] = GEN_INT (trunc_int_for_mode (delta >> 16, HImode)); - - /* Operands 4/5 are the low/high halfwords of vcall_offset. */ - op[4] = GEN_INT (trunc_int_for_mode (vcall_offset, HImode)); - op[5] = GEN_INT (trunc_int_for_mode (vcall_offset >> 16, HImode)); - - /* Operands 6/7 are temporary registers. */ - op[6] = gen_rtx_REG (Pmode, 79); - op[7] = gen_rtx_REG (Pmode, 78); - - /* Add DELTA to this pointer. */ - if (delta) - { - if (delta >= -0x200 && delta < 0x200) - output_asm_insn ("ai\t%1,%1,%2", op); - else if (delta >= -0x8000 && delta < 0x8000) - { - output_asm_insn ("il\t%6,%2", op); - output_asm_insn ("a\t%1,%1,%6", op); - } - else - { - output_asm_insn ("ilhu\t%6,%3", op); - output_asm_insn ("iohl\t%6,%2", op); - output_asm_insn ("a\t%1,%1,%6", op); - } - } - - /* Perform vcall adjustment. */ - if (vcall_offset) - { - output_asm_insn ("lqd\t%7,0(%1)", op); - output_asm_insn ("rotqby\t%7,%7,%1", op); - - if (vcall_offset >= -0x200 && vcall_offset < 0x200) - output_asm_insn ("ai\t%7,%7,%4", op); - else if (vcall_offset >= -0x8000 && vcall_offset < 0x8000) - { - output_asm_insn ("il\t%6,%4", op); - output_asm_insn ("a\t%7,%7,%6", op); - } - else - { - output_asm_insn ("ilhu\t%6,%5", op); - output_asm_insn ("iohl\t%6,%4", op); - output_asm_insn ("a\t%7,%7,%6", op); - } - - output_asm_insn ("lqd\t%6,0(%7)", op); - output_asm_insn ("rotqby\t%6,%6,%7", op); - output_asm_insn ("a\t%1,%1,%6", op); - } - - /* Jump to target. */ - output_asm_insn ("br\t%0", op); - - final_end_function (); - assemble_end_function (thunk, fnname); -} - -/* Canonicalize a comparison from one we don't have to one we do have. */ -static void -spu_canonicalize_comparison (int *code, rtx *op0, rtx *op1, - bool op0_preserve_value) -{ - if (!op0_preserve_value - && (*code == LE || *code == LT || *code == LEU || *code == LTU)) - { - rtx tem = *op0; - *op0 = *op1; - *op1 = tem; - *code = (int)swap_condition ((enum rtx_code)*code); - } -} - -/* Expand an atomic fetch-and-operate pattern. CODE is the binary operation - to perform. MEM is the memory on which to operate. VAL is the second - operand of the binary operator. BEFORE and AFTER are optional locations to - return the value of MEM either before of after the operation. */ -void -spu_expand_atomic_op (enum rtx_code code, rtx mem, rtx val, - rtx orig_before, rtx orig_after) -{ - machine_mode mode = GET_MODE (mem); - rtx before = orig_before, after = orig_after; - - if (before == NULL_RTX) - before = gen_reg_rtx (mode); - - emit_move_insn (before, mem); - - if (code == MULT) /* NAND operation */ - { - rtx x = expand_simple_binop (mode, AND, before, val, - NULL_RTX, 1, OPTAB_LIB_WIDEN); - after = expand_simple_unop (mode, NOT, x, after, 1); - } - else - { - after = expand_simple_binop (mode, code, before, val, - after, 1, OPTAB_LIB_WIDEN); - } - - emit_move_insn (mem, after); - - if (orig_after && after != orig_after) - emit_move_insn (orig_after, after); -} - -/* Implement TARGET_MODES_TIEABLE_P. */ - -static bool -spu_modes_tieable_p (machine_mode mode1, machine_mode mode2) -{ - return (GET_MODE_BITSIZE (mode1) <= MAX_FIXED_MODE_SIZE - && GET_MODE_BITSIZE (mode2) <= MAX_FIXED_MODE_SIZE); -} - -/* Implement TARGET_CAN_CHANGE_MODE_CLASS. GCC assumes that modes are - in the lowpart of a register, which is only true for SPU. */ - -static bool -spu_can_change_mode_class (machine_mode from, machine_mode to, reg_class_t) -{ - return (GET_MODE_SIZE (from) == GET_MODE_SIZE (to) - || (GET_MODE_SIZE (from) <= 4 && GET_MODE_SIZE (to) <= 4) - || (GET_MODE_SIZE (from) >= 16 && GET_MODE_SIZE (to) >= 16)); -} - -/* Implement TARGET_TRULY_NOOP_TRUNCATION. */ - -static bool -spu_truly_noop_truncation (poly_uint64 outprec, poly_uint64 inprec) -{ - return inprec <= 32 && outprec <= inprec; -} - -/* Implement TARGET_STATIC_RTX_ALIGNMENT. - - Make all static objects 16-byte aligned. This allows us to assume - they are also padded to 16 bytes, which means we can use a single - load or store instruction to access them. */ - -static HOST_WIDE_INT -spu_static_rtx_alignment (machine_mode mode) -{ - return MAX (GET_MODE_ALIGNMENT (mode), 128); -} - -/* Implement TARGET_CONSTANT_ALIGNMENT. - - Make all static objects 16-byte aligned. This allows us to assume - they are also padded to 16 bytes, which means we can use a single - load or store instruction to access them. */ - -static HOST_WIDE_INT -spu_constant_alignment (const_tree, HOST_WIDE_INT align) -{ - return MAX (align, 128); -} - -/* Table of machine attributes. */ -static const struct attribute_spec spu_attribute_table[] = -{ - /* { name, min_len, max_len, decl_req, type_req, fn_type_req, - affects_type_identity, handler, exclude } */ - { "naked", 0, 0, true, false, false, false, - spu_handle_fndecl_attribute, NULL }, - { "spu_vector", 0, 0, false, true, false, false, - spu_handle_vector_attribute, NULL }, - { NULL, 0, 0, false, false, false, false, NULL, NULL } -}; - -/* TARGET overrides. */ - -#undef TARGET_LRA_P -#define TARGET_LRA_P hook_bool_void_false - -#undef TARGET_ADDR_SPACE_POINTER_MODE -#define TARGET_ADDR_SPACE_POINTER_MODE spu_addr_space_pointer_mode - -#undef TARGET_ADDR_SPACE_ADDRESS_MODE -#define TARGET_ADDR_SPACE_ADDRESS_MODE spu_addr_space_address_mode - -#undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P -#define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P \ - spu_addr_space_legitimate_address_p - -#undef TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS -#define TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS spu_addr_space_legitimize_address - -#undef TARGET_ADDR_SPACE_SUBSET_P -#define TARGET_ADDR_SPACE_SUBSET_P spu_addr_space_subset_p - -#undef TARGET_ADDR_SPACE_CONVERT -#define TARGET_ADDR_SPACE_CONVERT spu_addr_space_convert - -#undef TARGET_INIT_BUILTINS -#define TARGET_INIT_BUILTINS spu_init_builtins -#undef TARGET_BUILTIN_DECL -#define TARGET_BUILTIN_DECL spu_builtin_decl - -#undef TARGET_EXPAND_BUILTIN -#define TARGET_EXPAND_BUILTIN spu_expand_builtin - -#undef TARGET_UNWIND_WORD_MODE -#define TARGET_UNWIND_WORD_MODE spu_unwind_word_mode - -#undef TARGET_LEGITIMIZE_ADDRESS -#define TARGET_LEGITIMIZE_ADDRESS spu_legitimize_address - -/* The current assembler doesn't like .4byte foo@ppu, so use the normal .long - and .quad for the debugger. When it is known that the assembler is fixed, - these can be removed. */ -#undef TARGET_ASM_UNALIGNED_SI_OP -#define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t" - -#undef TARGET_ASM_ALIGNED_DI_OP -#define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t" - -/* The .8byte directive doesn't seem to work well for a 32 bit - architecture. */ -#undef TARGET_ASM_UNALIGNED_DI_OP -#define TARGET_ASM_UNALIGNED_DI_OP NULL - -#undef TARGET_RTX_COSTS -#define TARGET_RTX_COSTS spu_rtx_costs - -#undef TARGET_ADDRESS_COST -#define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0 - -#undef TARGET_SCHED_ISSUE_RATE -#define TARGET_SCHED_ISSUE_RATE spu_sched_issue_rate - -#undef TARGET_SCHED_INIT_GLOBAL -#define TARGET_SCHED_INIT_GLOBAL spu_sched_init_global - -#undef TARGET_SCHED_INIT -#define TARGET_SCHED_INIT spu_sched_init - -#undef TARGET_SCHED_VARIABLE_ISSUE -#define TARGET_SCHED_VARIABLE_ISSUE spu_sched_variable_issue - -#undef TARGET_SCHED_REORDER -#define TARGET_SCHED_REORDER spu_sched_reorder - -#undef TARGET_SCHED_REORDER2 -#define TARGET_SCHED_REORDER2 spu_sched_reorder - -#undef TARGET_SCHED_ADJUST_COST -#define TARGET_SCHED_ADJUST_COST spu_sched_adjust_cost - -#undef TARGET_ATTRIBUTE_TABLE -#define TARGET_ATTRIBUTE_TABLE spu_attribute_table - -#undef TARGET_ASM_INTEGER -#define TARGET_ASM_INTEGER spu_assemble_integer - -#undef TARGET_SCALAR_MODE_SUPPORTED_P -#define TARGET_SCALAR_MODE_SUPPORTED_P spu_scalar_mode_supported_p - -#undef TARGET_VECTOR_MODE_SUPPORTED_P -#define TARGET_VECTOR_MODE_SUPPORTED_P spu_vector_mode_supported_p - -#undef TARGET_FUNCTION_OK_FOR_SIBCALL -#define TARGET_FUNCTION_OK_FOR_SIBCALL spu_function_ok_for_sibcall - -#undef TARGET_ASM_GLOBALIZE_LABEL -#define TARGET_ASM_GLOBALIZE_LABEL spu_asm_globalize_label - -#undef TARGET_PASS_BY_REFERENCE -#define TARGET_PASS_BY_REFERENCE spu_pass_by_reference - -#undef TARGET_FUNCTION_ARG -#define TARGET_FUNCTION_ARG spu_function_arg - -#undef TARGET_FUNCTION_ARG_ADVANCE -#define TARGET_FUNCTION_ARG_ADVANCE spu_function_arg_advance - -#undef TARGET_FUNCTION_ARG_OFFSET -#define TARGET_FUNCTION_ARG_OFFSET spu_function_arg_offset - -#undef TARGET_FUNCTION_ARG_PADDING -#define TARGET_FUNCTION_ARG_PADDING spu_function_arg_padding - -#undef TARGET_MUST_PASS_IN_STACK -#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size - -#undef TARGET_BUILD_BUILTIN_VA_LIST -#define TARGET_BUILD_BUILTIN_VA_LIST spu_build_builtin_va_list - -#undef TARGET_EXPAND_BUILTIN_VA_START -#define TARGET_EXPAND_BUILTIN_VA_START spu_va_start - -#undef TARGET_SETUP_INCOMING_VARARGS -#define TARGET_SETUP_INCOMING_VARARGS spu_setup_incoming_varargs - -#undef TARGET_MACHINE_DEPENDENT_REORG -#define TARGET_MACHINE_DEPENDENT_REORG spu_machine_dependent_reorg - -#undef TARGET_GIMPLIFY_VA_ARG_EXPR -#define TARGET_GIMPLIFY_VA_ARG_EXPR spu_gimplify_va_arg_expr - -#undef TARGET_INIT_LIBFUNCS -#define TARGET_INIT_LIBFUNCS spu_init_libfuncs - -#undef TARGET_RETURN_IN_MEMORY -#define TARGET_RETURN_IN_MEMORY spu_return_in_memory - -#undef TARGET_ENCODE_SECTION_INFO -#define TARGET_ENCODE_SECTION_INFO spu_encode_section_info - -#undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD -#define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD spu_builtin_mask_for_load - -#undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST -#define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST spu_builtin_vectorization_cost - -#undef TARGET_VECTORIZE_INIT_COST -#define TARGET_VECTORIZE_INIT_COST spu_init_cost - -#undef TARGET_VECTORIZE_ADD_STMT_COST -#define TARGET_VECTORIZE_ADD_STMT_COST spu_add_stmt_cost - -#undef TARGET_VECTORIZE_FINISH_COST -#define TARGET_VECTORIZE_FINISH_COST spu_finish_cost - -#undef TARGET_VECTORIZE_DESTROY_COST_DATA -#define TARGET_VECTORIZE_DESTROY_COST_DATA spu_destroy_cost_data - -#undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE -#define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE spu_vector_alignment_reachable - -#undef TARGET_LIBGCC_CMP_RETURN_MODE -#define TARGET_LIBGCC_CMP_RETURN_MODE spu_libgcc_cmp_return_mode - -#undef TARGET_LIBGCC_SHIFT_COUNT_MODE -#define TARGET_LIBGCC_SHIFT_COUNT_MODE spu_libgcc_shift_count_mode - -#undef TARGET_SCHED_SMS_RES_MII -#define TARGET_SCHED_SMS_RES_MII spu_sms_res_mii - -#undef TARGET_SECTION_TYPE_FLAGS -#define TARGET_SECTION_TYPE_FLAGS spu_section_type_flags - -#undef TARGET_ASM_SELECT_SECTION -#define TARGET_ASM_SELECT_SECTION spu_select_section - -#undef TARGET_ASM_UNIQUE_SECTION -#define TARGET_ASM_UNIQUE_SECTION spu_unique_section - -#undef TARGET_LEGITIMATE_ADDRESS_P -#define TARGET_LEGITIMATE_ADDRESS_P spu_legitimate_address_p - -#undef TARGET_LEGITIMATE_CONSTANT_P -#define TARGET_LEGITIMATE_CONSTANT_P spu_legitimate_constant_p - -#undef TARGET_TRAMPOLINE_INIT -#define TARGET_TRAMPOLINE_INIT spu_trampoline_init - -#undef TARGET_WARN_FUNC_RETURN -#define TARGET_WARN_FUNC_RETURN spu_warn_func_return - -#undef TARGET_OPTION_OVERRIDE -#define TARGET_OPTION_OVERRIDE spu_option_override - -#undef TARGET_CONDITIONAL_REGISTER_USAGE -#define TARGET_CONDITIONAL_REGISTER_USAGE spu_conditional_register_usage - -#undef TARGET_REF_MAY_ALIAS_ERRNO -#define TARGET_REF_MAY_ALIAS_ERRNO spu_ref_may_alias_errno - -#undef TARGET_ASM_OUTPUT_MI_THUNK -#define TARGET_ASM_OUTPUT_MI_THUNK spu_output_mi_thunk -#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK -#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true - -/* Variable tracking should be run after all optimizations which - change order of insns. It also needs a valid CFG. */ -#undef TARGET_DELAY_VARTRACK -#define TARGET_DELAY_VARTRACK true - -#undef TARGET_CANONICALIZE_COMPARISON -#define TARGET_CANONICALIZE_COMPARISON spu_canonicalize_comparison - -#undef TARGET_CAN_USE_DOLOOP_P -#define TARGET_CAN_USE_DOLOOP_P can_use_doloop_if_innermost - -#undef TARGET_MODES_TIEABLE_P -#define TARGET_MODES_TIEABLE_P spu_modes_tieable_p - -#undef TARGET_HARD_REGNO_NREGS -#define TARGET_HARD_REGNO_NREGS spu_hard_regno_nregs - -#undef TARGET_CAN_CHANGE_MODE_CLASS -#define TARGET_CAN_CHANGE_MODE_CLASS spu_can_change_mode_class - -#undef TARGET_TRULY_NOOP_TRUNCATION -#define TARGET_TRULY_NOOP_TRUNCATION spu_truly_noop_truncation - -#undef TARGET_STATIC_RTX_ALIGNMENT -#define TARGET_STATIC_RTX_ALIGNMENT spu_static_rtx_alignment -#undef TARGET_CONSTANT_ALIGNMENT -#define TARGET_CONSTANT_ALIGNMENT spu_constant_alignment - -#undef TARGET_HAVE_SPECULATION_SAFE_VALUE -#define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed - -struct gcc_target targetm = TARGET_INITIALIZER; - -#include "gt-spu.h" diff --git a/gcc/config/spu/spu.h b/gcc/config/spu/spu.h deleted file mode 100644 index 4af55bd..0000000 --- a/gcc/config/spu/spu.h +++ /dev/null @@ -1,517 +0,0 @@ -/* Copyright (C) 2006-2019 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - . */ - - -/* Run-time Target */ -#define TARGET_CPU_CPP_BUILTINS() spu_cpu_cpp_builtins(pfile) - -#define C_COMMON_OVERRIDE_OPTIONS spu_c_common_override_options() - -#define INIT_EXPANDERS spu_init_expanders() - -/* Which processor to generate code or schedule for. */ -enum processor_type -{ - PROCESSOR_CELL, - PROCESSOR_CELLEDP -}; - -extern GTY(()) int spu_arch; -extern GTY(()) int spu_tune; - -/* Support for a compile-time default architecture and tuning. The rules are: - --with-arch is ignored if -march is specified. - --with-tune is ignored if -mtune is specified. */ -#define OPTION_DEFAULT_SPECS \ - {"arch", "%{!march=*:-march=%(VALUE)}" }, \ - {"tune", "%{!mtune=*:-mtune=%(VALUE)}" } - -/* Default target_flags if no switches specified. */ -#ifndef TARGET_DEFAULT -#define TARGET_DEFAULT (MASK_ERROR_RELOC | MASK_SAFE_DMA | MASK_BRANCH_HINTS \ - | MASK_SAFE_HINTS | MASK_ADDRESS_SPACE_CONVERSION) -#endif - - -/* Storage Layout */ - -#define BITS_BIG_ENDIAN 1 - -#define BYTES_BIG_ENDIAN 1 - -#define WORDS_BIG_ENDIAN 1 - -/* GCC uses word_mode in many places, assuming that it is the fastest - integer mode. That is not the case for SPU though. We can't use - 32 here because (of some reason I can't remember.) */ -#define BITS_PER_WORD 128 - -#define UNITS_PER_WORD (BITS_PER_WORD/BITS_PER_UNIT) - -/* When building libgcc, we need to assume 4 words per units even - though UNITS_PER_WORD is 16, because the SPU has basically a 32-bit - instruction set although register size is 128 bits. In particular, - this causes libgcc to contain __divdi3 instead of __divti3 etc. - However, we allow this default to be re-defined on the command - line, so that we can use the LIB2_SIDITI_CONV_FUNCS mechanism - to get (in addition) TImode versions of some routines. */ -#ifndef LIBGCC2_UNITS_PER_WORD -#define LIBGCC2_UNITS_PER_WORD 4 -#endif - -#define POINTER_SIZE 32 - -#define PARM_BOUNDARY 128 - -#define STACK_BOUNDARY 128 - -/* We want it 8-byte aligned so we can properly use dual-issue - instructions, which can only happen on an 8-byte aligned address. */ -#define FUNCTION_BOUNDARY 64 - -/* We would like to allow a larger alignment for data objects (for DMA) - but the aligned attribute is limited by BIGGEST_ALIGNMENT. We don't - define BIGGEST_ALIGNMENT as larger because it is used in other places - and would end up wasting space. (Is this still true?) */ -#define BIGGEST_ALIGNMENT 128 - -#define MINIMUM_ATOMIC_ALIGNMENT 128 - -/* Make all static objects 16-byte aligned. This allows us to assume - they are also padded to 16-bytes, which means we can use a single - load or store instruction to access them. Do the same for objects - on the stack. (Except a bug (?) allows some stack objects to be - unaligned.) */ -#define DATA_ALIGNMENT(TYPE,ALIGN) ((ALIGN) > 128 ? (ALIGN) : 128) -#define LOCAL_ALIGNMENT(TYPE,ALIGN) ((ALIGN) > 128 ? (ALIGN) : 128) - -#define EMPTY_FIELD_BOUNDARY 32 - -#define STRICT_ALIGNMENT 1 - -/* symbol_ref's of functions are not aligned to 16 byte boundary. */ -#define ALIGNED_SYMBOL_REF_P(X) \ - (GET_CODE (X) == SYMBOL_REF \ - && (SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_ALIGN1) == 0 \ - && (! SYMBOL_REF_FUNCTION_P (X) \ - || align_functions.levels[0].get_value () >= 16)) - -#define PCC_BITFIELD_TYPE_MATTERS 1 - -#define MAX_FIXED_MODE_SIZE 128 - -#define STACK_SAVEAREA_MODE(save_level) \ - (save_level == SAVE_FUNCTION ? VOIDmode \ - : save_level == SAVE_NONLOCAL ? SImode \ - : Pmode) - -#define STACK_SIZE_MODE SImode - - -/* Type Layout */ - -#define INT_TYPE_SIZE 32 - -#define LONG_TYPE_SIZE 32 - -#define LONG_LONG_TYPE_SIZE 64 - -#define FLOAT_TYPE_SIZE 32 - -#define DOUBLE_TYPE_SIZE 64 - -#define LONG_DOUBLE_TYPE_SIZE 64 - -#define DEFAULT_SIGNED_CHAR 0 - -#define STDINT_LONG32 0 - - -/* Register Basics */ - -/* 128-130 are special registers that never appear in assembly code. */ -#define FIRST_PSEUDO_REGISTER 131 - -#define FIXED_REGISTERS { \ - 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 1, 1, 1 \ -} - -#define CALL_USED_REGISTERS { \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 1, 1, 1 \ -} - - -/* Register Classes */ - -enum reg_class { - NO_REGS, - GENERAL_REGS, - ALL_REGS, - LIM_REG_CLASSES -}; - -#define N_REG_CLASSES (int) LIM_REG_CLASSES - -#define REG_CLASS_NAMES \ -{ "NO_REGS", \ - "GENERAL_REGS", \ - "ALL_REGS" \ -} - -#define REG_CLASS_CONTENTS { \ - {0, 0, 0, 0, 0}, /* no regs */ \ - {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x3}, /* general regs */ \ - {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x3}} /* all regs */ - -#define REGNO_REG_CLASS(REGNO) ((void)(REGNO), GENERAL_REGS) - - -#define BASE_REG_CLASS GENERAL_REGS - -#define INDEX_REG_CLASS GENERAL_REGS - -#define REGNO_OK_FOR_BASE_P(regno) \ - ((regno) < FIRST_PSEUDO_REGISTER || (regno > LAST_VIRTUAL_REGISTER && reg_renumber[regno] >= 0)) - -#define REGNO_OK_FOR_INDEX_P(regno) \ - ((regno) < FIRST_PSEUDO_REGISTER || (regno > LAST_VIRTUAL_REGISTER && reg_renumber[regno] >= 0)) - -#define INT_REG_OK_FOR_INDEX_P(X,STRICT) \ - ((!(STRICT) || REGNO_OK_FOR_INDEX_P (REGNO (X)))) -#define INT_REG_OK_FOR_BASE_P(X,STRICT) \ - ((!(STRICT) || REGNO_OK_FOR_BASE_P (REGNO (X)))) - -#define REGISTER_TARGET_PRAGMAS() do { \ -c_register_addr_space ("__ea", ADDR_SPACE_EA); \ -targetm.resolve_overloaded_builtin = spu_resolve_overloaded_builtin; \ -}while (0) - - -/* Frame Layout */ - -#define STACK_GROWS_DOWNWARD 1 - -#define FRAME_GROWS_DOWNWARD 1 - -#define STACK_POINTER_OFFSET 32 - -#define FIRST_PARM_OFFSET(FNDECL) (0) - -#define DYNAMIC_CHAIN_ADDRESS(FP) plus_constant (Pmode, (FP), -16) - -#define RETURN_ADDR_RTX(COUNT,FP) (spu_return_addr (COUNT, FP)) - -/* Should this be defined? Would it simplify our implementation. */ -/* #define RETURN_ADDR_IN_PREVIOUS_FRAME */ - -#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG(Pmode, LINK_REGISTER_REGNUM) - -#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (LINK_REGISTER_REGNUM) - -#define ARG_POINTER_CFA_OFFSET(FNDECL) \ - (crtl->args.pretend_args_size - STACK_POINTER_OFFSET) - - -/* Stack Checking */ - -/* We store the Available Stack Size in the second slot of the stack - register. We emit stack checking code during the prologue. */ -#define STACK_CHECK_BUILTIN 1 - - -/* Frame Registers, and other registers */ - -#define STACK_POINTER_REGNUM 1 - -/* Will be eliminated. */ -#define FRAME_POINTER_REGNUM 128 - -/* This is not specified in any ABI, so could be set to anything. */ -#define HARD_FRAME_POINTER_REGNUM 127 - -/* Will be eliminated. */ -#define ARG_POINTER_REGNUM 129 - -#define STATIC_CHAIN_REGNUM 2 - -#define LINK_REGISTER_REGNUM 0 - -/* Used to keep track of instructions that have clobbered the hint - * buffer. Users can also specify it in inline asm. */ -#define HBR_REGNUM 130 - -#define MAX_REGISTER_ARGS 72 -#define FIRST_ARG_REGNUM 3 -#define LAST_ARG_REGNUM (FIRST_ARG_REGNUM + MAX_REGISTER_ARGS - 1) - -#define MAX_REGISTER_RETURN 72 -#define FIRST_RETURN_REGNUM 3 -#define LAST_RETURN_REGNUM (FIRST_RETURN_REGNUM + MAX_REGISTER_RETURN - 1) - - -/* Elimination */ - -#define ELIMINABLE_REGS \ - {{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ - {ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \ - {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ - {FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}} - -#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ - ((OFFSET) = spu_initial_elimination_offset((FROM),(TO))) - - -/* Stack Arguments */ - -#define ACCUMULATE_OUTGOING_ARGS 1 - -#define REG_PARM_STACK_SPACE(FNDECL) 0 - -#define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1 - - -/* Register Arguments */ - -#define CUMULATIVE_ARGS int - -#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,FNDECL,N_NAMED_ARGS) \ - ((CUM) = 0) - -#define PAD_VARARGS_DOWN 0 - -#define FUNCTION_ARG_REGNO_P(N) ((N) >= (FIRST_ARG_REGNUM) && (N) <= (LAST_ARG_REGNUM)) - -/* Scalar Return */ - -#define FUNCTION_VALUE(VALTYPE, FUNC) \ - (spu_function_value((VALTYPE),(FUNC))) - -#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, FIRST_RETURN_REGNUM) - -#define FUNCTION_VALUE_REGNO_P(N) ((N) >= (FIRST_RETURN_REGNUM) && (N) <= (LAST_RETURN_REGNUM)) - - -/* Machine-specific symbol_ref flags. */ -#define SYMBOL_FLAG_ALIGN1 (SYMBOL_FLAG_MACH_DEP << 0) - -/* Aggregate Return */ - -#define DEFAULT_PCC_STRUCT_RETURN 0 - - -/* Function Entry */ - -#define EXIT_IGNORE_STACK 0 - -#define EPILOGUE_USES(REGNO) ((REGNO)==1 ? 1 : 0) - - -/* Profiling */ - -#define FUNCTION_PROFILER(FILE, LABELNO) \ - spu_function_profiler ((FILE), (LABELNO)); - -#define NO_PROFILE_COUNTERS 1 - -#define PROFILE_BEFORE_PROLOGUE 1 - - -/* Trampolines */ - -#define TRAMPOLINE_SIZE (TARGET_LARGE_MEM ? 20 : 16) - -#define TRAMPOLINE_ALIGNMENT 128 - -/* Addressing Modes */ - -#define CONSTANT_ADDRESS_P(X) spu_constant_address_p(X) - -#define MAX_REGS_PER_ADDRESS 2 - -#define LEGITIMIZE_RELOAD_ADDRESS(AD, MODE, OPNUM, TYPE, IND, WIN) \ -do { \ - rtx new_rtx = spu_legitimize_reload_address (AD, MODE, OPNUM, \ - (int)(TYPE)); \ - if (new_rtx) \ - { \ - (AD) = new_rtx; \ - goto WIN; \ - } \ -} while (0) - - -/* Costs */ - -#define BRANCH_COST(speed_p, predictable_p) spu_branch_cost - -#define SLOW_BYTE_ACCESS 0 - -#define MOVE_RATIO(speed) ((speed)? 32 : 4) - -#define NO_FUNCTION_CSE 1 - - -/* Sections */ - -#define TEXT_SECTION_ASM_OP ".text" - -#define DATA_SECTION_ASM_OP ".data" - -#define JUMP_TABLES_IN_TEXT_SECTION 1 - - -/* PIC */ -#define PIC_OFFSET_TABLE_REGNUM 126 - - -/* File Framework */ - -#define ASM_APP_ON "" - -#define ASM_APP_OFF "" - - -/* Uninitialized Data */ -#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \ -( fputs (".comm ", (FILE)), \ - assemble_name ((FILE), (NAME)), \ - fprintf ((FILE), ",%d\n", (ROUNDED))) - -#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ -( fputs (".lcomm ", (FILE)), \ - assemble_name ((FILE), (NAME)), \ - fprintf ((FILE), ",%d\n", (ROUNDED))) - - -/* Label Output */ -#define ASM_OUTPUT_LABEL(FILE,NAME) \ - do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0) - -#define ASM_OUTPUT_LABELREF(FILE, NAME) \ - asm_fprintf (FILE, "%U%s", default_strip_name_encoding (NAME)) - -#define ASM_OUTPUT_SYMBOL_REF(FILE, X) \ - do \ - { \ - tree decl; \ - assemble_name (FILE, XSTR ((X), 0)); \ - if ((decl = SYMBOL_REF_DECL ((X))) != 0 \ - && TREE_CODE (decl) == VAR_DECL \ - && TYPE_ADDR_SPACE (TREE_TYPE (decl))) \ - fputs ("@ppu", FILE); \ - } while (0) - - -/* Instruction Output */ -#define REGISTER_NAMES \ -{"$lr", "$sp", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", \ - "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31", \ - "$32", "$33", "$34", "$35", "$36", "$37", "$38", "$39", "$40", "$41", "$42", "$43", "$44", "$45", "$46", "$47", \ - "$48", "$49", "$50", "$51", "$52", "$53", "$54", "$55", "$56", "$57", "$58", "$59", "$60", "$61", "$62", "$63", \ - "$64", "$65", "$66", "$67", "$68", "$69", "$70", "$71", "$72", "$73", "$74", "$75", "$76", "$77", "$78", "$79", \ - "$80", "$81", "$82", "$83", "$84", "$85", "$86", "$87", "$88", "$89", "$90", "$91", "$92", "$93", "$94", "$95", \ - "$96", "$97", "$98", "$99", "$100", "$101", "$102", "$103", "$104", "$105", "$106", "$107", "$108", "$109", "$110", "$111", \ - "$112", "$113", "$114", "$115", "$116", "$117", "$118", "$119", "$120", "$121", "$122", "$123", "$124", "$125", "$126", "$127", \ - "$vfp", "$vap", "hbr" \ -} - -#define PRINT_OPERAND(FILE, X, CODE) print_operand(FILE, X, CODE) - -#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \ - print_operand_address (FILE, ADDR) - -#define LOCAL_LABEL_PREFIX "." - -#define USER_LABEL_PREFIX "" - -#define ASM_COMMENT_START "#" - - -/* Dispatch Tables */ - -#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ - fprintf (FILE, "\t.word .L%d-.L%d\n", VALUE, REL) - -#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ - fprintf (FILE, "\t.word .L%d\n", VALUE) - - -/* Alignment Output */ - -#define ASM_OUTPUT_ALIGN(FILE,LOG) \ - do { if (LOG!=0) fprintf (FILE, "\t.align\t%d\n", (LOG)); } while (0) - - -/* Misc */ - -#define CASE_VECTOR_MODE SImode - -#define MOVE_MAX 16 - -#define STORE_FLAG_VALUE -1 - -#define Pmode SImode - -#define FUNCTION_MODE QImode - - -/* Address spaces. */ -#define ADDR_SPACE_EA 1 - - -/* Builtins. */ - -enum spu_builtin_type -{ - B_INSN, - B_JUMP, - B_BISLED, - B_CALL, - B_HINT, - B_OVERLOAD, - B_INTERNAL -}; - -struct spu_builtin_description -{ - int fcode; - int icode; - const char *name; - enum spu_builtin_type type; - - /* The first element of parm is always the return type. The rest - are a zero terminated list of parameters. */ - int parm[5]; -}; - -extern struct spu_builtin_description spu_builtins[]; - diff --git a/gcc/config/spu/spu.md b/gcc/config/spu/spu.md deleted file mode 100644 index bb62298..0000000 --- a/gcc/config/spu/spu.md +++ /dev/null @@ -1,5255 +0,0 @@ -;; Copyright (C) 2006-2019 Free Software Foundation, Inc. - -;; This file is free software; you can redistribute it and/or modify it under -;; the terms of the GNU General Public License as published by the Free -;; Software Foundation; either version 3 of the License, or (at your option) -;; any later version. - -;; This file is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -;; for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; . - -;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. - - -;; Define an insn type attribute. This is used in function unit delay -;; computations. -;; multi0 is a multiple insn rtl whose first insn is in pipe0 -;; multi1 is a multiple insn rtl whose first insn is in pipe1 -(define_attr "type" "fx2,shuf,fx3,load,store,br,spr,lnop,nop,fxb,fp6,fp7,fpd,iprefetch,multi0,multi1,hbr,convert" - (const_string "fx2")) - -;; Length (in bytes). -(define_attr "length" "" - (const_int 4)) - -(define_attr "tune" "cell,celledp" (const (symbol_ref "spu_tune"))) -;; Processor type -- this attribute must exactly match the processor_type -;; enumeration in spu.h. - -(define_attr "cpu" "spu" - (const (symbol_ref "spu_cpu_attr"))) - -; (define_function_unit NAME MULTIPLICITY SIMULTANEITY -; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST]) - -(define_cpu_unit "pipe0,pipe1,fp,ls") - -(define_insn_reservation "NOP" 1 (eq_attr "type" "nop") - "pipe0") - -(define_insn_reservation "FX2" 2 (eq_attr "type" "fx2") - "pipe0, nothing") - -(define_insn_reservation "FX3" 4 (eq_attr "type" "fx3,fxb") - "pipe0, nothing*3") - -(define_insn_reservation "FP6" 6 (eq_attr "type" "fp6") - "pipe0 + fp, nothing*5") - -(define_insn_reservation "FP7" 7 (eq_attr "type" "fp7") - "pipe0, fp, nothing*5") - -;; The behavior of the double precision is that both pipes stall -;; for 6 cycles and the rest of the operation pipelines for -;; 7 cycles. The simplest way to model this is to simply ignore -;; the 6 cyle stall. -(define_insn_reservation "FPD" 7 - (and (eq_attr "tune" "cell") - (eq_attr "type" "fpd")) - "pipe0 + pipe1, fp, nothing*5") - -;; Tune for CELLEDP, 9 cycles, dual-issuable, fully pipelined -(define_insn_reservation "FPD_CELLEDP" 9 - (and (eq_attr "tune" "celledp") - (eq_attr "type" "fpd")) - "pipe0 + fp, nothing*8") - -(define_insn_reservation "LNOP" 1 (eq_attr "type" "lnop") - "pipe1") - -(define_insn_reservation "STORE" 1 (eq_attr "type" "store") - "pipe1 + ls") - -(define_insn_reservation "IPREFETCH" 1 (eq_attr "type" "iprefetch") - "pipe1 + ls") - -(define_insn_reservation "SHUF" 4 (eq_attr "type" "shuf,br,spr") - "pipe1, nothing*3") - -(define_insn_reservation "LOAD" 6 (eq_attr "type" "load") - "pipe1 + ls, nothing*5") - -(define_insn_reservation "HBR" 18 (eq_attr "type" "hbr") - "pipe1, nothing*15") - -(define_insn_reservation "MULTI0" 4 (eq_attr "type" "multi0") - "pipe0+pipe1, nothing*3") - -(define_insn_reservation "MULTI1" 4 (eq_attr "type" "multi1") - "pipe1, nothing*3") - -(define_insn_reservation "CONVERT" 0 (eq_attr "type" "convert") - "nothing") - -;; Force pipe0 to occur before pipe 1 in a cycle. -(absence_set "pipe0" "pipe1") - - -(define_c_enum "unspec" [ - UNSPEC_IPREFETCH - UNSPEC_FREST - UNSPEC_FRSQEST - UNSPEC_FI - UNSPEC_EXTEND_CMP - UNSPEC_CG - UNSPEC_CGX - UNSPEC_ADDX - UNSPEC_BG - UNSPEC_BGX - UNSPEC_SFX - UNSPEC_FSM - UNSPEC_HBR - UNSPEC_NOP - UNSPEC_CONVERT - UNSPEC_SELB - UNSPEC_SHUFB - UNSPEC_CPAT - UNSPEC_CNTB - UNSPEC_SUMB - UNSPEC_FSMB - UNSPEC_FSMH - UNSPEC_GBB - UNSPEC_GBH - UNSPEC_GB - UNSPEC_AVGB - UNSPEC_ABSDB - UNSPEC_ORX - UNSPEC_HEQ - UNSPEC_HGT - UNSPEC_HLGT - UNSPEC_STOP - UNSPEC_STOPD - UNSPEC_SET_INTR - UNSPEC_FSCRRD - UNSPEC_FSCRWR - UNSPEC_MFSPR - UNSPEC_MTSPR - UNSPEC_RDCH - UNSPEC_RCHCNT - UNSPEC_WRCH - UNSPEC_SPU_REALIGN_LOAD - UNSPEC_SPU_MASK_FOR_LOAD - UNSPEC_DFTSV - UNSPEC_FLOAT_EXTEND - UNSPEC_FLOAT_TRUNCATE - UNSPEC_SP_SET - UNSPEC_SP_TEST -]) - -(define_c_enum "unspecv" [ - UNSPECV_BLOCKAGE - UNSPECV_LNOP - UNSPECV_NOP - UNSPECV_SYNC -]) - -(include "predicates.md") -(include "constraints.md") - - -;; Mode iterators - -(define_mode_iterator ALL [QI V16QI - HI V8HI - SI V4SI - DI V2DI - TI - SF V4SF - DF V2DF]) - -; Everything except DI and TI which are handled separately because -; they need different constraints to correctly test VOIDmode constants -(define_mode_iterator MOV [QI V16QI - HI V8HI - SI V4SI - V2DI - SF V4SF - DF V2DF]) - -(define_mode_iterator QHSI [QI HI SI]) -(define_mode_iterator QHSDI [QI HI SI DI]) -(define_mode_iterator DTI [DI TI]) - -(define_mode_iterator VINT [QI V16QI - HI V8HI - SI V4SI - DI V2DI - TI]) - -(define_mode_iterator VQHSI [QI V16QI - HI V8HI - SI V4SI]) - -(define_mode_iterator VHSI [HI V8HI - SI V4SI]) - -(define_mode_iterator VSDF [SF V4SF - DF V2DF]) - -(define_mode_iterator VSI [SI V4SI]) -(define_mode_iterator VDI [DI V2DI]) -(define_mode_iterator VSF [SF V4SF]) -(define_mode_iterator VDF [DF V2DF]) - -(define_mode_iterator VCMP [V16QI - V8HI - V4SI - V4SF - V2DF]) - -(define_mode_iterator VCMPU [V16QI - V8HI - V4SI]) - -(define_mode_attr v [(V8HI "v") (V4SI "v") - (HI "") (SI "")]) - -(define_mode_attr bh [(QI "b") (V16QI "b") - (HI "h") (V8HI "h") - (SI "") (V4SI "")]) - -(define_mode_attr d [(SF "") (V4SF "") - (DF "d") (V2DF "d")]) -(define_mode_attr d6 [(SF "6") (V4SF "6") - (DF "d") (V2DF "d")]) - -(define_mode_attr f2i [(SF "si") (V4SF "v4si") - (DF "di") (V2DF "v2di")]) -(define_mode_attr F2I [(SF "SI") (V4SF "V4SI") - (DF "DI") (V2DF "V2DI")]) -(define_mode_attr i2f [(SI "sf") (V4SI "v4sf") - (DI "df") (V2DI "v2df")]) -(define_mode_attr I2F [(SI "SF") (V4SI "V4SF") - (DI "DF") (V2DI "V2DF")]) - -(define_mode_attr DF2I [(DF "SI") (V2DF "V2DI")]) - -(define_mode_attr umask [(HI "f") (V8HI "f") - (SI "g") (V4SI "g")]) -(define_mode_attr nmask [(HI "F") (V8HI "F") - (SI "G") (V4SI "G")]) - -;; Used for carry and borrow instructions. -(define_mode_iterator CBOP [SI DI V4SI V2DI]) - -;; Used in vec_set and vec_extract -(define_mode_iterator V [V2DI V4SI V8HI V16QI V2DF V4SF]) -(define_mode_attr inner [(V16QI "QI") - (V8HI "HI") - (V4SI "SI") - (V2DI "DI") - (V4SF "SF") - (V2DF "DF")]) -;; Like above, but in lower case -(define_mode_attr inner_l [(V16QI "qi") - (V8HI "hi") - (V4SI "si") - (V2DI "di") - (V4SF "sf") - (V2DF "df")]) -(define_mode_attr vmult [(V16QI "1") - (V8HI "2") - (V4SI "4") - (V2DI "8") - (V4SF "4") - (V2DF "8")]) -(define_mode_attr voff [(V16QI "13") - (V8HI "14") - (V4SI "0") - (V2DI "0") - (V4SF "0") - (V2DF "0")]) - - -;; mov - -(define_expand "mov" - [(set (match_operand:ALL 0 "nonimmediate_operand" "") - (match_operand:ALL 1 "general_operand" ""))] - "" - { - if (spu_expand_mov(operands, mode)) - DONE; - }) - -(define_split - [(set (match_operand 0 "spu_reg_operand") - (match_operand 1 "immediate_operand"))] - - "" - [(set (match_dup 0) - (high (match_dup 1))) - (set (match_dup 0) - (lo_sum (match_dup 0) - (match_dup 1)))] - { - if (spu_split_immediate (operands)) - DONE; - FAIL; - }) - -(define_insn "pic" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (match_operand:SI 1 "immediate_operand" "s")) - (use (const_int 0))] - "flag_pic" - "ila\t%0,%%pic(%1)") - -;; Whenever a function generates the 'pic' pattern above we need to -;; load the pic_offset_table register. -;; GCC doesn't deal well with labels in the middle of a block so we -;; hardcode the offsets in the asm here. -(define_insn "load_pic_offset" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (unspec:SI [(const_int 0)] 0)) - (set (match_operand:SI 1 "spu_reg_operand" "=r") - (unspec:SI [(const_int 0)] 0))] - "flag_pic" - "ila\t%1,.+8\;brsl\t%0,4" - [(set_attr "length" "8") - (set_attr "type" "multi0")]) - - -;; move internal - -(define_insn "_mov" - [(set (match_operand:MOV 0 "spu_dest_operand" "=r,r,r,r,r,m") - (match_operand:MOV 1 "spu_mov_operand" "r,A,f,j,m,r"))] - "register_operand(operands[0], mode) - || register_operand(operands[1], mode)" - "@ - ori\t%0,%1,0 - il%s1\t%0,%S1 - fsmbi\t%0,%S1 - c%s1d\t%0,%S1($sp) - lq%p1\t%0,%1 - stq%p0\t%1,%0" - [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")]) - -(define_insn "low_" - [(set (match_operand:VSI 0 "spu_reg_operand" "=r") - (lo_sum:VSI (match_operand:VSI 1 "spu_reg_operand" "0") - (match_operand:VSI 2 "immediate_operand" "i")))] - "" - "iohl\t%0,%2@l") - -(define_insn "_movdi" - [(set (match_operand:DI 0 "spu_dest_operand" "=r,r,r,r,r,m") - (match_operand:DI 1 "spu_mov_operand" "r,a,f,k,m,r"))] - "register_operand(operands[0], DImode) - || register_operand(operands[1], DImode)" - "@ - ori\t%0,%1,0 - il%d1\t%0,%D1 - fsmbi\t%0,%D1 - c%d1d\t%0,%D1($sp) - lq%p1\t%0,%1 - stq%p0\t%1,%0" - [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")]) - -(define_insn "_movti" - [(set (match_operand:TI 0 "spu_dest_operand" "=r,r,r,r,r,m") - (match_operand:TI 1 "spu_mov_operand" "r,U,f,l,m,r"))] - "register_operand(operands[0], TImode) - || register_operand(operands[1], TImode)" - "@ - ori\t%0,%1,0 - il%t1\t%0,%T1 - fsmbi\t%0,%T1 - c%t1d\t%0,%T1($sp) - lq%p1\t%0,%1 - stq%p0\t%1,%0" - [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")]) - -(define_split - [(set (match_operand 0 "spu_reg_operand") - (match_operand 1 "memory_operand"))] - "GET_MODE_SIZE (GET_MODE (operands[0])) < 16 - && GET_MODE(operands[0]) == GET_MODE(operands[1]) - && !reload_in_progress && !reload_completed" - [(set (match_dup 0) - (match_dup 1))] - { if (spu_split_load(operands)) - DONE; - }) - -(define_split - [(set (match_operand 0 "memory_operand") - (match_operand 1 "spu_reg_operand"))] - "GET_MODE_SIZE (GET_MODE (operands[0])) < 16 - && GET_MODE(operands[0]) == GET_MODE(operands[1]) - && !reload_in_progress && !reload_completed" - [(set (match_dup 0) - (match_dup 1))] - { if (spu_split_store(operands)) - DONE; - }) -;; Operand 3 is the number of bytes. 1:b 2:h 4:w 8:d - -(define_expand "cpat" - [(set (match_operand:TI 0 "spu_reg_operand" "=r,r") - (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "r,r") - (match_operand:SI 2 "spu_nonmem_operand" "r,n") - (match_operand:SI 3 "immediate_operand" "i,i")] UNSPEC_CPAT))] - "" - { - rtx x = gen_cpat_const (operands); - if (x) - { - emit_move_insn (operands[0], x); - DONE; - } - }) - -(define_insn "_cpat" - [(set (match_operand:TI 0 "spu_reg_operand" "=r,r") - (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "r,r") - (match_operand:SI 2 "spu_nonmem_operand" "r,n") - (match_operand:SI 3 "immediate_operand" "i,i")] UNSPEC_CPAT))] - "" - "@ - c%M3x\t%0,%1,%2 - c%M3d\t%0,%C2(%1)" - [(set_attr "type" "shuf")]) - -(define_split - [(set (match_operand:TI 0 "spu_reg_operand") - (unspec:TI [(match_operand:SI 1 "spu_nonmem_operand") - (match_operand:SI 2 "immediate_operand") - (match_operand:SI 3 "immediate_operand")] UNSPEC_CPAT))] - "" - [(set (match_dup:TI 0) - (match_dup:TI 4))] - { - operands[4] = gen_cpat_const (operands); - if (!operands[4]) - FAIL; - }) - -;; extend - -(define_insn "extendqihi2" - [(set (match_operand:HI 0 "spu_reg_operand" "=r") - (sign_extend:HI (match_operand:QI 1 "spu_reg_operand" "r")))] - "" - "xsbh\t%0,%1") - -(define_insn "extendhisi2" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")))] - "" - "xshw\t%0,%1") - -(define_expand "extendsidi2" - [(set (match_dup:DI 2) - (zero_extend:DI (match_operand:SI 1 "spu_reg_operand" ""))) - (set (match_operand:DI 0 "spu_reg_operand" "") - (sign_extend:DI (vec_select:SI (match_dup:V2SI 3) - (parallel [(const_int 1)]))))] - "" - { - operands[2] = gen_reg_rtx (DImode); - operands[3] = spu_gen_subreg (V2SImode, operands[2]); - }) - -(define_insn "xswd" - [(set (match_operand:DI 0 "spu_reg_operand" "=r") - (sign_extend:DI - (vec_select:SI - (match_operand:V2SI 1 "spu_reg_operand" "r") - (parallel [(const_int 1) ]))))] - "" - "xswd\t%0,%1"); - -;; By splitting this late we don't allow much opportunity for sharing of -;; constants. That's ok because this should really be optimized away. -(define_insn_and_split "extendti2" - [(set (match_operand:TI 0 "register_operand" "") - (sign_extend:TI (match_operand:QHSDI 1 "register_operand" "")))] - "" - "#" - "" - [(set (match_dup:TI 0) - (sign_extend:TI (match_dup:QHSDI 1)))] - { - spu_expand_sign_extend(operands); - DONE; - }) - - -;; zero_extend - -(define_insn "zero_extendqihi2" - [(set (match_operand:HI 0 "spu_reg_operand" "=r") - (zero_extend:HI (match_operand:QI 1 "spu_reg_operand" "r")))] - "" - "andi\t%0,%1,0x00ff") - -(define_insn "zero_extendqisi2" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (zero_extend:SI (match_operand:QI 1 "spu_reg_operand" "r")))] - "" - "andi\t%0,%1,0x00ff") - -(define_expand "zero_extendhisi2" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))) - (clobber (match_scratch:SI 2 "=&r"))] - "" - { - rtx mask = gen_reg_rtx (SImode); - rtx op1 = simplify_gen_subreg (SImode, operands[1], HImode, 0); - emit_move_insn (mask, GEN_INT (0xffff)); - emit_insn (gen_andsi3(operands[0], op1, mask)); - DONE; - }) - -(define_insn "zero_extendsidi2" - [(set (match_operand:DI 0 "spu_reg_operand" "=r") - (zero_extend:DI (match_operand:SI 1 "spu_reg_operand" "r")))] - "" - "rotqmbyi\t%0,%1,-4" - [(set_attr "type" "shuf")]) - -(define_insn "zero_extendqiti2" - [(set (match_operand:TI 0 "spu_reg_operand" "=r") - (zero_extend:TI (match_operand:QI 1 "spu_reg_operand" "r")))] - "" - "andi\t%0,%1,0x00ff\;rotqmbyi\t%0,%0,-12" - [(set_attr "type" "multi0") - (set_attr "length" "8")]) - -(define_insn "zero_extendhiti2" - [(set (match_operand:TI 0 "spu_reg_operand" "=r") - (zero_extend:TI (match_operand:HI 1 "spu_reg_operand" "r")))] - "" - "shli\t%0,%1,16\;rotqmbyi\t%0,%0,-14" - [(set_attr "type" "multi1") - (set_attr "length" "8")]) - -(define_insn "zero_extendsiti2" - [(set (match_operand:TI 0 "spu_reg_operand" "=r") - (zero_extend:TI (match_operand:SI 1 "spu_reg_operand" "r")))] - "" - "rotqmbyi\t%0,%1,-12" - [(set_attr "type" "shuf")]) - -(define_insn "zero_extendditi2" - [(set (match_operand:TI 0 "spu_reg_operand" "=r") - (zero_extend:TI (match_operand:DI 1 "spu_reg_operand" "r")))] - "" - "rotqmbyi\t%0,%1,-8" - [(set_attr "type" "shuf")]) - - -;; trunc - -(define_insn "truncdiqi2" - [(set (match_operand:QI 0 "spu_reg_operand" "=r") - (truncate:QI (match_operand:DI 1 "spu_reg_operand" "r")))] - "" - "shlqbyi\t%0,%1,4" - [(set_attr "type" "shuf")]) - -(define_insn "truncdihi2" - [(set (match_operand:HI 0 "spu_reg_operand" "=r") - (truncate:HI (match_operand:DI 1 "spu_reg_operand" "r")))] - "" - "shlqbyi\t%0,%1,4" - [(set_attr "type" "shuf")]) - -(define_insn "truncdisi2" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (truncate:SI (match_operand:DI 1 "spu_reg_operand" "r")))] - "" - "shlqbyi\t%0,%1,4" - [(set_attr "type" "shuf")]) - -(define_insn "trunctiqi2" - [(set (match_operand:QI 0 "spu_reg_operand" "=r") - (truncate:QI (match_operand:TI 1 "spu_reg_operand" "r")))] - "" - "shlqbyi\t%0,%1,12" - [(set_attr "type" "shuf")]) - -(define_insn "trunctihi2" - [(set (match_operand:HI 0 "spu_reg_operand" "=r") - (truncate:HI (match_operand:TI 1 "spu_reg_operand" "r")))] - "" - "shlqbyi\t%0,%1,12" - [(set_attr "type" "shuf")]) - -(define_insn "trunctisi2" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (truncate:SI (match_operand:TI 1 "spu_reg_operand" "r")))] - "" - "shlqbyi\t%0,%1,12" - [(set_attr "type" "shuf")]) - -(define_insn "trunctidi2" - [(set (match_operand:DI 0 "spu_reg_operand" "=r") - (truncate:DI (match_operand:TI 1 "spu_reg_operand" "r")))] - "" - "shlqbyi\t%0,%1,8" - [(set_attr "type" "shuf")]) - - -;; float conversions - -(define_insn "float2" - [(set (match_operand: 0 "spu_reg_operand" "=r") - (float: (match_operand:VSI 1 "spu_reg_operand" "r")))] - "" - "csflt\t%0,%1,0" - [(set_attr "type" "fp7")]) - -(define_insn "fix_trunc2" - [(set (match_operand: 0 "spu_reg_operand" "=r") - (fix: (match_operand:VSF 1 "spu_reg_operand" "r")))] - "" - "cflts\t%0,%1,0" - [(set_attr "type" "fp7")]) - -(define_insn "floatuns2" - [(set (match_operand: 0 "spu_reg_operand" "=r") - (unsigned_float: (match_operand:VSI 1 "spu_reg_operand" "r")))] - "" - "cuflt\t%0,%1,0" - [(set_attr "type" "fp7")]) - -(define_insn "fixuns_trunc2" - [(set (match_operand: 0 "spu_reg_operand" "=r") - (unsigned_fix: (match_operand:VSF 1 "spu_reg_operand" "r")))] - "" - "cfltu\t%0,%1,0" - [(set_attr "type" "fp7")]) - -(define_insn "float2_mul" - [(set (match_operand: 0 "spu_reg_operand" "=r") - (mult: (float: (match_operand:VSI 1 "spu_reg_operand" "r")) - (match_operand: 2 "spu_inv_exp2_operand" "w")))] - "" - "csflt\t%0,%1,%w2" - [(set_attr "type" "fp7")]) - -(define_insn "float2_div" - [(set (match_operand: 0 "spu_reg_operand" "=r") - (div: (float: (match_operand:VSI 1 "spu_reg_operand" "r")) - (match_operand: 2 "spu_exp2_operand" "v")))] - "" - "csflt\t%0,%1,%v2" - [(set_attr "type" "fp7")]) - - -(define_insn "fix_trunc2_mul" - [(set (match_operand: 0 "spu_reg_operand" "=r") - (fix: (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r") - (match_operand:VSF 2 "spu_exp2_operand" "v"))))] - "" - "cflts\t%0,%1,%v2" - [(set_attr "type" "fp7")]) - -(define_insn "floatuns2_mul" - [(set (match_operand: 0 "spu_reg_operand" "=r") - (mult: (unsigned_float: (match_operand:VSI 1 "spu_reg_operand" "r")) - (match_operand: 2 "spu_inv_exp2_operand" "w")))] - "" - "cuflt\t%0,%1,%w2" - [(set_attr "type" "fp7")]) - -(define_insn "floatuns2_div" - [(set (match_operand: 0 "spu_reg_operand" "=r") - (div: (unsigned_float: (match_operand:VSI 1 "spu_reg_operand" "r")) - (match_operand: 2 "spu_exp2_operand" "v")))] - "" - "cuflt\t%0,%1,%v2" - [(set_attr "type" "fp7")]) - -(define_insn "fixuns_trunc2_mul" - [(set (match_operand: 0 "spu_reg_operand" "=r") - (unsigned_fix: (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r") - (match_operand:VSF 2 "spu_exp2_operand" "v"))))] - "" - "cfltu\t%0,%1,%v2" - [(set_attr "type" "fp7")]) - -(define_insn "extendsfdf2" - [(set (match_operand:DF 0 "spu_reg_operand" "=r") - (unspec:DF [(match_operand:SF 1 "spu_reg_operand" "r")] - UNSPEC_FLOAT_EXTEND))] - "" - "fesd\t%0,%1" - [(set_attr "type" "fpd")]) - -(define_insn "truncdfsf2" - [(set (match_operand:SF 0 "spu_reg_operand" "=r") - (unspec:SF [(match_operand:DF 1 "spu_reg_operand" "r")] - UNSPEC_FLOAT_TRUNCATE))] - "" - "frds\t%0,%1" - [(set_attr "type" "fpd")]) - -(define_expand "floatdisf2" - [(set (match_operand:SF 0 "register_operand" "") - (float:SF (match_operand:DI 1 "register_operand" "")))] - "" - { - rtx c0 = gen_reg_rtx (SImode); - rtx r0 = gen_reg_rtx (DImode); - rtx r1 = gen_reg_rtx (SFmode); - rtx r2 = gen_reg_rtx (SImode); - rtx setneg = gen_reg_rtx (SImode); - rtx isneg = gen_reg_rtx (SImode); - rtx neg = gen_reg_rtx (DImode); - rtx mask = gen_reg_rtx (DImode); - - emit_move_insn (c0, GEN_INT (-0x80000000ll)); - - emit_insn (gen_negdi2 (neg, operands[1])); - emit_insn (gen_cgt_di_m1 (isneg, operands[1])); - emit_insn (gen_extend_compare (mask, isneg)); - emit_insn (gen_selb (r0, neg, operands[1], mask)); - emit_insn (gen_andc_si (setneg, c0, isneg)); - - emit_insn (gen_floatunsdisf2 (r1, r0)); - - emit_insn (gen_iorsi3 (r2, gen_rtx_SUBREG (SImode, r1, 0), setneg)); - emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, r2, 0)); - DONE; - }) - -(define_insn_and_split "floatunsdisf2" - [(set (match_operand:SF 0 "register_operand" "=r") - (unsigned_float:SF (match_operand:DI 1 "register_operand" "r"))) - (clobber (match_scratch:SF 2 "=r")) - (clobber (match_scratch:SF 3 "=r")) - (clobber (match_scratch:SF 4 "=r"))] - "" - "#" - "reload_completed" - [(set (match_dup:SF 0) - (unsigned_float:SF (match_dup:DI 1)))] - { - rtx op1_v4si = gen_rtx_REG (V4SImode, REGNO (operands[1])); - rtx op2_v4sf = gen_rtx_REG (V4SFmode, REGNO (operands[2])); - rtx op2_ti = gen_rtx_REG (TImode, REGNO (operands[2])); - rtx op3_ti = gen_rtx_REG (TImode, REGNO (operands[3])); - - REAL_VALUE_TYPE scale; - real_2expN (&scale, 32, SFmode); - - emit_insn (gen_floatunsv4siv4sf2 (op2_v4sf, op1_v4si)); - emit_insn (gen_shlqby_ti (op3_ti, op2_ti, GEN_INT (4))); - - emit_move_insn (operands[4], - const_double_from_real_value (scale, SFmode)); - emit_insn (gen_fmasf4 (operands[0], - operands[2], operands[4], operands[3])); - DONE; - }) - -(define_expand "floattisf2" - [(set (match_operand:SF 0 "register_operand" "") - (float:SF (match_operand:TI 1 "register_operand" "")))] - "" - { - rtx c0 = gen_reg_rtx (SImode); - rtx r0 = gen_reg_rtx (TImode); - rtx r1 = gen_reg_rtx (SFmode); - rtx r2 = gen_reg_rtx (SImode); - rtx setneg = gen_reg_rtx (SImode); - rtx isneg = gen_reg_rtx (SImode); - rtx neg = gen_reg_rtx (TImode); - rtx mask = gen_reg_rtx (TImode); - - emit_move_insn (c0, GEN_INT (-0x80000000ll)); - - emit_insn (gen_negti2 (neg, operands[1])); - emit_insn (gen_cgt_ti_m1 (isneg, operands[1])); - emit_insn (gen_extend_compare (mask, isneg)); - emit_insn (gen_selb (r0, neg, operands[1], mask)); - emit_insn (gen_andc_si (setneg, c0, isneg)); - - emit_insn (gen_floatunstisf2 (r1, r0)); - - emit_insn (gen_iorsi3 (r2, gen_rtx_SUBREG (SImode, r1, 0), setneg)); - emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, r2, 0)); - DONE; - }) - -(define_insn_and_split "floatunstisf2" - [(set (match_operand:SF 0 "register_operand" "=r") - (unsigned_float:SF (match_operand:TI 1 "register_operand" "r"))) - (clobber (match_scratch:SF 2 "=r")) - (clobber (match_scratch:SF 3 "=r")) - (clobber (match_scratch:SF 4 "=r"))] - "" - "#" - "reload_completed" - [(set (match_dup:SF 0) - (unsigned_float:SF (match_dup:TI 1)))] - { - rtx op1_v4si = gen_rtx_REG (V4SImode, REGNO (operands[1])); - rtx op2_v4sf = gen_rtx_REG (V4SFmode, REGNO (operands[2])); - rtx op2_ti = gen_rtx_REG (TImode, REGNO (operands[2])); - rtx op3_ti = gen_rtx_REG (TImode, REGNO (operands[3])); - - REAL_VALUE_TYPE scale; - real_2expN (&scale, 32, SFmode); - - emit_insn (gen_floatunsv4siv4sf2 (op2_v4sf, op1_v4si)); - emit_insn (gen_shlqby_ti (op3_ti, op2_ti, GEN_INT (4))); - - emit_move_insn (operands[4], - const_double_from_real_value (scale, SFmode)); - emit_insn (gen_fmasf4 (operands[2], - operands[2], operands[4], operands[3])); - - emit_insn (gen_shlqby_ti (op3_ti, op3_ti, GEN_INT (4))); - emit_insn (gen_fmasf4 (operands[2], - operands[2], operands[4], operands[3])); - - emit_insn (gen_shlqby_ti (op3_ti, op3_ti, GEN_INT (4))); - emit_insn (gen_fmasf4 (operands[0], - operands[2], operands[4], operands[3])); - DONE; - }) - -;; Do (double)(operands[1]+0x80000000u)-(double)0x80000000 -(define_expand "floatsidf2" - [(set (match_operand:DF 0 "register_operand" "") - (float:DF (match_operand:SI 1 "register_operand" "")))] - "" - { - rtx c0 = gen_reg_rtx (SImode); - rtx c1 = gen_reg_rtx (DFmode); - rtx r0 = gen_reg_rtx (SImode); - rtx r1 = gen_reg_rtx (DFmode); - - emit_move_insn (c0, GEN_INT (-0x80000000ll)); - emit_move_insn (c1, spu_float_const ("2147483648", DFmode)); - emit_insn (gen_xorsi3 (r0, operands[1], c0)); - emit_insn (gen_floatunssidf2 (r1, r0)); - emit_insn (gen_subdf3 (operands[0], r1, c1)); - DONE; - }) - -(define_expand "floatunssidf2" - [(set (match_operand:DF 0 "register_operand" "=r") - (unsigned_float:DF (match_operand:SI 1 "register_operand" "r")))] - "" - "{ - rtx value; - rtx c0 = spu_const_from_ints (V16QImode, 0x02031011, 0x12138080, - 0x06071415, 0x16178080); - rtx r0 = gen_reg_rtx (V16QImode); - - if (optimize_size) - { - start_sequence (); - value = - emit_library_call_value (convert_optab_libfunc (ufloat_optab, - DFmode, SImode), - NULL_RTX, LCT_NORMAL, DFmode, - operands[1], SImode); - rtx_insn *insns = get_insns (); - end_sequence (); - emit_libcall_block (insns, operands[0], value, - gen_rtx_UNSIGNED_FLOAT (DFmode, operands[1])); - } - else - { - emit_move_insn (r0, c0); - emit_insn (gen_floatunssidf2_internal (operands[0], operands[1], r0)); - } - DONE; - }") - -(define_insn_and_split "floatunssidf2_internal" - [(set (match_operand:DF 0 "register_operand" "=r") - (unsigned_float:DF (match_operand:SI 1 "register_operand" "r"))) - (use (match_operand:V16QI 2 "register_operand" "r")) - (clobber (match_scratch:V4SI 3 "=&r")) - (clobber (match_scratch:V4SI 4 "=&r")) - (clobber (match_scratch:V4SI 5 "=&r")) - (clobber (match_scratch:V4SI 6 "=&r"))] - "" - "clz\t%3,%1\;il\t%6,1023+31\;shl\t%4,%1,%3\;ceqi\t%5,%3,32\;sf\t%6,%3,%6\;a\t%4,%4,%4\;andc\t%6,%6,%5\;shufb\t%6,%6,%4,%2\;shlqbii\t%0,%6,4" - "reload_completed" - [(set (match_dup:DF 0) - (unsigned_float:DF (match_dup:SI 1)))] - "{ - rtx *ops = operands; - rtx op1_v4si = gen_rtx_REG(V4SImode, REGNO(ops[1])); - rtx op0_ti = gen_rtx_REG (TImode, REGNO (ops[0])); - rtx op2_ti = gen_rtx_REG (TImode, REGNO (ops[2])); - rtx op6_ti = gen_rtx_REG (TImode, REGNO (ops[6])); - emit_insn (gen_clzv4si2 (ops[3],op1_v4si)); - emit_move_insn (ops[6], spu_const (V4SImode, 1023+31)); - emit_insn (gen_vashlv4si3 (ops[4],op1_v4si,ops[3])); - emit_insn (gen_ceq_v4si (ops[5],ops[3],spu_const (V4SImode, 32))); - emit_insn (gen_subv4si3 (ops[6],ops[6],ops[3])); - emit_insn (gen_addv4si3 (ops[4],ops[4],ops[4])); - emit_insn (gen_andc_v4si (ops[6],ops[6],ops[5])); - emit_insn (gen_shufb (ops[6],ops[6],ops[4],op2_ti)); - emit_insn (gen_shlqbi_ti (op0_ti,op6_ti,GEN_INT(4))); - DONE; - }" - [(set_attr "length" "32")]) - -(define_expand "floatdidf2" - [(set (match_operand:DF 0 "register_operand" "") - (float:DF (match_operand:DI 1 "register_operand" "")))] - "" - { - rtx c0 = gen_reg_rtx (DImode); - rtx r0 = gen_reg_rtx (DImode); - rtx r1 = gen_reg_rtx (DFmode); - rtx r2 = gen_reg_rtx (DImode); - rtx setneg = gen_reg_rtx (DImode); - rtx isneg = gen_reg_rtx (SImode); - rtx neg = gen_reg_rtx (DImode); - rtx mask = gen_reg_rtx (DImode); - - emit_move_insn (c0, GEN_INT (0x8000000000000000ull)); - - emit_insn (gen_negdi2 (neg, operands[1])); - emit_insn (gen_cgt_di_m1 (isneg, operands[1])); - emit_insn (gen_extend_compare (mask, isneg)); - emit_insn (gen_selb (r0, neg, operands[1], mask)); - emit_insn (gen_andc_di (setneg, c0, mask)); - - emit_insn (gen_floatunsdidf2 (r1, r0)); - - emit_insn (gen_iordi3 (r2, gen_rtx_SUBREG (DImode, r1, 0), setneg)); - emit_move_insn (operands[0], gen_rtx_SUBREG (DFmode, r2, 0)); - DONE; - }) - -(define_expand "floatunsdidf2" - [(set (match_operand:DF 0 "register_operand" "=r") - (unsigned_float:DF (match_operand:DI 1 "register_operand" "r")))] - "" - "{ - rtx value; - rtx c0 = spu_const_from_ints (V16QImode, 0x02031011, 0x12138080, - 0x06071415, 0x16178080); - rtx c1 = spu_const_from_ints (V4SImode, 1023+63, 1023+31, 0, 0); - rtx r0 = gen_reg_rtx (V16QImode); - rtx r1 = gen_reg_rtx (V4SImode); - - if (optimize_size) - { - start_sequence (); - value = - emit_library_call_value (convert_optab_libfunc (ufloat_optab, - DFmode, DImode), - NULL_RTX, LCT_NORMAL, DFmode, - operands[1], DImode); - rtx_insn *insns = get_insns (); - end_sequence (); - emit_libcall_block (insns, operands[0], value, - gen_rtx_UNSIGNED_FLOAT (DFmode, operands[1])); - } - else - { - emit_move_insn (r1, c1); - emit_move_insn (r0, c0); - emit_insn (gen_floatunsdidf2_internal (operands[0], operands[1], r0, r1)); - } - DONE; - }") - -(define_insn_and_split "floatunsdidf2_internal" - [(set (match_operand:DF 0 "register_operand" "=r") - (unsigned_float:DF (match_operand:DI 1 "register_operand" "r"))) - (use (match_operand:V16QI 2 "register_operand" "r")) - (use (match_operand:V4SI 3 "register_operand" "r")) - (clobber (match_scratch:V4SI 4 "=&r")) - (clobber (match_scratch:V4SI 5 "=&r")) - (clobber (match_scratch:V4SI 6 "=&r"))] - "" - "clz\t%4,%1\;shl\t%5,%1,%4\;ceqi\t%6,%4,32\;sf\t%4,%4,%3\;a\t%5,%5,%5\;andc\t%4,%4,%6\;shufb\t%4,%4,%5,%2\;shlqbii\t%4,%4,4\;shlqbyi\t%5,%4,8\;dfa\t%0,%4,%5" - "reload_completed" - [(set (match_operand:DF 0 "register_operand" "=r") - (unsigned_float:DF (match_operand:DI 1 "register_operand" "r")))] - "{ - rtx *ops = operands; - rtx op1_v4si = gen_rtx_REG (V4SImode, REGNO(ops[1])); - rtx op2_ti = gen_rtx_REG (TImode, REGNO(ops[2])); - rtx op4_ti = gen_rtx_REG (TImode, REGNO(ops[4])); - rtx op5_ti = gen_rtx_REG (TImode, REGNO(ops[5])); - rtx op4_df = gen_rtx_REG (DFmode, REGNO(ops[4])); - rtx op5_df = gen_rtx_REG (DFmode, REGNO(ops[5])); - emit_insn (gen_clzv4si2 (ops[4],op1_v4si)); - emit_insn (gen_vashlv4si3 (ops[5],op1_v4si,ops[4])); - emit_insn (gen_ceq_v4si (ops[6],ops[4],spu_const (V4SImode, 32))); - emit_insn (gen_subv4si3 (ops[4],ops[3],ops[4])); - emit_insn (gen_addv4si3 (ops[5],ops[5],ops[5])); - emit_insn (gen_andc_v4si (ops[4],ops[4],ops[6])); - emit_insn (gen_shufb (ops[4],ops[4],ops[5],op2_ti)); - emit_insn (gen_shlqbi_ti (op4_ti,op4_ti,GEN_INT(4))); - emit_insn (gen_shlqby_ti (op5_ti,op4_ti,GEN_INT(8))); - emit_insn (gen_adddf3 (ops[0],op4_df,op5_df)); - DONE; - }" - [(set_attr "length" "40")]) - - -;; add - -(define_expand "addv16qi3" - [(set (match_operand:V16QI 0 "spu_reg_operand" "=r") - (plus:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r") - (match_operand:V16QI 2 "spu_reg_operand" "r")))] - "" - "{ - rtx res_short = simplify_gen_subreg (V8HImode, operands[0], V16QImode, 0); - rtx lhs_short = simplify_gen_subreg (V8HImode, operands[1], V16QImode, 0); - rtx rhs_short = simplify_gen_subreg (V8HImode, operands[2], V16QImode, 0); - rtx rhs_and = gen_reg_rtx (V8HImode); - rtx hi_char = gen_reg_rtx (V8HImode); - rtx lo_char = gen_reg_rtx (V8HImode); - rtx mask = gen_reg_rtx (V8HImode); - - emit_move_insn (mask, spu_const (V8HImode, 0x00ff)); - emit_insn (gen_andv8hi3 (rhs_and, rhs_short, spu_const (V8HImode, 0xff00))); - emit_insn (gen_addv8hi3 (hi_char, lhs_short, rhs_and)); - emit_insn (gen_addv8hi3 (lo_char, lhs_short, rhs_short)); - emit_insn (gen_selb (res_short, hi_char, lo_char, mask)); - DONE; - }") - -(define_insn "add3" - [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r") - (plus:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r") - (match_operand:VHSI 2 "spu_arith_operand" "r,B")))] - "" - "@ - a\t%0,%1,%2 - ai\t%0,%1,%2") - -(define_expand "add3" - [(set (match_dup:VDI 3) - (unspec:VDI [(match_operand:VDI 1 "spu_reg_operand" "") - (match_operand:VDI 2 "spu_reg_operand" "")] UNSPEC_CG)) - (set (match_dup:VDI 5) - (unspec:VDI [(match_dup 3) - (match_dup 3) - (match_dup:TI 4)] UNSPEC_SHUFB)) - (set (match_operand:VDI 0 "spu_reg_operand" "") - (unspec:VDI [(match_dup 1) - (match_dup 2) - (match_dup 5)] UNSPEC_ADDX))] - "" - { - unsigned char pat[16] = { - 0x04, 0x05, 0x06, 0x07, - 0x80, 0x80, 0x80, 0x80, - 0x0c, 0x0d, 0x0e, 0x0f, - 0x80, 0x80, 0x80, 0x80 - }; - operands[3] = gen_reg_rtx (mode); - operands[4] = gen_reg_rtx (TImode); - operands[5] = gen_reg_rtx (mode); - emit_move_insn (operands[4], array_to_constant (TImode, pat)); - }) - -(define_insn "cg_" - [(set (match_operand:CBOP 0 "spu_reg_operand" "=r") - (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r") - (match_operand 2 "spu_reg_operand" "r")] UNSPEC_CG))] - "operands != NULL" - "cg\t%0,%1,%2") - -(define_insn "cgx_" - [(set (match_operand:CBOP 0 "spu_reg_operand" "=r") - (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r") - (match_operand 2 "spu_reg_operand" "r") - (match_operand 3 "spu_reg_operand" "0")] UNSPEC_CGX))] - "operands != NULL" - "cgx\t%0,%1,%2") - -(define_insn "addx_" - [(set (match_operand:CBOP 0 "spu_reg_operand" "=r") - (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r") - (match_operand 2 "spu_reg_operand" "r") - (match_operand 3 "spu_reg_operand" "0")] UNSPEC_ADDX))] - "operands != NULL" - "addx\t%0,%1,%2") - - -;; This is not the most efficient implementation of addti3. -;; We include this here because 1) the compiler needs it to be -;; defined as the word size is 128-bit and 2) sometimes gcc -;; substitutes an add for a constant left-shift. 2) is unlikely -;; because we also give addti3 a high cost. In case gcc does -;; generate TImode add, here is the code to do it. -;; operand 2 is a nonmemory because the compiler requires it. -(define_insn "addti3" - [(set (match_operand:TI 0 "spu_reg_operand" "=&r") - (plus:TI (match_operand:TI 1 "spu_reg_operand" "r") - (match_operand:TI 2 "spu_nonmem_operand" "r"))) - (clobber (match_scratch:TI 3 "=&r"))] - "" - "cg\t%3,%1,%2\n\\ - shlqbyi\t%3,%3,4\n\\ - cgx\t%3,%1,%2\n\\ - shlqbyi\t%3,%3,4\n\\ - cgx\t%3,%1,%2\n\\ - shlqbyi\t%0,%3,4\n\\ - addx\t%0,%1,%2" - [(set_attr "type" "multi0") - (set_attr "length" "28")]) - -(define_insn "add3" - [(set (match_operand:VSF 0 "spu_reg_operand" "=r") - (plus:VSF (match_operand:VSF 1 "spu_reg_operand" "r") - (match_operand:VSF 2 "spu_reg_operand" "r")))] - "" - "fa\t%0,%1,%2" - [(set_attr "type" "fp6")]) - -(define_insn "add3" - [(set (match_operand:VDF 0 "spu_reg_operand" "=r") - (plus:VDF (match_operand:VDF 1 "spu_reg_operand" "r") - (match_operand:VDF 2 "spu_reg_operand" "r")))] - "" - "dfa\t%0,%1,%2" - [(set_attr "type" "fpd")]) - - -;; sub - -(define_expand "subv16qi3" - [(set (match_operand:V16QI 0 "spu_reg_operand" "=r") - (minus:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r") - (match_operand:V16QI 2 "spu_reg_operand" "r")))] - "" - "{ - rtx res_short = simplify_gen_subreg (V8HImode, operands[0], V16QImode, 0); - rtx lhs_short = simplify_gen_subreg (V8HImode, operands[1], V16QImode, 0); - rtx rhs_short = simplify_gen_subreg (V8HImode, operands[2], V16QImode, 0); - rtx rhs_and = gen_reg_rtx (V8HImode); - rtx hi_char = gen_reg_rtx (V8HImode); - rtx lo_char = gen_reg_rtx (V8HImode); - rtx mask = gen_reg_rtx (V8HImode); - - emit_move_insn (mask, spu_const (V8HImode, 0x00ff)); - emit_insn (gen_andv8hi3 (rhs_and, rhs_short, spu_const (V8HImode, 0xff00))); - emit_insn (gen_subv8hi3 (hi_char, lhs_short, rhs_and)); - emit_insn (gen_subv8hi3 (lo_char, lhs_short, rhs_short)); - emit_insn (gen_selb (res_short, hi_char, lo_char, mask)); - DONE; - }") - -(define_insn "sub3" - [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r") - (minus:VHSI (match_operand:VHSI 1 "spu_arith_operand" "r,B") - (match_operand:VHSI 2 "spu_reg_operand" "r,r")))] - "" - "@ - sf\t%0,%2,%1 - sfi\t%0,%2,%1") - -(define_expand "sub3" - [(set (match_dup:VDI 3) - (unspec:VDI [(match_operand:VDI 1 "spu_reg_operand" "") - (match_operand:VDI 2 "spu_reg_operand" "")] UNSPEC_BG)) - (set (match_dup:VDI 5) - (unspec:VDI [(match_dup 3) - (match_dup 3) - (match_dup:TI 4)] UNSPEC_SHUFB)) - (set (match_operand:VDI 0 "spu_reg_operand" "") - (unspec:VDI [(match_dup 1) - (match_dup 2) - (match_dup 5)] UNSPEC_SFX))] - "" - { - unsigned char pat[16] = { - 0x04, 0x05, 0x06, 0x07, - 0xc0, 0xc0, 0xc0, 0xc0, - 0x0c, 0x0d, 0x0e, 0x0f, - 0xc0, 0xc0, 0xc0, 0xc0 - }; - operands[3] = gen_reg_rtx (mode); - operands[4] = gen_reg_rtx (TImode); - operands[5] = gen_reg_rtx (mode); - emit_move_insn (operands[4], array_to_constant (TImode, pat)); - }) - -(define_insn "bg_" - [(set (match_operand:CBOP 0 "spu_reg_operand" "=r") - (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r") - (match_operand 2 "spu_reg_operand" "r")] UNSPEC_BG))] - "operands != NULL" - "bg\t%0,%2,%1") - -(define_insn "bgx_" - [(set (match_operand:CBOP 0 "spu_reg_operand" "=r") - (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r") - (match_operand 2 "spu_reg_operand" "r") - (match_operand 3 "spu_reg_operand" "0")] UNSPEC_BGX))] - "operands != NULL" - "bgx\t%0,%2,%1") - -(define_insn "sfx_" - [(set (match_operand:CBOP 0 "spu_reg_operand" "=r") - (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r") - (match_operand 2 "spu_reg_operand" "r") - (match_operand 3 "spu_reg_operand" "0")] UNSPEC_SFX))] - "operands != NULL" - "sfx\t%0,%2,%1") - -(define_insn "subti3" - [(set (match_operand:TI 0 "spu_reg_operand" "=r") - (minus:TI (match_operand:TI 1 "spu_reg_operand" "r") - (match_operand:TI 2 "spu_reg_operand" "r"))) - (clobber (match_scratch:TI 3 "=&r")) - (clobber (match_scratch:TI 4 "=&r")) - (clobber (match_scratch:TI 5 "=&r")) - (clobber (match_scratch:TI 6 "=&r"))] - "" - "il\t%6,1\n\\ - bg\t%3,%2,%1\n\\ - xor\t%3,%3,%6\n\\ - sf\t%4,%2,%1\n\\ - shlqbyi\t%5,%3,4\n\\ - bg\t%3,%5,%4\n\\ - xor\t%3,%3,%6\n\\ - sf\t%4,%5,%4\n\\ - shlqbyi\t%5,%3,4\n\\ - bg\t%3,%5,%4\n\\ - xor\t%3,%3,%6\n\\ - sf\t%4,%5,%4\n\\ - shlqbyi\t%5,%3,4\n\\ - sf\t%0,%5,%4" - [(set_attr "type" "multi0") - (set_attr "length" "56")]) - -(define_insn "sub3" - [(set (match_operand:VSF 0 "spu_reg_operand" "=r") - (minus:VSF (match_operand:VSF 1 "spu_reg_operand" "r") - (match_operand:VSF 2 "spu_reg_operand" "r")))] - "" - "fs\t%0,%1,%2" - [(set_attr "type" "fp6")]) - -(define_insn "sub3" - [(set (match_operand:VDF 0 "spu_reg_operand" "=r") - (minus:VDF (match_operand:VDF 1 "spu_reg_operand" "r") - (match_operand:VDF 2 "spu_reg_operand" "r")))] - "" - "dfs\t%0,%1,%2" - [(set_attr "type" "fpd")]) - - -;; neg - -(define_expand "negv16qi2" - [(set (match_operand:V16QI 0 "spu_reg_operand" "=r") - (neg:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")))] - "" - "{ - rtx zero = gen_reg_rtx (V16QImode); - emit_move_insn (zero, CONST0_RTX (V16QImode)); - emit_insn (gen_subv16qi3 (operands[0], zero, operands[1])); - DONE; - }") - -(define_insn "neg2" - [(set (match_operand:VHSI 0 "spu_reg_operand" "=r") - (neg:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")))] - "" - "sfi\t%0,%1,0") - -(define_expand "negdi2" - [(set (match_operand:DI 0 "spu_reg_operand" "") - (neg:DI (match_operand:DI 1 "spu_reg_operand" "")))] - "" - { - rtx zero = gen_reg_rtx(DImode); - emit_move_insn(zero, GEN_INT(0)); - emit_insn (gen_subdi3(operands[0], zero, operands[1])); - DONE; - }) - -(define_expand "negti2" - [(set (match_operand:TI 0 "spu_reg_operand" "") - (neg:TI (match_operand:TI 1 "spu_reg_operand" "")))] - "" - { - rtx zero = gen_reg_rtx(TImode); - emit_move_insn(zero, GEN_INT(0)); - emit_insn (gen_subti3(operands[0], zero, operands[1])); - DONE; - }) - -(define_expand "neg2" - [(parallel - [(set (match_operand:VSF 0 "spu_reg_operand" "") - (neg:VSF (match_operand:VSF 1 "spu_reg_operand" ""))) - (use (match_dup 2))])] - "" - "operands[2] = gen_reg_rtx (mode); - emit_move_insn (operands[2], spu_const (mode, -0x80000000ull));") - -(define_expand "neg2" - [(parallel - [(set (match_operand:VDF 0 "spu_reg_operand" "") - (neg:VDF (match_operand:VDF 1 "spu_reg_operand" ""))) - (use (match_dup 2))])] - "" - "operands[2] = gen_reg_rtx (mode); - emit_move_insn (operands[2], spu_const (mode, -0x8000000000000000ull));") - -(define_insn_and_split "_neg2" - [(set (match_operand:VSDF 0 "spu_reg_operand" "=r") - (neg:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r"))) - (use (match_operand: 2 "spu_reg_operand" "r"))] - "" - "#" - "" - [(set (match_dup: 3) - (xor: (match_dup: 4) - (match_dup: 2)))] - { - operands[3] = spu_gen_subreg (mode, operands[0]); - operands[4] = spu_gen_subreg (mode, operands[1]); - }) - - -;; abs - -(define_expand "abs2" - [(parallel - [(set (match_operand:VSF 0 "spu_reg_operand" "") - (abs:VSF (match_operand:VSF 1 "spu_reg_operand" ""))) - (use (match_dup 2))])] - "" - "operands[2] = gen_reg_rtx (mode); - emit_move_insn (operands[2], spu_const (mode, 0x7fffffffull));") - -(define_expand "abs2" - [(parallel - [(set (match_operand:VDF 0 "spu_reg_operand" "") - (abs:VDF (match_operand:VDF 1 "spu_reg_operand" ""))) - (use (match_dup 2))])] - "" - "operands[2] = gen_reg_rtx (mode); - emit_move_insn (operands[2], spu_const (mode, 0x7fffffffffffffffull));") - -(define_insn_and_split "_abs2" - [(set (match_operand:VSDF 0 "spu_reg_operand" "=r") - (abs:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r"))) - (use (match_operand: 2 "spu_reg_operand" "r"))] - "" - "#" - "" - [(set (match_dup: 3) - (and: (match_dup: 4) - (match_dup: 2)))] - { - operands[3] = spu_gen_subreg (mode, operands[0]); - operands[4] = spu_gen_subreg (mode, operands[1]); - }) - - -;; mul - -(define_insn "mulhi3" - [(set (match_operand:HI 0 "spu_reg_operand" "=r,r") - (mult:HI (match_operand:HI 1 "spu_reg_operand" "r,r") - (match_operand:HI 2 "spu_arith_operand" "r,B")))] - "" - "@ - mpy\t%0,%1,%2 - mpyi\t%0,%1,%2" - [(set_attr "type" "fp7")]) - -(define_expand "mulv8hi3" - [(set (match_operand:V8HI 0 "spu_reg_operand" "") - (mult:V8HI (match_operand:V8HI 1 "spu_reg_operand" "") - (match_operand:V8HI 2 "spu_reg_operand" "")))] - "" - "{ - rtx result = simplify_gen_subreg (V4SImode, operands[0], V8HImode, 0); - rtx low = gen_reg_rtx (V4SImode); - rtx high = gen_reg_rtx (V4SImode); - rtx shift = gen_reg_rtx (V4SImode); - rtx mask = gen_reg_rtx (V4SImode); - - emit_move_insn (mask, spu_const (V4SImode, 0x0000ffff)); - emit_insn (gen_vec_widen_smult_even_v8hi (high, operands[1], operands[2])); - emit_insn (gen_vec_widen_smult_odd_v8hi (low, operands[1], operands[2])); - emit_insn (gen_vashlv4si3 (shift, high, spu_const(V4SImode, 16))); - emit_insn (gen_selb (result, shift, low, mask)); - DONE; - }") - -(define_expand "mul3" - [(parallel - [(set (match_operand:VSI 0 "spu_reg_operand" "") - (mult:VSI (match_operand:VSI 1 "spu_reg_operand" "") - (match_operand:VSI 2 "spu_reg_operand" ""))) - (clobber (match_dup:VSI 3)) - (clobber (match_dup:VSI 4)) - (clobber (match_dup:VSI 5)) - (clobber (match_dup:VSI 6))])] - "" - { - operands[3] = gen_reg_rtx(mode); - operands[4] = gen_reg_rtx(mode); - operands[5] = gen_reg_rtx(mode); - operands[6] = gen_reg_rtx(mode); - }) - -(define_insn_and_split "_mulsi3" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (mult:SI (match_operand:SI 1 "spu_reg_operand" "r") - (match_operand:SI 2 "spu_arith_operand" "rK"))) - (clobber (match_operand:SI 3 "spu_reg_operand" "=&r")) - (clobber (match_operand:SI 4 "spu_reg_operand" "=&r")) - (clobber (match_operand:SI 5 "spu_reg_operand" "=&r")) - (clobber (match_operand:SI 6 "spu_reg_operand" "=&r"))] - "" - "#" - "" - [(set (match_dup:SI 0) - (mult:SI (match_dup:SI 1) - (match_dup:SI 2)))] - { - HOST_WIDE_INT val = 0; - rtx a = operands[3]; - rtx b = operands[4]; - rtx c = operands[5]; - rtx d = operands[6]; - if (GET_CODE(operands[2]) == CONST_INT) - { - val = INTVAL(operands[2]); - emit_move_insn(d, operands[2]); - operands[2] = d; - } - if (val && (val & 0xffff) == 0) - { - emit_insn (gen_mpyh_si(operands[0], operands[2], operands[1])); - } - else if (val > 0 && val < 0x10000) - { - rtx cst = satisfies_constraint_K (GEN_INT (val)) ? GEN_INT(val) : d; - emit_insn (gen_mpyh_si(a, operands[1], operands[2])); - emit_insn (gen_mpyu_si(c, operands[1], cst)); - emit_insn (gen_addsi3(operands[0], a, c)); - } - else - { - emit_insn (gen_mpyh_si(a, operands[1], operands[2])); - emit_insn (gen_mpyh_si(b, operands[2], operands[1])); - emit_insn (gen_mpyu_si(c, operands[1], operands[2])); - emit_insn (gen_addsi3(d, a, b)); - emit_insn (gen_addsi3(operands[0], d, c)); - } - DONE; - }) - -(define_insn_and_split "_mulv4si3" - [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") - (mult:V4SI (match_operand:V4SI 1 "spu_reg_operand" "r") - (match_operand:V4SI 2 "spu_reg_operand" "r"))) - (clobber (match_operand:V4SI 3 "spu_reg_operand" "=&r")) - (clobber (match_operand:V4SI 4 "spu_reg_operand" "=&r")) - (clobber (match_operand:V4SI 5 "spu_reg_operand" "=&r")) - (clobber (match_operand:V4SI 6 "spu_reg_operand" "=&r"))] - "" - "#" - "" - [(set (match_dup:V4SI 0) - (mult:V4SI (match_dup:V4SI 1) - (match_dup:V4SI 2)))] - { - rtx a = operands[3]; - rtx b = operands[4]; - rtx c = operands[5]; - rtx d = operands[6]; - rtx op1 = simplify_gen_subreg (V8HImode, operands[1], V4SImode, 0); - rtx op2 = simplify_gen_subreg (V8HImode, operands[2], V4SImode, 0); - emit_insn (gen_spu_mpyh(a, op1, op2)); - emit_insn (gen_spu_mpyh(b, op2, op1)); - emit_insn (gen_vec_widen_umult_odd_v8hi (c, op1, op2)); - emit_insn (gen_addv4si3(d, a, b)); - emit_insn (gen_addv4si3(operands[0], d, c)); - DONE; - }) - -(define_insn "mulhisi3" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")) - (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))))] - "" - "mpy\t%0,%1,%2" - [(set_attr "type" "fp7")]) - -(define_insn "mulhisi3_imm" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")) - (match_operand:SI 2 "imm_K_operand" "K")))] - "" - "mpyi\t%0,%1,%2" - [(set_attr "type" "fp7")]) - -(define_insn "umulhisi3" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (mult:SI (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")) - (zero_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))))] - "" - "mpyu\t%0,%1,%2" - [(set_attr "type" "fp7")]) - -(define_insn "umulhisi3_imm" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (mult:SI (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")) - (and:SI (match_operand:SI 2 "imm_K_operand" "K") (const_int 65535))))] - "" - "mpyui\t%0,%1,%2" - [(set_attr "type" "fp7")]) - -(define_insn "mpyu_si" - [(set (match_operand:SI 0 "spu_reg_operand" "=r,r") - (mult:SI (and:SI (match_operand:SI 1 "spu_reg_operand" "r,r") - (const_int 65535)) - (and:SI (match_operand:SI 2 "spu_arith_operand" "r,K") - (const_int 65535))))] - "" - "@ - mpyu\t%0,%1,%2 - mpyui\t%0,%1,%2" - [(set_attr "type" "fp7")]) - -;; This isn't always profitable to use. Consider r = a * b + c * d. -;; It's faster to do the multiplies in parallel then add them. If we -;; merge a multiply and add it prevents the multiplies from happening in -;; parallel. -(define_insn "mpya_si" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (plus:SI (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")) - (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))) - (match_operand:SI 3 "spu_reg_operand" "r")))] - "0" - "mpya\t%0,%1,%2,%3" - [(set_attr "type" "fp7")]) - -(define_insn "mpyh_si" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (mult:SI (and:SI (match_operand:SI 1 "spu_reg_operand" "r") - (const_int -65536)) - (and:SI (match_operand:SI 2 "spu_reg_operand" "r") - (const_int 65535))))] - "" - "mpyh\t%0,%1,%2" - [(set_attr "type" "fp7")]) - -(define_insn "mpys_si" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (ashiftrt:SI - (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")) - (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))) - (const_int 16)))] - "" - "mpys\t%0,%1,%2" - [(set_attr "type" "fp7")]) - -(define_insn "mpyhh_si" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (mult:SI (ashiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r") - (const_int 16)) - (ashiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r") - (const_int 16))))] - "" - "mpyhh\t%0,%1,%2" - [(set_attr "type" "fp7")]) - -(define_insn "mpyhhu_si" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (mult:SI (lshiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r") - (const_int 16)) - (lshiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r") - (const_int 16))))] - "" - "mpyhhu\t%0,%1,%2" - [(set_attr "type" "fp7")]) - -(define_insn "mpyhha_si" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (plus:SI (mult:SI (ashiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r") - (const_int 16)) - (ashiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r") - (const_int 16))) - (match_operand:SI 3 "spu_reg_operand" "0")))] - "0" - "mpyhha\t%0,%1,%2" - [(set_attr "type" "fp7")]) - -(define_insn "mul3" - [(set (match_operand:VSDF 0 "spu_reg_operand" "=r") - (mult:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r") - (match_operand:VSDF 2 "spu_reg_operand" "r")))] - "" - "fm\t%0,%1,%2" - [(set_attr "type" "fp")]) - -(define_insn "fma4" - [(set (match_operand:VSF 0 "spu_reg_operand" "=r") - (fma:VSF (match_operand:VSF 1 "spu_reg_operand" "r") - (match_operand:VSF 2 "spu_reg_operand" "r") - (match_operand:VSF 3 "spu_reg_operand" "r")))] - "" - "fma\t%0,%1,%2,%3" - [(set_attr "type" "fp6")]) - -;; ??? The official description is (c - a*b), which is exactly (-a*b + c). -;; Note that this doesn't match the dfnms description. Incorrect? -(define_insn "fnma4" - [(set (match_operand:VSF 0 "spu_reg_operand" "=r") - (fma:VSF - (neg:VSF (match_operand:VSF 1 "spu_reg_operand" "r")) - (match_operand:VSF 2 "spu_reg_operand" "r") - (match_operand:VSF 3 "spu_reg_operand" "r")))] - "" - "fnms\t%0,%1,%2,%3" - [(set_attr "type" "fp6")]) - -(define_insn "fms4" - [(set (match_operand:VSF 0 "spu_reg_operand" "=r") - (fma:VSF - (match_operand:VSF 1 "spu_reg_operand" "r") - (match_operand:VSF 2 "spu_reg_operand" "r") - (neg:VSF (match_operand:VSF 3 "spu_reg_operand" "r"))))] - "" - "fms\t%0,%1,%2,%3" - [(set_attr "type" "fp6")]) - -(define_insn "fma4" - [(set (match_operand:VDF 0 "spu_reg_operand" "=r") - (fma:VDF (match_operand:VDF 1 "spu_reg_operand" "r") - (match_operand:VDF 2 "spu_reg_operand" "r") - (match_operand:VDF 3 "spu_reg_operand" "0")))] - "" - "dfma\t%0,%1,%2" - [(set_attr "type" "fpd")]) - -(define_insn "fms4" - [(set (match_operand:VDF 0 "spu_reg_operand" "=r") - (fma:VDF - (match_operand:VDF 1 "spu_reg_operand" "r") - (match_operand:VDF 2 "spu_reg_operand" "r") - (neg:VDF (match_operand:VDF 3 "spu_reg_operand" "0"))))] - "" - "dfms\t%0,%1,%2" - [(set_attr "type" "fpd")]) - -(define_insn "nfma4" - [(set (match_operand:VDF 0 "spu_reg_operand" "=r") - (neg:VDF - (fma:VDF (match_operand:VDF 1 "spu_reg_operand" "r") - (match_operand:VDF 2 "spu_reg_operand" "r") - (match_operand:VDF 3 "spu_reg_operand" "0"))))] - "" - "dfnma\t%0,%1,%2" - [(set_attr "type" "fpd")]) - -(define_insn "nfms4" - [(set (match_operand:VDF 0 "spu_reg_operand" "=r") - (neg:VDF - (fma:VDF - (match_operand:VDF 1 "spu_reg_operand" "r") - (match_operand:VDF 2 "spu_reg_operand" "r") - (neg:VDF (match_operand:VDF 3 "spu_reg_operand" "0")))))] - "" - "dfnms\t%0,%1,%2" - [(set_attr "type" "fpd")]) - -;; If signed zeros are ignored, -(a * b - c) = -a * b + c. -(define_expand "fnma4" - [(set (match_operand:VDF 0 "spu_reg_operand" "") - (neg:VDF - (fma:VDF - (match_operand:VDF 1 "spu_reg_operand" "") - (match_operand:VDF 2 "spu_reg_operand" "") - (neg:VDF (match_operand:VDF 3 "spu_reg_operand" "")))))] - "!HONOR_SIGNED_ZEROS (mode)" - "") - -;; If signed zeros are ignored, -(a * b + c) = -a * b - c. -(define_expand "fnms4" - [(set (match_operand:VDF 0 "register_operand" "") - (neg:VDF - (fma:VDF - (match_operand:VDF 1 "register_operand" "") - (match_operand:VDF 2 "register_operand" "") - (match_operand:VDF 3 "register_operand" ""))))] - "!HONOR_SIGNED_ZEROS (mode)" - "") - -;; mul highpart, used for divide by constant optimizations. - -(define_expand "smulsi3_highpart" - [(set (match_operand:SI 0 "register_operand" "") - (truncate:SI - (ashiftrt:DI - (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "")) - (sign_extend:DI (match_operand:SI 2 "register_operand" ""))) - (const_int 32))))] - "" - { - rtx t0 = gen_reg_rtx (SImode); - rtx t1 = gen_reg_rtx (SImode); - rtx t2 = gen_reg_rtx (SImode); - rtx t3 = gen_reg_rtx (SImode); - rtx t4 = gen_reg_rtx (SImode); - rtx t5 = gen_reg_rtx (SImode); - rtx t6 = gen_reg_rtx (SImode); - rtx t7 = gen_reg_rtx (SImode); - rtx t8 = gen_reg_rtx (SImode); - rtx t9 = gen_reg_rtx (SImode); - rtx t11 = gen_reg_rtx (SImode); - rtx t12 = gen_reg_rtx (SImode); - rtx t14 = gen_reg_rtx (SImode); - rtx t15 = gen_reg_rtx (HImode); - rtx t16 = gen_reg_rtx (HImode); - rtx t17 = gen_reg_rtx (HImode); - rtx t18 = gen_reg_rtx (HImode); - rtx t19 = gen_reg_rtx (SImode); - rtx t20 = gen_reg_rtx (SImode); - rtx t21 = gen_reg_rtx (SImode); - rtx op1_hi = gen_rtx_SUBREG (HImode, operands[1], 2); - rtx op2_hi = gen_rtx_SUBREG (HImode, operands[2], 2); - rtx t0_hi = gen_rtx_SUBREG (HImode, t0, 2); - rtx t1_hi = gen_rtx_SUBREG (HImode, t1, 2); - - rtx_insn *insn = emit_insn (gen_lshrsi3 (t0, operands[1], GEN_INT (16))); - emit_insn (gen_lshrsi3 (t1, operands[2], GEN_INT (16))); - emit_insn (gen_umulhisi3 (t2, op1_hi, op2_hi)); - emit_insn (gen_mpyh_si (t3, operands[1], operands[2])); - emit_insn (gen_mpyh_si (t4, operands[2], operands[1])); - emit_insn (gen_mpyhh_si (t5, operands[1], operands[2])); - emit_insn (gen_mpys_si (t6, t0_hi, op2_hi)); - emit_insn (gen_mpys_si (t7, t1_hi, op1_hi)); - - /* Gen carry bits (in t9 and t11). */ - emit_insn (gen_addsi3 (t8, t2, t3)); - emit_insn (gen_cg_si (t9, t2, t3)); - emit_insn (gen_cg_si (t11, t8, t4)); - - /* Gen high 32 bits in operand[0]. Correct for mpys. */ - emit_insn (gen_addx_si (t12, t5, t6, t9)); - emit_insn (gen_addx_si (t14, t12, t7, t11)); - - /* mpys treats both operands as signed when we really want it to treat - the first operand as signed and the second operand as unsigned. - The code below corrects for that difference. */ - emit_insn (gen_cgt_hi (t15, op1_hi, GEN_INT (-1))); - emit_insn (gen_cgt_hi (t16, op2_hi, GEN_INT (-1))); - emit_insn (gen_andc_hi (t17, t1_hi, t15)); - emit_insn (gen_andc_hi (t18, t0_hi, t16)); - emit_insn (gen_extendhisi2 (t19, t17)); - emit_insn (gen_extendhisi2 (t20, t18)); - emit_insn (gen_addsi3 (t21, t19, t20)); - emit_insn (gen_addsi3 (operands[0], t14, t21)); - unshare_all_rtl_in_chain (insn); - DONE; - }) - -(define_expand "umulsi3_highpart" - [(set (match_operand:SI 0 "register_operand" "") - (truncate:SI - (ashiftrt:DI - (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "")) - (zero_extend:DI (match_operand:SI 2 "register_operand" ""))) - (const_int 32))))] - "" - - { - rtx t0 = gen_reg_rtx (SImode); - rtx t1 = gen_reg_rtx (SImode); - rtx t2 = gen_reg_rtx (SImode); - rtx t3 = gen_reg_rtx (SImode); - rtx t4 = gen_reg_rtx (SImode); - rtx t5 = gen_reg_rtx (SImode); - rtx t6 = gen_reg_rtx (SImode); - rtx t7 = gen_reg_rtx (SImode); - rtx t8 = gen_reg_rtx (SImode); - rtx t9 = gen_reg_rtx (SImode); - rtx t10 = gen_reg_rtx (SImode); - rtx t12 = gen_reg_rtx (SImode); - rtx t13 = gen_reg_rtx (SImode); - rtx t14 = gen_reg_rtx (SImode); - rtx op1_hi = gen_rtx_SUBREG (HImode, operands[1], 2); - rtx op2_hi = gen_rtx_SUBREG (HImode, operands[2], 2); - rtx t0_hi = gen_rtx_SUBREG (HImode, t0, 2); - - rtx_insn *insn = emit_insn (gen_rotlsi3 (t0, operands[2], GEN_INT (16))); - emit_insn (gen_umulhisi3 (t1, op1_hi, op2_hi)); - emit_insn (gen_umulhisi3 (t2, op1_hi, t0_hi)); - emit_insn (gen_mpyhhu_si (t3, operands[1], t0)); - emit_insn (gen_mpyhhu_si (t4, operands[1], operands[2])); - emit_insn (gen_ashlsi3 (t5, t2, GEN_INT (16))); - emit_insn (gen_ashlsi3 (t6, t3, GEN_INT (16))); - emit_insn (gen_lshrsi3 (t7, t2, GEN_INT (16))); - emit_insn (gen_lshrsi3 (t8, t3, GEN_INT (16))); - - /* Gen carry bits (in t10 and t12). */ - emit_insn (gen_addsi3 (t9, t1, t5)); - emit_insn (gen_cg_si (t10, t1, t5)); - emit_insn (gen_cg_si (t12, t9, t6)); - - /* Gen high 32 bits in operand[0]. */ - emit_insn (gen_addx_si (t13, t4, t7, t10)); - emit_insn (gen_addx_si (t14, t13, t8, t12)); - emit_insn (gen_movsi (operands[0], t14)); - unshare_all_rtl_in_chain (insn); - - DONE; - }) - -;; div - -;; Not necessarily the best implementation of divide but faster then -;; the default that gcc provides because this is inlined and it uses -;; clz. -(define_insn "divmodsi4" - [(set (match_operand:SI 0 "spu_reg_operand" "=&r") - (div:SI (match_operand:SI 1 "spu_reg_operand" "r") - (match_operand:SI 2 "spu_reg_operand" "r"))) - (set (match_operand:SI 3 "spu_reg_operand" "=&r") - (mod:SI (match_dup 1) - (match_dup 2))) - (clobber (match_scratch:SI 4 "=&r")) - (clobber (match_scratch:SI 5 "=&r")) - (clobber (match_scratch:SI 6 "=&r")) - (clobber (match_scratch:SI 7 "=&r")) - (clobber (match_scratch:SI 8 "=&r")) - (clobber (match_scratch:SI 9 "=&r")) - (clobber (match_scratch:SI 10 "=&r")) - (clobber (match_scratch:SI 11 "=&r")) - (clobber (match_scratch:SI 12 "=&r")) - (clobber (reg:SI 130))] - "" - "heqi %2,0\\n\\ - hbrr 3f,1f\\n\\ - sfi %8,%1,0\\n\\ - sfi %9,%2,0\\n\\ - cgti %10,%1,-1\\n\\ - cgti %11,%2,-1\\n\\ - selb %8,%8,%1,%10\\n\\ - selb %9,%9,%2,%11\\n\\ - clz %4,%8\\n\\ - clz %7,%9\\n\\ - il %5,1\\n\\ - fsmbi %0,0\\n\\ - sf %7,%4,%7\\n\\ - shlqbyi %3,%8,0\\n\\ - xor %11,%10,%11\\n\\ - shl %5,%5,%7\\n\\ - shl %4,%9,%7\\n\\ - lnop \\n\\ -1: or %12,%0,%5\\n\\ - rotqmbii %5,%5,-1\\n\\ - clgt %6,%4,%3\\n\\ - lnop \\n\\ - sf %7,%4,%3\\n\\ - rotqmbii %4,%4,-1\\n\\ - selb %0,%12,%0,%6\\n\\ - lnop \\n\\ - selb %3,%7,%3,%6\\n\\ -3: brnz %5,1b\\n\\ -2: sfi %8,%3,0\\n\\ - sfi %9,%0,0\\n\\ - selb %3,%8,%3,%10\\n\\ - selb %0,%0,%9,%11" - [(set_attr "type" "multi0") - (set_attr "length" "128")]) - -(define_insn "udivmodsi4" - [(set (match_operand:SI 0 "spu_reg_operand" "=&r") - (udiv:SI (match_operand:SI 1 "spu_reg_operand" "r") - (match_operand:SI 2 "spu_reg_operand" "r"))) - (set (match_operand:SI 3 "spu_reg_operand" "=&r") - (umod:SI (match_dup 1) - (match_dup 2))) - (clobber (match_scratch:SI 4 "=&r")) - (clobber (match_scratch:SI 5 "=&r")) - (clobber (match_scratch:SI 6 "=&r")) - (clobber (match_scratch:SI 7 "=&r")) - (clobber (match_scratch:SI 8 "=&r")) - (clobber (reg:SI 130))] - "" - "heqi %2,0\\n\\ - hbrr 3f,1f\\n\\ - clz %7,%2\\n\\ - clz %4,%1\\n\\ - il %5,1\\n\\ - fsmbi %0,0\\n\\ - sf %7,%4,%7\\n\\ - ori %3,%1,0\\n\\ - shl %5,%5,%7\\n\\ - shl %4,%2,%7\\n\\ -1: or %8,%0,%5\\n\\ - rotqmbii %5,%5,-1\\n\\ - clgt %6,%4,%3\\n\\ - lnop \\n\\ - sf %7,%4,%3\\n\\ - rotqmbii %4,%4,-1\\n\\ - selb %0,%8,%0,%6\\n\\ - lnop \\n\\ - selb %3,%7,%3,%6\\n\\ -3: brnz %5,1b\\n\\ -2:" - [(set_attr "type" "multi0") - (set_attr "length" "80")]) - -(define_expand "div3" - [(parallel - [(set (match_operand:VSF 0 "spu_reg_operand" "") - (div:VSF (match_operand:VSF 1 "spu_reg_operand" "") - (match_operand:VSF 2 "spu_reg_operand" ""))) - (clobber (match_scratch:VSF 3 "")) - (clobber (match_scratch:VSF 4 "")) - (clobber (match_scratch:VSF 5 ""))])] - "" - "") - -(define_insn_and_split "*div3_fast" - [(set (match_operand:VSF 0 "spu_reg_operand" "=r") - (div:VSF (match_operand:VSF 1 "spu_reg_operand" "r") - (match_operand:VSF 2 "spu_reg_operand" "r"))) - (clobber (match_scratch:VSF 3 "=&r")) - (clobber (match_scratch:VSF 4 "=&r")) - (clobber (scratch:VSF))] - "flag_unsafe_math_optimizations" - "#" - "reload_completed" - [(set (match_dup:VSF 0) - (div:VSF (match_dup:VSF 1) - (match_dup:VSF 2))) - (clobber (match_dup:VSF 3)) - (clobber (match_dup:VSF 4)) - (clobber (scratch:VSF))] - { - emit_insn (gen_frest_(operands[3], operands[2])); - emit_insn (gen_fi_(operands[3], operands[2], operands[3])); - emit_insn (gen_mul3(operands[4], operands[1], operands[3])); - emit_insn (gen_fnma4(operands[0], operands[4], operands[2], operands[1])); - emit_insn (gen_fma4(operands[0], operands[0], operands[3], operands[4])); - DONE; - }) - -(define_insn_and_split "*div3_adjusted" - [(set (match_operand:VSF 0 "spu_reg_operand" "=r") - (div:VSF (match_operand:VSF 1 "spu_reg_operand" "r") - (match_operand:VSF 2 "spu_reg_operand" "r"))) - (clobber (match_scratch:VSF 3 "=&r")) - (clobber (match_scratch:VSF 4 "=&r")) - (clobber (match_scratch:VSF 5 "=&r"))] - "!flag_unsafe_math_optimizations" - "#" - "reload_completed" - [(set (match_dup:VSF 0) - (div:VSF (match_dup:VSF 1) - (match_dup:VSF 2))) - (clobber (match_dup:VSF 3)) - (clobber (match_dup:VSF 4)) - (clobber (match_dup:VSF 5))] - { - emit_insn (gen_frest_ (operands[3], operands[2])); - emit_insn (gen_fi_ (operands[3], operands[2], operands[3])); - emit_insn (gen_mul3 (operands[4], operands[1], operands[3])); - emit_insn (gen_fnma4 (operands[5], operands[4], operands[2], operands[1])); - emit_insn (gen_fma4 (operands[3], operands[5], operands[3], operands[4])); - - /* Due to truncation error, the quotient result may be low by 1 ulp. - Conditionally add one if the estimate is too small in magnitude. */ - - emit_move_insn (gen_lowpart (mode, operands[4]), - spu_const (mode, 0x80000000ULL)); - emit_move_insn (gen_lowpart (mode, operands[5]), - spu_const (mode, 0x3f800000ULL)); - emit_insn (gen_selb (operands[5], operands[5], operands[1], operands[4])); - - emit_insn (gen_add3 (gen_lowpart (mode, operands[4]), - gen_lowpart (mode, operands[3]), - spu_const (mode, 1))); - emit_insn (gen_fnma4 (operands[0], operands[2], operands[4], operands[1])); - emit_insn (gen_mul3 (operands[0], operands[0], operands[5])); - emit_insn (gen_cgt_ (gen_lowpart (mode, operands[0]), - gen_lowpart (mode, operands[0]), - spu_const (mode, -1))); - emit_insn (gen_selb (operands[0], operands[3], operands[4], operands[0])); - DONE; - }) - - -;; sqrt - -(define_insn_and_split "sqrtsf2" - [(set (match_operand:SF 0 "spu_reg_operand" "=r") - (sqrt:SF (match_operand:SF 1 "spu_reg_operand" "r"))) - (clobber (match_scratch:SF 2 "=&r")) - (clobber (match_scratch:SF 3 "=&r")) - (clobber (match_scratch:SF 4 "=&r")) - (clobber (match_scratch:SF 5 "=&r"))] - "" - "#" - "reload_completed" - [(set (match_dup:SF 0) - (sqrt:SF (match_dup:SF 1))) - (clobber (match_dup:SF 2)) - (clobber (match_dup:SF 3)) - (clobber (match_dup:SF 4)) - (clobber (match_dup:SF 5))] - { - emit_move_insn (operands[3],spu_float_const(\"0.5\",SFmode)); - emit_move_insn (operands[4],spu_float_const(\"1.00000011920928955078125\",SFmode)); - emit_insn (gen_frsqest_sf(operands[2],operands[1])); - emit_insn (gen_fi_sf(operands[2],operands[1],operands[2])); - emit_insn (gen_mulsf3(operands[5],operands[2],operands[1])); - emit_insn (gen_mulsf3(operands[3],operands[5],operands[3])); - emit_insn (gen_fnmasf4(operands[4],operands[2],operands[5],operands[4])); - emit_insn (gen_fmasf4(operands[0],operands[4],operands[3],operands[5])); - DONE; - }) - -(define_insn "frest_" - [(set (match_operand:VSF 0 "spu_reg_operand" "=r") - (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")] UNSPEC_FREST))] - "" - "frest\t%0,%1" - [(set_attr "type" "shuf")]) - -(define_insn "frsqest_" - [(set (match_operand:VSF 0 "spu_reg_operand" "=r") - (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")] UNSPEC_FRSQEST))] - "" - "frsqest\t%0,%1" - [(set_attr "type" "shuf")]) - -(define_insn "fi_" - [(set (match_operand:VSF 0 "spu_reg_operand" "=r") - (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r") - (match_operand:VSF 2 "spu_reg_operand" "r")] UNSPEC_FI))] - "" - "fi\t%0,%1,%2" - [(set_attr "type" "fp7")]) - - -;; and - -(define_insn "and3" - [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r") - (and:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r") - (match_operand:MOV 2 "spu_logical_operand" "r,C")))] - "" - "@ - and\t%0,%1,%2 - and%j2i\t%0,%1,%J2") - -(define_insn "anddi3" - [(set (match_operand:DI 0 "spu_reg_operand" "=r,r") - (and:DI (match_operand:DI 1 "spu_reg_operand" "r,r") - (match_operand:DI 2 "spu_logical_operand" "r,c")))] - "" - "@ - and\t%0,%1,%2 - and%k2i\t%0,%1,%K2") - -(define_insn "andti3" - [(set (match_operand:TI 0 "spu_reg_operand" "=r,r") - (and:TI (match_operand:TI 1 "spu_reg_operand" "r,r") - (match_operand:TI 2 "spu_logical_operand" "r,Y")))] - "" - "@ - and\t%0,%1,%2 - and%m2i\t%0,%1,%L2") - -(define_insn "andc_" - [(set (match_operand:ALL 0 "spu_reg_operand" "=r") - (and:ALL (not:ALL (match_operand:ALL 2 "spu_reg_operand" "r")) - (match_operand:ALL 1 "spu_reg_operand" "r")))] - "" - "andc\t%0,%1,%2") - -(define_insn "nand_" - [(set (match_operand:ALL 0 "spu_reg_operand" "=r") - (not:ALL (and:ALL (match_operand:ALL 2 "spu_reg_operand" "r") - (match_operand:ALL 1 "spu_reg_operand" "r"))))] - "" - "nand\t%0,%1,%2") - - -;; ior - -(define_insn "ior3" - [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r,r") - (ior:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r,0") - (match_operand:MOV 2 "spu_ior_operand" "r,C,D")))] - "" - "@ - or\t%0,%1,%2 - or%j2i\t%0,%1,%J2 - iohl\t%0,%J2") - -(define_insn "iordi3" - [(set (match_operand:DI 0 "spu_reg_operand" "=r,r,r") - (ior:DI (match_operand:DI 1 "spu_reg_operand" "r,r,0") - (match_operand:DI 2 "spu_ior_operand" "r,c,d")))] - "" - "@ - or\t%0,%1,%2 - or%k2i\t%0,%1,%K2 - iohl\t%0,%K2") - -(define_insn "iorti3" - [(set (match_operand:TI 0 "spu_reg_operand" "=r,r,r") - (ior:TI (match_operand:TI 1 "spu_reg_operand" "r,r,0") - (match_operand:TI 2 "spu_ior_operand" "r,Y,Z")))] - "" - "@ - or\t%0,%1,%2 - or%m2i\t%0,%1,%L2 - iohl\t%0,%L2") - -(define_insn "orc_" - [(set (match_operand:ALL 0 "spu_reg_operand" "=r") - (ior:ALL (not:ALL (match_operand:ALL 2 "spu_reg_operand" "r")) - (match_operand:ALL 1 "spu_reg_operand" "r")))] - "" - "orc\t%0,%1,%2") - -(define_insn "nor_" - [(set (match_operand:ALL 0 "spu_reg_operand" "=r") - (not:ALL (ior:ALL (match_operand:ALL 1 "spu_reg_operand" "r") - (match_operand:ALL 2 "spu_reg_operand" "r"))))] - "" - "nor\t%0,%1,%2") - -;; xor - -(define_insn "xor3" - [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r") - (xor:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r") - (match_operand:MOV 2 "spu_logical_operand" "r,B")))] - "" - "@ - xor\t%0,%1,%2 - xor%j2i\t%0,%1,%J2") - -(define_insn "xordi3" - [(set (match_operand:DI 0 "spu_reg_operand" "=r,r") - (xor:DI (match_operand:DI 1 "spu_reg_operand" "r,r") - (match_operand:DI 2 "spu_logical_operand" "r,c")))] - "" - "@ - xor\t%0,%1,%2 - xor%k2i\t%0,%1,%K2") - -(define_insn "xorti3" - [(set (match_operand:TI 0 "spu_reg_operand" "=r,r") - (xor:TI (match_operand:TI 1 "spu_reg_operand" "r,r") - (match_operand:TI 2 "spu_logical_operand" "r,Y")))] - "" - "@ - xor\t%0,%1,%2 - xor%m2i\t%0,%1,%L2") - -(define_insn "eqv_" - [(set (match_operand:ALL 0 "spu_reg_operand" "=r") - (not:ALL (xor:ALL (match_operand:ALL 1 "spu_reg_operand" "r") - (match_operand:ALL 2 "spu_reg_operand" "r"))))] - "" - "eqv\t%0,%1,%2") - -;; one_cmpl - -(define_insn "one_cmpl2" - [(set (match_operand:ALL 0 "spu_reg_operand" "=r") - (not:ALL (match_operand:ALL 1 "spu_reg_operand" "r")))] - "" - "nor\t%0,%1,%1") - - -;; selb - -(define_expand "selb" - [(set (match_operand 0 "spu_reg_operand" "") - (unspec [(match_operand 1 "spu_reg_operand" "") - (match_operand 2 "spu_reg_operand" "") - (match_operand 3 "spu_reg_operand" "")] UNSPEC_SELB))] - "" - { - rtx s = gen__selb (operands[0], operands[1], operands[2], operands[3]); - PUT_MODE (SET_SRC (s), GET_MODE (operands[0])); - emit_insn (s); - DONE; - }) - -;; This could be defined as a combination of logical operations, but at -;; one time it caused a crash due to recursive expansion of rtl during CSE. -(define_insn "_selb" - [(set (match_operand 0 "spu_reg_operand" "=r") - (unspec [(match_operand 1 "spu_reg_operand" "r") - (match_operand 2 "spu_reg_operand" "r") - (match_operand 3 "spu_reg_operand" "r")] UNSPEC_SELB))] - "GET_MODE(operands[0]) == GET_MODE(operands[1]) - && GET_MODE(operands[1]) == GET_MODE(operands[2])" - "selb\t%0,%1,%2,%3") - - -;; Misc. byte/bit operations -;; clz/ctz/ffs/popcount/parity -;; cntb/sumb - -(define_insn "clz2" - [(set (match_operand:VSI 0 "spu_reg_operand" "=r") - (clz:VSI (match_operand:VSI 1 "spu_reg_operand" "r")))] - "" - "clz\t%0,%1") - -(define_expand "ctz2" - [(set (match_dup 2) - (neg:VSI (match_operand:VSI 1 "spu_reg_operand" ""))) - (set (match_dup 3) (and:VSI (match_dup 1) - (match_dup 2))) - (set (match_dup 4) (clz:VSI (match_dup 3))) - (set (match_operand:VSI 0 "spu_reg_operand" "") - (minus:VSI (match_dup 5) (match_dup 4)))] - "" - { - operands[2] = gen_reg_rtx (mode); - operands[3] = gen_reg_rtx (mode); - operands[4] = gen_reg_rtx (mode); - operands[5] = spu_const(mode, 31); - }) - -(define_expand "clrsb2" - [(set (match_dup 2) - (gt:VSI (match_operand:VSI 1 "spu_reg_operand" "") (match_dup 5))) - (set (match_dup 3) (not:VSI (xor:VSI (match_dup 1) (match_dup 2)))) - (set (match_dup 4) (clz:VSI (match_dup 3))) - (set (match_operand:VSI 0 "spu_reg_operand") - (plus:VSI (match_dup 4) (match_dup 5)))] - "" - { - operands[2] = gen_reg_rtx (mode); - operands[3] = gen_reg_rtx (mode); - operands[4] = gen_reg_rtx (mode); - operands[5] = spu_const(mode, -1); - }) - -(define_expand "ffs2" - [(set (match_dup 2) - (neg:VSI (match_operand:VSI 1 "spu_reg_operand" ""))) - (set (match_dup 3) (and:VSI (match_dup 1) - (match_dup 2))) - (set (match_dup 4) (clz:VSI (match_dup 3))) - (set (match_operand:VSI 0 "spu_reg_operand" "") - (minus:VSI (match_dup 5) (match_dup 4)))] - "" - { - operands[2] = gen_reg_rtx (mode); - operands[3] = gen_reg_rtx (mode); - operands[4] = gen_reg_rtx (mode); - operands[5] = spu_const(mode, 32); - }) - -(define_expand "popcountsi2" - [(set (match_dup 2) - (unspec:SI [(match_operand:SI 1 "spu_reg_operand" "")] - UNSPEC_CNTB)) - (set (match_dup 3) - (unspec:HI [(match_dup 2)] UNSPEC_SUMB)) - (set (match_operand:SI 0 "spu_reg_operand" "") - (sign_extend:SI (match_dup 3)))] - "" - { - operands[2] = gen_reg_rtx (SImode); - operands[3] = gen_reg_rtx (HImode); - }) - -(define_expand "paritysi2" - [(set (match_operand:SI 0 "spu_reg_operand" "") - (parity:SI (match_operand:SI 1 "spu_reg_operand" "")))] - "" - { - operands[2] = gen_reg_rtx (SImode); - emit_insn (gen_popcountsi2(operands[2], operands[1])); - emit_insn (gen_andsi3(operands[0], operands[2], GEN_INT (1))); - DONE; - }) - -(define_insn "cntb_si" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (unspec:SI [(match_operand:SI 1 "spu_reg_operand" "r")] - UNSPEC_CNTB))] - "" - "cntb\t%0,%1" - [(set_attr "type" "fxb")]) - -(define_insn "cntb_v16qi" - [(set (match_operand:V16QI 0 "spu_reg_operand" "=r") - (unspec:V16QI [(match_operand:V16QI 1 "spu_reg_operand" "r")] - UNSPEC_CNTB))] - "" - "cntb\t%0,%1" - [(set_attr "type" "fxb")]) - -(define_insn "sumb_si" - [(set (match_operand:HI 0 "spu_reg_operand" "=r") - (unspec:HI [(match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_SUMB))] - "" - "sumb\t%0,%1,%1" - [(set_attr "type" "fxb")]) - - -;; ashl, vashl - -(define_insn "ashl3" - [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r") - (ashift:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r") - (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))] - "" - "@ - shl\t%0,%1,%2 - shli\t%0,%1,%2" - [(set_attr "type" "fx3")]) - -(define_insn_and_split "ashldi3" - [(set (match_operand:DI 0 "spu_reg_operand" "=r,r") - (ashift:DI (match_operand:DI 1 "spu_reg_operand" "r,r") - (match_operand:SI 2 "spu_nonmem_operand" "r,I"))) - (clobber (match_scratch:SI 3 "=&r,X"))] - "" - "#" - "reload_completed" - [(set (match_dup:DI 0) - (ashift:DI (match_dup:DI 1) - (match_dup:SI 2)))] - { - rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0])); - rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1])); - rtx op2 = operands[2]; - rtx op3 = operands[3]; - - if (GET_CODE (operands[2]) == REG) - { - emit_insn (gen_addsi3 (op3, op2, GEN_INT (64))); - emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64))); - emit_insn (gen_shlqbybi_ti (op0, op0, op3)); - emit_insn (gen_shlqbi_ti (op0, op0, op3)); - } - else - { - HOST_WIDE_INT val = INTVAL (operands[2]); - emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64))); - emit_insn (gen_shlqby_ti (op0, op0, GEN_INT (val / 8 + 8))); - if (val % 8) - emit_insn (gen_shlqbi_ti (op0, op0, GEN_INT (val % 8))); - } - DONE; - }) - -(define_expand "ashlti3" - [(parallel [(set (match_operand:TI 0 "spu_reg_operand" "") - (ashift:TI (match_operand:TI 1 "spu_reg_operand" "") - (match_operand:SI 2 "spu_nonmem_operand" ""))) - (clobber (match_dup:TI 3))])] - "" - "if (GET_CODE (operands[2]) == CONST_INT) - { - emit_insn (gen_ashlti3_imm(operands[0], operands[1], operands[2])); - DONE; - } - operands[3] = gen_reg_rtx (TImode);") - -(define_insn_and_split "ashlti3_imm" - [(set (match_operand:TI 0 "spu_reg_operand" "=r,r") - (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r") - (match_operand:SI 2 "immediate_operand" "O,P")))] - "" - "@ - shlqbyi\t%0,%1,%h2 - shlqbii\t%0,%1,%e2" - "!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2])" - [(set (match_dup:TI 0) - (ashift:TI (match_dup:TI 1) - (match_dup:SI 3))) - (set (match_dup:TI 0) - (ashift:TI (match_dup:TI 0) - (match_dup:SI 4)))] - { - HOST_WIDE_INT val = INTVAL(operands[2]); - operands[3] = GEN_INT (val&7); - operands[4] = GEN_INT (val&-8); - } - [(set_attr "type" "shuf,shuf")]) - -(define_insn_and_split "ashlti3_reg" - [(set (match_operand:TI 0 "spu_reg_operand" "=r") - (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r") - (match_operand:SI 2 "spu_reg_operand" "r"))) - (clobber (match_operand:TI 3 "spu_reg_operand" "=&r"))] - "" - "#" - "" - [(set (match_dup:TI 3) - (ashift:TI (match_dup:TI 1) - (and:SI (match_dup:SI 2) - (const_int 7)))) - (set (match_dup:TI 0) - (ashift:TI (match_dup:TI 3) - (and:SI (match_dup:SI 2) - (const_int -8))))] - "") - -(define_insn "shlqbybi_ti" - [(set (match_operand:TI 0 "spu_reg_operand" "=r,r") - (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r") - (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I") - (const_int -8))))] - "" - "@ - shlqbybi\t%0,%1,%2 - shlqbyi\t%0,%1,%h2" - [(set_attr "type" "shuf,shuf")]) - -(define_insn "shlqbi_ti" - [(set (match_operand:TI 0 "spu_reg_operand" "=r,r") - (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r") - (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I") - (const_int 7))))] - "" - "@ - shlqbi\t%0,%1,%2 - shlqbii\t%0,%1,%e2" - [(set_attr "type" "shuf,shuf")]) - -(define_insn "shlqby_ti" - [(set (match_operand:TI 0 "spu_reg_operand" "=r,r") - (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r") - (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I") - (const_int 8))))] - "" - "@ - shlqby\t%0,%1,%2 - shlqbyi\t%0,%1,%f2" - [(set_attr "type" "shuf,shuf")]) - - -;; lshr, vlshr - -(define_insn_and_split "lshr3" - [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r") - (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r") - (match_operand:VHSI 2 "spu_nonmem_operand" "r,W"))) - (clobber (match_scratch:VHSI 3 "=&r,X"))] - "" - "@ - # - rotmi\t%0,%1,-%2" - "reload_completed && GET_CODE (operands[2]) == REG" - [(set (match_dup:VHSI 3) - (neg:VHSI (match_dup:VHSI 2))) - (set (match_dup:VHSI 0) - (lshiftrt:VHSI (match_dup:VHSI 1) - (neg:VHSI (match_dup:VHSI 3))))] - "" - [(set_attr "type" "*,fx3")]) - -(define_insn "lshr3_imm" - [(set (match_operand:VHSI 0 "spu_reg_operand" "=r") - (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r") - (match_operand:VHSI 2 "immediate_operand" "W")))] - "" - "rotmi\t%0,%1,-%2" - [(set_attr "type" "fx3")]) - -(define_insn "rotm_" - [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r") - (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r") - (neg:VHSI (match_operand:VHSI 2 "spu_nonmem_operand" "r,W"))))] - "" - "@ - rotm\t%0,%1,%2 - rotmi\t%0,%1,-%2" - [(set_attr "type" "fx3")]) - -(define_insn_and_split "lshr3" - [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r,r") - (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r,r") - (match_operand:SI 2 "spu_nonmem_operand" "r,O,P")))] - "" - "@ - # - rotqmbyi\t%0,%1,-%h2 - rotqmbii\t%0,%1,-%e2" - "REG_P (operands[2]) || (!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2]))" - [(set (match_dup:DTI 3) - (lshiftrt:DTI (match_dup:DTI 1) - (match_dup:SI 4))) - (set (match_dup:DTI 0) - (lshiftrt:DTI (match_dup:DTI 3) - (match_dup:SI 5)))] - { - operands[3] = gen_reg_rtx (mode); - if (GET_CODE (operands[2]) == CONST_INT) - { - HOST_WIDE_INT val = INTVAL(operands[2]); - operands[4] = GEN_INT (val & 7); - operands[5] = GEN_INT (val & -8); - } - else - { - rtx t0 = gen_reg_rtx (SImode); - rtx t1 = gen_reg_rtx (SImode); - emit_insn (gen_subsi3(t0, GEN_INT(0), operands[2])); - emit_insn (gen_subsi3(t1, GEN_INT(7), operands[2])); - operands[4] = gen_rtx_AND (SImode, gen_rtx_NEG (SImode, t0), GEN_INT (7)); - operands[5] = gen_rtx_AND (SImode, gen_rtx_NEG (SImode, gen_rtx_AND (SImode, t1, GEN_INT (-8))), GEN_INT (-8)); - } - } - [(set_attr "type" "*,shuf,shuf")]) - -(define_expand "shrqbybi_" - [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r") - (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r") - (and:SI (neg:SI (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I") - (const_int -8))) - (const_int -8))))] - "" - { - if (GET_CODE (operands[2]) == CONST_INT) - operands[2] = GEN_INT (7 - INTVAL (operands[2])); - else - { - rtx t0 = gen_reg_rtx (SImode); - emit_insn (gen_subsi3 (t0, GEN_INT (7), operands[2])); - operands[2] = t0; - } - }) - -(define_insn "rotqmbybi_" - [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r") - (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r") - (and:SI (neg:SI (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I") - (const_int -8))) - (const_int -8))))] - "" - "@ - rotqmbybi\t%0,%1,%2 - rotqmbyi\t%0,%1,-%H2" - [(set_attr "type" "shuf")]) - -(define_insn_and_split "shrqbi_" - [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r") - (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r") - (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I") - (const_int 7)))) - (clobber (match_scratch:SI 3 "=&r,X"))] - "" - "#" - "reload_completed" - [(set (match_dup:DTI 0) - (lshiftrt:DTI (match_dup:DTI 1) - (and:SI (neg:SI (match_dup:SI 3)) (const_int 7))))] - { - if (GET_CODE (operands[2]) == CONST_INT) - operands[3] = GEN_INT (-INTVAL (operands[2])); - else - emit_insn (gen_subsi3 (operands[3], GEN_INT (0), operands[2])); - } - [(set_attr "type" "shuf")]) - -(define_insn "rotqmbi_" - [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r") - (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r") - (and:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")) - (const_int 7))))] - "" - "@ - rotqmbi\t%0,%1,%2 - rotqmbii\t%0,%1,-%E2" - [(set_attr "type" "shuf")]) - -(define_expand "shrqby_" - [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r") - (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r") - (mult:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")) - (const_int 8))))] - "" - { - if (GET_CODE (operands[2]) == CONST_INT) - operands[2] = GEN_INT (-INTVAL (operands[2])); - else - { - rtx t0 = gen_reg_rtx (SImode); - emit_insn (gen_subsi3 (t0, GEN_INT (0), operands[2])); - operands[2] = t0; - } - }) - -(define_insn "rotqmby_" - [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r") - (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r") - (mult:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")) - (const_int 8))))] - "" - "@ - rotqmby\t%0,%1,%2 - rotqmbyi\t%0,%1,-%F2" - [(set_attr "type" "shuf")]) - - -;; ashr, vashr - -(define_insn_and_split "ashr3" - [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r") - (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r") - (match_operand:VHSI 2 "spu_nonmem_operand" "r,W"))) - (clobber (match_scratch:VHSI 3 "=&r,X"))] - "" - "@ - # - rotmai\t%0,%1,-%2" - "reload_completed && GET_CODE (operands[2]) == REG" - [(set (match_dup:VHSI 3) - (neg:VHSI (match_dup:VHSI 2))) - (set (match_dup:VHSI 0) - (ashiftrt:VHSI (match_dup:VHSI 1) - (neg:VHSI (match_dup:VHSI 3))))] - "" - [(set_attr "type" "*,fx3")]) - -(define_insn "ashr3_imm" - [(set (match_operand:VHSI 0 "spu_reg_operand" "=r") - (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r") - (match_operand:VHSI 2 "immediate_operand" "W")))] - "" - "rotmai\t%0,%1,-%2" - [(set_attr "type" "fx3")]) - - -(define_insn "rotma_" - [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r") - (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r") - (neg:VHSI (match_operand:VHSI 2 "spu_nonmem_operand" "r,W"))))] - "" - "@ - rotma\t%0,%1,%2 - rotmai\t%0,%1,-%2" - [(set_attr "type" "fx3")]) - -(define_insn_and_split "ashrdi3" - [(set (match_operand:DI 0 "spu_reg_operand" "=r,r") - (ashiftrt:DI (match_operand:DI 1 "spu_reg_operand" "r,r") - (match_operand:SI 2 "spu_nonmem_operand" "r,I"))) - (clobber (match_scratch:TI 3 "=&r,&r")) - (clobber (match_scratch:TI 4 "=&r,&r")) - (clobber (match_scratch:SI 5 "=&r,&r"))] - "" - "#" - "reload_completed" - [(set (match_dup:DI 0) - (ashiftrt:DI (match_dup:DI 1) - (match_dup:SI 2)))] - { - rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0])); - rtx op0v = gen_rtx_REG (V4SImode, REGNO (op0)); - rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1])); - rtx op1s = gen_rtx_REG (SImode, REGNO (op1)); - rtx op2 = operands[2]; - rtx op3 = operands[3]; - rtx op4 = operands[4]; - rtx op5 = operands[5]; - - if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 63) - { - rtx op0s = gen_rtx_REG (SImode, REGNO (op0)); - emit_insn (gen_ashrsi3 (op0s, op1s, GEN_INT (32))); - emit_insn (gen_spu_fsm (op0v, op0s)); - } - else if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 32) - { - rtx op0d = gen_rtx_REG (V2DImode, REGNO (op0)); - HOST_WIDE_INT val = INTVAL (op2); - emit_insn (gen_lshrti3 (op0, op1, GEN_INT (32))); - emit_insn (gen_spu_xswd (op0d, op0v)); - if (val > 32) - emit_insn (gen_vashrv4si3 (op0v, op0v, spu_const (V4SImode, val - 32))); - } - else - { - rtx op3v = gen_rtx_REG (V4SImode, REGNO (op3)); - unsigned char arr[16] = { - 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 - }; - - emit_insn (gen_ashrsi3 (op5, op1s, GEN_INT (31))); - emit_move_insn (op4, array_to_constant (TImode, arr)); - emit_insn (gen_spu_fsm (op3v, op5)); - - if (GET_CODE (operands[2]) == REG) - { - emit_insn (gen_selb (op4, op3, op1, op4)); - emit_insn (gen_negsi2 (op5, op2)); - emit_insn (gen_rotqbybi_ti (op0, op4, op5)); - emit_insn (gen_rotqbi_ti (op0, op0, op5)); - } - else - { - HOST_WIDE_INT val = -INTVAL (op2); - emit_insn (gen_selb (op0, op3, op1, op4)); - if ((val - 7) / 8) - emit_insn (gen_rotqby_ti (op0, op0, GEN_INT ((val - 7) / 8))); - if (val % 8) - emit_insn (gen_rotqbi_ti (op0, op0, GEN_INT (val % 8))); - } - } - DONE; - }) - - -(define_insn_and_split "ashrti3" - [(set (match_operand:TI 0 "spu_reg_operand" "=r,r") - (ashiftrt:TI (match_operand:TI 1 "spu_reg_operand" "r,r") - (match_operand:SI 2 "spu_nonmem_operand" "r,i")))] - "" - "#" - "" - [(set (match_dup:TI 0) - (ashiftrt:TI (match_dup:TI 1) - (match_dup:SI 2)))] - { - rtx sign_shift = gen_reg_rtx (SImode); - rtx sign_mask = gen_reg_rtx (TImode); - rtx sign_mask_v4si = gen_rtx_SUBREG (V4SImode, sign_mask, 0); - rtx op1_v4si = spu_gen_subreg (V4SImode, operands[1]); - rtx t = gen_reg_rtx (TImode); - emit_insn (gen_subsi3 (sign_shift, GEN_INT (128), force_reg (SImode, operands[2]))); - emit_insn (gen_vashrv4si3 (sign_mask_v4si, op1_v4si, spu_const (V4SImode, 31))); - emit_insn (gen_fsm_ti (sign_mask, sign_mask)); - emit_insn (gen_ashlti3 (sign_mask, sign_mask, sign_shift)); - emit_insn (gen_lshrti3 (t, operands[1], operands[2])); - emit_insn (gen_iorti3 (operands[0], t, sign_mask)); - DONE; - }) - -;; fsm is used after rotam to replicate the sign across the whole register. -(define_insn "fsm_ti" - [(set (match_operand:TI 0 "spu_reg_operand" "=r") - (unspec:TI [(match_operand:TI 1 "spu_reg_operand" "r")] UNSPEC_FSM))] - "" - "fsm\t%0,%1" - [(set_attr "type" "shuf")]) - - -;; vrotl, rotl - -(define_insn "rotl3" - [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r") - (rotate:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r") - (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))] - "" - "@ - rot\t%0,%1,%2 - roti\t%0,%1,%2" - [(set_attr "type" "fx3")]) - -(define_insn "rotlti3" - [(set (match_operand:TI 0 "spu_reg_operand" "=&r,r,r,r") - (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r,r,r") - (match_operand:SI 2 "spu_nonmem_operand" "r,O,P,I")))] - "" - "@ - rotqbybi\t%0,%1,%2\;rotqbi\t%0,%0,%2 - rotqbyi\t%0,%1,%h2 - rotqbii\t%0,%1,%e2 - rotqbyi\t%0,%1,%h2\;rotqbii\t%0,%0,%e2" - [(set_attr "length" "8,4,4,8") - (set_attr "type" "multi1,shuf,shuf,multi1")]) - -(define_insn "rotqbybi_ti" - [(set (match_operand:TI 0 "spu_reg_operand" "=r,r") - (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r") - (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I") - (const_int -8))))] - "" - "@ - rotqbybi\t%0,%1,%2 - rotqbyi\t%0,%1,%h2" - [(set_attr "type" "shuf,shuf")]) - -(define_insn "rotqby_ti" - [(set (match_operand:TI 0 "spu_reg_operand" "=r,r") - (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r") - (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I") - (const_int 8))))] - "" - "@ - rotqby\t%0,%1,%2 - rotqbyi\t%0,%1,%f2" - [(set_attr "type" "shuf,shuf")]) - -(define_insn "rotqbi_ti" - [(set (match_operand:TI 0 "spu_reg_operand" "=r,r") - (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r") - (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I") - (const_int 7))))] - "" - "@ - rotqbi\t%0,%1,%2 - rotqbii\t%0,%1,%e2" - [(set_attr "type" "shuf,shuf")]) - - -;; struct extract/insert -;; We handle mem's because GCC will generate invalid SUBREG's -;; and inefficient code. - -(define_expand "extv" - [(set (match_operand:TI 0 "register_operand" "") - (sign_extract:TI (match_operand 1 "nonimmediate_operand" "") - (match_operand:SI 2 "const_int_operand" "") - (match_operand:SI 3 "const_int_operand" "")))] - "" - { - spu_expand_extv (operands, 0); - DONE; - }) - -(define_expand "extzv" - [(set (match_operand:TI 0 "register_operand" "") - (zero_extract:TI (match_operand 1 "nonimmediate_operand" "") - (match_operand:SI 2 "const_int_operand" "") - (match_operand:SI 3 "const_int_operand" "")))] - "" - { - spu_expand_extv (operands, 1); - DONE; - }) - -(define_expand "insv" - [(set (zero_extract (match_operand 0 "nonimmediate_operand" "") - (match_operand:SI 1 "const_int_operand" "") - (match_operand:SI 2 "const_int_operand" "")) - (match_operand 3 "nonmemory_operand" ""))] - "" - { - if (INTVAL (operands[1]) + INTVAL (operands[2]) - > GET_MODE_BITSIZE (GET_MODE (operands[0]))) - FAIL; - spu_expand_insv(operands); - DONE; - }) - -;; Simplify a number of patterns that get generated by extv, extzv, -;; insv, and loads. -(define_insn_and_split "trunc_shr_ti" - [(set (match_operand:QHSI 0 "spu_reg_operand" "=r") - (truncate:QHSI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "0") - (const_int 96)])))] - "" - "#" - "reload_completed" - [(const_int 0)] - { - spu_split_convert (operands); - DONE; - } - [(set_attr "type" "convert") - (set_attr "length" "0")]) - -(define_insn_and_split "trunc_shr_tidi" - [(set (match_operand:DI 0 "spu_reg_operand" "=r") - (truncate:DI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "0") - (const_int 64)])))] - "" - "#" - "reload_completed" - [(const_int 0)] - { - spu_split_convert (operands); - DONE; - } - [(set_attr "type" "convert") - (set_attr "length" "0")]) - -(define_insn_and_split "shl_ext_ti" - [(set (match_operand:TI 0 "spu_reg_operand" "=r") - (ashift:TI (match_operator:TI 2 "extend_operator" [(match_operand:QHSI 1 "spu_reg_operand" "0")]) - (const_int 96)))] - "" - "#" - "reload_completed" - [(const_int 0)] - { - spu_split_convert (operands); - DONE; - } - [(set_attr "type" "convert") - (set_attr "length" "0")]) - -(define_insn_and_split "shl_ext_diti" - [(set (match_operand:TI 0 "spu_reg_operand" "=r") - (ashift:TI (match_operator:TI 2 "extend_operator" [(match_operand:DI 1 "spu_reg_operand" "0")]) - (const_int 64)))] - "" - "#" - "reload_completed" - [(const_int 0)] - { - spu_split_convert (operands); - DONE; - } - [(set_attr "type" "convert") - (set_attr "length" "0")]) - -(define_insn "sext_trunc_lshr_tiqisi" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (sign_extend:SI (truncate:QI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r") - (const_int 120)]))))] - "" - "rotmai\t%0,%1,-24" - [(set_attr "type" "fx3")]) - -(define_insn "zext_trunc_lshr_tiqisi" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (zero_extend:SI (truncate:QI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r") - (const_int 120)]))))] - "" - "rotmi\t%0,%1,-24" - [(set_attr "type" "fx3")]) - -(define_insn "sext_trunc_lshr_tihisi" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (sign_extend:SI (truncate:HI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r") - (const_int 112)]))))] - "" - "rotmai\t%0,%1,-16" - [(set_attr "type" "fx3")]) - -(define_insn "zext_trunc_lshr_tihisi" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (zero_extend:SI (truncate:HI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r") - (const_int 112)]))))] - "" - "rotmi\t%0,%1,-16" - [(set_attr "type" "fx3")]) - - -;; String/block move insn. -;; Argument 0 is the destination -;; Argument 1 is the source -;; Argument 2 is the length -;; Argument 3 is the alignment - -(define_expand "movstrsi" - [(parallel [(set (match_operand:BLK 0 "" "") - (match_operand:BLK 1 "" "")) - (use (match_operand:SI 2 "" "")) - (use (match_operand:SI 3 "" ""))])] - "" - " - { - if (spu_expand_block_move (operands)) - DONE; - else - FAIL; - }") - - -;; jump - -(define_insn "indirect_jump" - [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r"))] - "" - "bi\t%0" - [(set_attr "type" "br")]) - -(define_insn "jump" - [(set (pc) - (label_ref (match_operand 0 "" "")))] - "" - "br\t%0" - [(set_attr "type" "br")]) - - -;; return - -;; This will be used for leaf functions, that don't save any regs and -;; don't have locals on stack, maybe... that is for functions that -;; don't change $sp and don't need to save $lr. -(define_expand "return" - [(return)] - "direct_return()" - "") - -;; used in spu_expand_epilogue to generate return from a function and -;; explicitly set use of $lr. - -(define_insn "_return" - [(return)] - "" - "bi\t$lr" - [(set_attr "type" "br")]) - - - -;; ceq - -(define_insn "ceq_" - [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r") - (eq:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r") - (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))] - "" - "@ - ceq\t%0,%1,%2 - ceqi\t%0,%1,%2") - -(define_insn_and_split "ceq_di" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (eq:SI (match_operand:DI 1 "spu_reg_operand" "r") - (match_operand:DI 2 "spu_reg_operand" "r")))] - "" - "#" - "reload_completed" - [(set (match_dup:SI 0) - (eq:SI (match_dup:DI 1) - (match_dup:DI 2)))] - { - rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0])); - rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1])); - rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2])); - emit_insn (gen_ceq_v4si (op0, op1, op2)); - emit_insn (gen_spu_gb (op0, op0)); - emit_insn (gen_cgt_si (operands[0], operands[0], GEN_INT (11))); - DONE; - }) - - -;; We provide the TI compares for completeness and because some parts of -;; gcc/libgcc use them, even though user code might never see it. -(define_insn "ceq_ti" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (eq:SI (match_operand:TI 1 "spu_reg_operand" "r") - (match_operand:TI 2 "spu_reg_operand" "r")))] - "" - "ceq\t%0,%1,%2\;gb\t%0,%0\;ceqi\t%0,%0,15" - [(set_attr "type" "multi0") - (set_attr "length" "12")]) - -(define_insn "ceq_" - [(set (match_operand: 0 "spu_reg_operand" "=r") - (eq: (match_operand:VSF 1 "spu_reg_operand" "r") - (match_operand:VSF 2 "spu_reg_operand" "r")))] - "" - "fceq\t%0,%1,%2") - -(define_insn "cmeq_" - [(set (match_operand: 0 "spu_reg_operand" "=r") - (eq: (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r")) - (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))] - "" - "fcmeq\t%0,%1,%2") - -;; These implementations will ignore checking of NaN or INF if -;; compiled with option -ffinite-math-only. -(define_expand "ceq_df" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (eq:SI (match_operand:DF 1 "spu_reg_operand" "r") - (match_operand:DF 2 "const_zero_operand" "i")))] - "" -{ - if (spu_arch == PROCESSOR_CELL) - { - rtx ra = gen_reg_rtx (V4SImode); - rtx rb = gen_reg_rtx (V4SImode); - rtx temp = gen_reg_rtx (TImode); - rtx temp_v4si = spu_gen_subreg (V4SImode, temp); - rtx temp2 = gen_reg_rtx (V4SImode); - rtx biteq = gen_reg_rtx (V4SImode); - rtx ahi_inf = gen_reg_rtx (V4SImode); - rtx a_nan = gen_reg_rtx (V4SImode); - rtx a_abs = gen_reg_rtx (V4SImode); - rtx b_abs = gen_reg_rtx (V4SImode); - rtx iszero = gen_reg_rtx (V4SImode); - rtx sign_mask = gen_reg_rtx (V4SImode); - rtx nan_mask = gen_reg_rtx (V4SImode); - rtx hihi_promote = gen_reg_rtx (TImode); - rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF, - 0x7FFFFFFF, 0xFFFFFFFF); - - emit_move_insn (sign_mask, pat); - pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0, - 0x7FF00000, 0x0); - emit_move_insn (nan_mask, pat); - pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213, - 0x08090A0B, 0x18191A1B); - emit_move_insn (hihi_promote, pat); - - emit_insn (gen_spu_convert (ra, operands[1])); - emit_insn (gen_spu_convert (rb, operands[2])); - emit_insn (gen_ceq_v4si (biteq, ra, rb)); - emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq), - GEN_INT (4 * 8))); - emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si)); - - emit_insn (gen_andv4si3 (a_abs, ra, sign_mask)); - emit_insn (gen_andv4si3 (b_abs, rb, sign_mask)); - if (!flag_finite_math_only) - { - emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask)); - emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask)); - emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan), - GEN_INT (4 * 8))); - emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf)); - emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2)); - } - emit_insn (gen_iorv4si3 (temp2, a_abs, b_abs)); - emit_insn (gen_ceq_v4si (iszero, temp2, CONST0_RTX (V4SImode))); - emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero), - GEN_INT (4 * 8))); - emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si)); - emit_insn (gen_iorv4si3 (temp2, biteq, iszero)); - if (!flag_finite_math_only) - { - emit_insn (gen_andc_v4si (temp2, temp2, a_nan)); - } - emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote)); - DONE; - } -}) - -(define_insn "ceq__celledp" - [(set (match_operand: 0 "spu_reg_operand" "=r") - (eq: (match_operand:VDF 1 "spu_reg_operand" "r") - (match_operand:VDF 2 "spu_reg_operand" "r")))] - "spu_arch == PROCESSOR_CELLEDP" - "dfceq\t%0,%1,%2" - [(set_attr "type" "fpd")]) - -(define_insn "cmeq__celledp" - [(set (match_operand: 0 "spu_reg_operand" "=r") - (eq: (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "r")) - (abs:VDF (match_operand:VDF 2 "spu_reg_operand" "r"))))] - "spu_arch == PROCESSOR_CELLEDP" - "dfcmeq\t%0,%1,%2" - [(set_attr "type" "fpd")]) - -(define_expand "ceq_v2df" - [(set (match_operand:V2DI 0 "spu_reg_operand" "=r") - (eq:V2DI (match_operand:V2DF 1 "spu_reg_operand" "r") - (match_operand:V2DF 2 "spu_reg_operand" "r")))] - "" -{ - if (spu_arch == PROCESSOR_CELL) - { - rtx ra = spu_gen_subreg (V4SImode, operands[1]); - rtx rb = spu_gen_subreg (V4SImode, operands[2]); - rtx temp = gen_reg_rtx (TImode); - rtx temp_v4si = spu_gen_subreg (V4SImode, temp); - rtx temp2 = gen_reg_rtx (V4SImode); - rtx biteq = gen_reg_rtx (V4SImode); - rtx ahi_inf = gen_reg_rtx (V4SImode); - rtx a_nan = gen_reg_rtx (V4SImode); - rtx a_abs = gen_reg_rtx (V4SImode); - rtx b_abs = gen_reg_rtx (V4SImode); - rtx iszero = gen_reg_rtx (V4SImode); - rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF, - 0x7FFFFFFF, 0xFFFFFFFF); - rtx sign_mask = gen_reg_rtx (V4SImode); - rtx nan_mask = gen_reg_rtx (V4SImode); - rtx hihi_promote = gen_reg_rtx (TImode); - - emit_move_insn (sign_mask, pat); - pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0, - 0x7FF00000, 0x0); - emit_move_insn (nan_mask, pat); - pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213, - 0x08090A0B, 0x18191A1B); - emit_move_insn (hihi_promote, pat); - - emit_insn (gen_ceq_v4si (biteq, ra, rb)); - emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq), - GEN_INT (4 * 8))); - emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si)); - emit_insn (gen_andv4si3 (a_abs, ra, sign_mask)); - emit_insn (gen_andv4si3 (b_abs, rb, sign_mask)); - emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask)); - emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask)); - emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan), - GEN_INT (4 * 8))); - emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf)); - emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2)); - emit_insn (gen_iorv4si3 (temp2, a_abs, b_abs)); - emit_insn (gen_ceq_v4si (iszero, temp2, CONST0_RTX (V4SImode))); - emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero), - GEN_INT (4 * 8))); - emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si)); - emit_insn (gen_iorv4si3 (temp2, biteq, iszero)); - emit_insn (gen_andc_v4si (temp2, temp2, a_nan)); - emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote)); - DONE; - } -}) - -(define_expand "cmeq_v2df" - [(set (match_operand:V2DI 0 "spu_reg_operand" "=r") - (eq:V2DI (abs:V2DF (match_operand:V2DF 1 "spu_reg_operand" "r")) - (abs:V2DF (match_operand:V2DF 2 "spu_reg_operand" "r"))))] - "" -{ - if (spu_arch == PROCESSOR_CELL) - { - rtx ra = spu_gen_subreg (V4SImode, operands[1]); - rtx rb = spu_gen_subreg (V4SImode, operands[2]); - rtx temp = gen_reg_rtx (TImode); - rtx temp_v4si = spu_gen_subreg (V4SImode, temp); - rtx temp2 = gen_reg_rtx (V4SImode); - rtx biteq = gen_reg_rtx (V4SImode); - rtx ahi_inf = gen_reg_rtx (V4SImode); - rtx a_nan = gen_reg_rtx (V4SImode); - rtx a_abs = gen_reg_rtx (V4SImode); - rtx b_abs = gen_reg_rtx (V4SImode); - - rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF, - 0x7FFFFFFF, 0xFFFFFFFF); - rtx sign_mask = gen_reg_rtx (V4SImode); - rtx nan_mask = gen_reg_rtx (V4SImode); - rtx hihi_promote = gen_reg_rtx (TImode); - - emit_move_insn (sign_mask, pat); - - pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0, - 0x7FF00000, 0x0); - emit_move_insn (nan_mask, pat); - pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213, - 0x08090A0B, 0x18191A1B); - emit_move_insn (hihi_promote, pat); - - emit_insn (gen_andv4si3 (a_abs, ra, sign_mask)); - emit_insn (gen_andv4si3 (b_abs, rb, sign_mask)); - emit_insn (gen_ceq_v4si (biteq, a_abs, b_abs)); - emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq), - GEN_INT (4 * 8))); - emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si)); - emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask)); - emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask)); - emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan), - GEN_INT (4 * 8))); - emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf)); - emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2)); - emit_insn (gen_andc_v4si (temp2, biteq, a_nan)); - emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote)); - DONE; - } -}) - - -;; cgt - -(define_insn "cgt_" - [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r") - (gt:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r") - (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))] - "" - "@ - cgt\t%0,%1,%2 - cgti\t%0,%1,%2") - -(define_insn "cgt_di_m1" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (gt:SI (match_operand:DI 1 "spu_reg_operand" "r") - (const_int -1)))] - "" - "cgti\t%0,%1,-1") - -(define_insn_and_split "cgt_di" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (gt:SI (match_operand:DI 1 "spu_reg_operand" "r") - (match_operand:DI 2 "spu_reg_operand" "r"))) - (clobber (match_scratch:V4SI 3 "=&r")) - (clobber (match_scratch:V4SI 4 "=&r")) - (clobber (match_scratch:V4SI 5 "=&r"))] - "" - "#" - "reload_completed" - [(set (match_dup:SI 0) - (gt:SI (match_dup:DI 1) - (match_dup:DI 2)))] - { - rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0])); - rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1])); - rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2])); - rtx op3 = operands[3]; - rtx op4 = operands[4]; - rtx op5 = operands[5]; - rtx op3d = gen_rtx_REG (V2DImode, REGNO (operands[3])); - emit_insn (gen_clgt_v4si (op3, op1, op2)); - emit_insn (gen_ceq_v4si (op4, op1, op2)); - emit_insn (gen_cgt_v4si (op5, op1, op2)); - emit_insn (gen_spu_xswd (op3d, op3)); - emit_insn (gen_selb (op0, op5, op3, op4)); - DONE; - }) - -(define_insn "cgt_ti_m1" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (gt:SI (match_operand:TI 1 "spu_reg_operand" "r") - (const_int -1)))] - "" - "cgti\t%0,%1,-1") - -(define_insn "cgt_ti" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (gt:SI (match_operand:TI 1 "spu_reg_operand" "r") - (match_operand:TI 2 "spu_reg_operand" "r"))) - (clobber (match_scratch:V4SI 3 "=&r")) - (clobber (match_scratch:V4SI 4 "=&r")) - (clobber (match_scratch:V4SI 5 "=&r"))] - "" - "clgt\t%4,%1,%2\;\ -ceq\t%3,%1,%2\;\ -cgt\t%5,%1,%2\;\ -shlqbyi\t%0,%4,4\;\ -selb\t%0,%4,%0,%3\;\ -shlqbyi\t%0,%0,4\;\ -selb\t%0,%4,%0,%3\;\ -shlqbyi\t%0,%0,4\;\ -selb\t%0,%5,%0,%3" - [(set_attr "type" "multi0") - (set_attr "length" "36")]) - -(define_insn "cgt_" - [(set (match_operand: 0 "spu_reg_operand" "=r") - (gt: (match_operand:VSF 1 "spu_reg_operand" "r") - (match_operand:VSF 2 "spu_reg_operand" "r")))] - "" - "fcgt\t%0,%1,%2") - -(define_insn "cmgt_" - [(set (match_operand: 0 "spu_reg_operand" "=r") - (gt: (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r")) - (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))] - "" - "fcmgt\t%0,%1,%2") - -(define_expand "cgt_df" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (gt:SI (match_operand:DF 1 "spu_reg_operand" "r") - (match_operand:DF 2 "const_zero_operand" "i")))] - "" -{ - if (spu_arch == PROCESSOR_CELL) - { - rtx ra = gen_reg_rtx (V4SImode); - rtx rb = gen_reg_rtx (V4SImode); - rtx zero = gen_reg_rtx (V4SImode); - rtx temp = gen_reg_rtx (TImode); - rtx temp_v4si = spu_gen_subreg (V4SImode, temp); - rtx temp2 = gen_reg_rtx (V4SImode); - rtx hi_inf = gen_reg_rtx (V4SImode); - rtx a_nan = gen_reg_rtx (V4SImode); - rtx b_nan = gen_reg_rtx (V4SImode); - rtx a_abs = gen_reg_rtx (V4SImode); - rtx b_abs = gen_reg_rtx (V4SImode); - rtx asel = gen_reg_rtx (V4SImode); - rtx bsel = gen_reg_rtx (V4SImode); - rtx abor = gen_reg_rtx (V4SImode); - rtx bbor = gen_reg_rtx (V4SImode); - rtx gt_hi = gen_reg_rtx (V4SImode); - rtx gt_lo = gen_reg_rtx (V4SImode); - rtx sign_mask = gen_reg_rtx (V4SImode); - rtx nan_mask = gen_reg_rtx (V4SImode); - rtx hi_promote = gen_reg_rtx (TImode); - rtx borrow_shuffle = gen_reg_rtx (TImode); - - rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF, - 0x7FFFFFFF, 0xFFFFFFFF); - emit_move_insn (sign_mask, pat); - pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0, - 0x7FF00000, 0x0); - emit_move_insn (nan_mask, pat); - pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203, - 0x08090A0B, 0x08090A0B); - emit_move_insn (hi_promote, pat); - pat = spu_const_from_ints (TImode, 0x04050607, 0xC0C0C0C0, - 0x0C0D0E0F, 0xC0C0C0C0); - emit_move_insn (borrow_shuffle, pat); - - emit_insn (gen_spu_convert (ra, operands[1])); - emit_insn (gen_spu_convert (rb, operands[2])); - emit_insn (gen_andv4si3 (a_abs, ra, sign_mask)); - emit_insn (gen_andv4si3 (b_abs, rb, sign_mask)); - - if (!flag_finite_math_only) - { - /* check if ra is NaN */ - emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask)); - emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask)); - emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan), - GEN_INT (4 * 8))); - emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf)); - emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2)); - emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote)); - - /* check if rb is NaN */ - emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask)); - emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask)); - emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan), - GEN_INT (4 * 8))); - emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf)); - emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2)); - emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote)); - - /* check if ra or rb is NaN */ - emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan)); - } - emit_move_insn (zero, CONST0_RTX (V4SImode)); - emit_insn (gen_vashrv4si3 (asel, ra, spu_const (V4SImode, 31))); - emit_insn (gen_shufb (asel, asel, asel, hi_promote)); - emit_insn (gen_bg_v4si (abor, zero, a_abs)); - emit_insn (gen_shufb (abor, abor, abor, borrow_shuffle)); - emit_insn (gen_sfx_v4si (abor, zero, a_abs, abor)); - emit_insn (gen_selb (abor, a_abs, abor, asel)); - - emit_insn (gen_vashrv4si3 (bsel, rb, spu_const (V4SImode, 31))); - emit_insn (gen_shufb (bsel, bsel, bsel, hi_promote)); - emit_insn (gen_bg_v4si (bbor, zero, b_abs)); - emit_insn (gen_shufb (bbor, bbor, bbor, borrow_shuffle)); - emit_insn (gen_sfx_v4si (bbor, zero, b_abs, bbor)); - emit_insn (gen_selb (bbor, b_abs, bbor, bsel)); - - emit_insn (gen_cgt_v4si (gt_hi, abor, bbor)); - emit_insn (gen_clgt_v4si (gt_lo, abor, bbor)); - emit_insn (gen_ceq_v4si (temp2, abor, bbor)); - emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo), - GEN_INT (4 * 8))); - emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si)); - emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2)); - emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote)); - if (!flag_finite_math_only) - { - /* correct for NaNs */ - emit_insn (gen_andc_v4si (temp2, temp2, a_nan)); - } - emit_insn (gen_spu_convert (operands[0], temp2)); - DONE; - } -}) - -(define_insn "cgt__celledp" - [(set (match_operand: 0 "spu_reg_operand" "=r") - (gt: (match_operand:VDF 1 "spu_reg_operand" "r") - (match_operand:VDF 2 "spu_reg_operand" "r")))] - "spu_arch == PROCESSOR_CELLEDP" - "dfcgt\t%0,%1,%2" - [(set_attr "type" "fpd")]) - -(define_insn "cmgt__celledp" - [(set (match_operand: 0 "spu_reg_operand" "=r") - (gt: (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "r")) - (abs:VDF (match_operand:VDF 2 "spu_reg_operand" "r"))))] - "spu_arch == PROCESSOR_CELLEDP" - "dfcmgt\t%0,%1,%2" - [(set_attr "type" "fpd")]) - -(define_expand "cgt_v2df" - [(set (match_operand:V2DI 0 "spu_reg_operand" "=r") - (gt:V2DI (match_operand:V2DF 1 "spu_reg_operand" "r") - (match_operand:V2DF 2 "spu_reg_operand" "r")))] - "" -{ - if (spu_arch == PROCESSOR_CELL) - { - rtx ra = spu_gen_subreg (V4SImode, operands[1]); - rtx rb = spu_gen_subreg (V4SImode, operands[2]); - rtx zero = gen_reg_rtx (V4SImode); - rtx temp = gen_reg_rtx (TImode); - rtx temp_v4si = spu_gen_subreg (V4SImode, temp); - rtx temp2 = gen_reg_rtx (V4SImode); - rtx hi_inf = gen_reg_rtx (V4SImode); - rtx a_nan = gen_reg_rtx (V4SImode); - rtx b_nan = gen_reg_rtx (V4SImode); - rtx a_abs = gen_reg_rtx (V4SImode); - rtx b_abs = gen_reg_rtx (V4SImode); - rtx asel = gen_reg_rtx (V4SImode); - rtx bsel = gen_reg_rtx (V4SImode); - rtx abor = gen_reg_rtx (V4SImode); - rtx bbor = gen_reg_rtx (V4SImode); - rtx gt_hi = gen_reg_rtx (V4SImode); - rtx gt_lo = gen_reg_rtx (V4SImode); - rtx sign_mask = gen_reg_rtx (V4SImode); - rtx nan_mask = gen_reg_rtx (V4SImode); - rtx hi_promote = gen_reg_rtx (TImode); - rtx borrow_shuffle = gen_reg_rtx (TImode); - rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF, - 0x7FFFFFFF, 0xFFFFFFFF); - emit_move_insn (sign_mask, pat); - pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0, - 0x7FF00000, 0x0); - emit_move_insn (nan_mask, pat); - pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203, - 0x08090A0B, 0x08090A0B); - emit_move_insn (hi_promote, pat); - pat = spu_const_from_ints (TImode, 0x04050607, 0xC0C0C0C0, - 0x0C0D0E0F, 0xC0C0C0C0); - emit_move_insn (borrow_shuffle, pat); - - emit_insn (gen_andv4si3 (a_abs, ra, sign_mask)); - emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask)); - emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask)); - emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan), - GEN_INT (4 * 8))); - emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf)); - emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2)); - emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote)); - emit_insn (gen_andv4si3 (b_abs, rb, sign_mask)); - emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask)); - emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask)); - emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan), - GEN_INT (4 * 8))); - emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf)); - emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2)); - emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote)); - emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan)); - emit_move_insn (zero, CONST0_RTX (V4SImode)); - emit_insn (gen_vashrv4si3 (asel, ra, spu_const (V4SImode, 31))); - emit_insn (gen_shufb (asel, asel, asel, hi_promote)); - emit_insn (gen_bg_v4si (abor, zero, a_abs)); - emit_insn (gen_shufb (abor, abor, abor, borrow_shuffle)); - emit_insn (gen_sfx_v4si (abor, zero, a_abs, abor)); - emit_insn (gen_selb (abor, a_abs, abor, asel)); - emit_insn (gen_vashrv4si3 (bsel, rb, spu_const (V4SImode, 31))); - emit_insn (gen_shufb (bsel, bsel, bsel, hi_promote)); - emit_insn (gen_bg_v4si (bbor, zero, b_abs)); - emit_insn (gen_shufb (bbor, bbor, bbor, borrow_shuffle)); - emit_insn (gen_sfx_v4si (bbor, zero, b_abs, bbor)); - emit_insn (gen_selb (bbor, b_abs, bbor, bsel)); - emit_insn (gen_cgt_v4si (gt_hi, abor, bbor)); - emit_insn (gen_clgt_v4si (gt_lo, abor, bbor)); - emit_insn (gen_ceq_v4si (temp2, abor, bbor)); - emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo), - GEN_INT (4 * 8))); - emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si)); - emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2)); - - emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote)); - emit_insn (gen_andc_v4si (temp2, temp2, a_nan)); - emit_move_insn (operands[0], spu_gen_subreg (V2DImode, temp2)); - DONE; - } -}) - -(define_expand "cmgt_v2df" - [(set (match_operand:V2DI 0 "spu_reg_operand" "=r") - (gt:V2DI (abs:V2DF (match_operand:V2DF 1 "spu_reg_operand" "r")) - (abs:V2DF (match_operand:V2DF 2 "spu_reg_operand" "r"))))] - "" -{ - if (spu_arch == PROCESSOR_CELL) - { - rtx ra = spu_gen_subreg (V4SImode, operands[1]); - rtx rb = spu_gen_subreg (V4SImode, operands[2]); - rtx temp = gen_reg_rtx (TImode); - rtx temp_v4si = spu_gen_subreg (V4SImode, temp); - rtx temp2 = gen_reg_rtx (V4SImode); - rtx hi_inf = gen_reg_rtx (V4SImode); - rtx a_nan = gen_reg_rtx (V4SImode); - rtx b_nan = gen_reg_rtx (V4SImode); - rtx a_abs = gen_reg_rtx (V4SImode); - rtx b_abs = gen_reg_rtx (V4SImode); - rtx gt_hi = gen_reg_rtx (V4SImode); - rtx gt_lo = gen_reg_rtx (V4SImode); - rtx sign_mask = gen_reg_rtx (V4SImode); - rtx nan_mask = gen_reg_rtx (V4SImode); - rtx hi_promote = gen_reg_rtx (TImode); - rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF, - 0x7FFFFFFF, 0xFFFFFFFF); - emit_move_insn (sign_mask, pat); - pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0, - 0x7FF00000, 0x0); - emit_move_insn (nan_mask, pat); - pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203, - 0x08090A0B, 0x08090A0B); - emit_move_insn (hi_promote, pat); - - emit_insn (gen_andv4si3 (a_abs, ra, sign_mask)); - emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask)); - emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask)); - emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan), - GEN_INT (4 * 8))); - emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf)); - emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2)); - emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote)); - emit_insn (gen_andv4si3 (b_abs, rb, sign_mask)); - emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask)); - emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask)); - emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan), - GEN_INT (4 * 8))); - emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf)); - emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2)); - emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote)); - emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan)); - - emit_insn (gen_clgt_v4si (gt_hi, a_abs, b_abs)); - emit_insn (gen_clgt_v4si (gt_lo, a_abs, b_abs)); - emit_insn (gen_ceq_v4si (temp2, a_abs, b_abs)); - emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo), - GEN_INT (4 * 8))); - emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si)); - emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2)); - emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote)); - emit_insn (gen_andc_v4si (temp2, temp2, a_nan)); - emit_move_insn (operands[0], spu_gen_subreg (V2DImode, temp2)); - DONE; - } -}) - - -;; clgt - -(define_insn "clgt_" - [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r") - (gtu:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r") - (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))] - "" - "@ - clgt\t%0,%1,%2 - clgti\t%0,%1,%2") - -(define_insn_and_split "clgt_di" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (gtu:SI (match_operand:DI 1 "spu_reg_operand" "r") - (match_operand:DI 2 "spu_reg_operand" "r"))) - (clobber (match_scratch:V4SI 3 "=&r")) - (clobber (match_scratch:V4SI 4 "=&r")) - (clobber (match_scratch:V4SI 5 "=&r"))] - "" - "#" - "reload_completed" - [(set (match_dup:SI 0) - (gtu:SI (match_dup:DI 1) - (match_dup:DI 2)))] - { - rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0])); - rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1])); - rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2])); - rtx op3 = operands[3]; - rtx op4 = operands[4]; - rtx op5 = operands[5]; - rtx op5d = gen_rtx_REG (V2DImode, REGNO (operands[5])); - emit_insn (gen_clgt_v4si (op3, op1, op2)); - emit_insn (gen_ceq_v4si (op4, op1, op2)); - emit_insn (gen_spu_xswd (op5d, op3)); - emit_insn (gen_selb (op0, op3, op5, op4)); - DONE; - }) - -(define_insn "clgt_ti" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (gtu:SI (match_operand:TI 1 "spu_reg_operand" "r") - (match_operand:TI 2 "spu_reg_operand" "r"))) - (clobber (match_scratch:V4SI 3 "=&r")) - (clobber (match_scratch:V4SI 4 "=&r"))] - "" - "ceq\t%3,%1,%2\;\ -clgt\t%4,%1,%2\;\ -shlqbyi\t%0,%4,4\;\ -selb\t%0,%4,%0,%3\;\ -shlqbyi\t%0,%0,4\;\ -selb\t%0,%4,%0,%3\;\ -shlqbyi\t%0,%0,4\;\ -selb\t%0,%4,%0,%3" - [(set_attr "type" "multi0") - (set_attr "length" "32")]) - - -;; dftsv -(define_insn "dftsv_celledp" - [(set (match_operand:V2DI 0 "spu_reg_operand" "=r") - (unspec:V2DI [(match_operand:V2DF 1 "spu_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i")] - UNSPEC_DFTSV))] - "spu_arch == PROCESSOR_CELLEDP" - "dftsv\t%0,%1,%2" - [(set_attr "type" "fpd")]) - -(define_expand "dftsv" - [(set (match_operand:V2DI 0 "spu_reg_operand" "=r") - (unspec:V2DI [(match_operand:V2DF 1 "spu_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i")] - UNSPEC_DFTSV))] - "" -{ - if (spu_arch == PROCESSOR_CELL) - { - rtx result = gen_reg_rtx (V4SImode); - emit_move_insn (result, CONST0_RTX (V4SImode)); - - if (INTVAL (operands[2])) - { - rtx ra = spu_gen_subreg (V4SImode, operands[1]); - rtx abs = gen_reg_rtx (V4SImode); - rtx sign = gen_reg_rtx (V4SImode); - rtx temp = gen_reg_rtx (TImode); - rtx temp_v4si = spu_gen_subreg (V4SImode, temp); - rtx temp2 = gen_reg_rtx (V4SImode); - rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF, - 0x7FFFFFFF, 0xFFFFFFFF); - rtx sign_mask = gen_reg_rtx (V4SImode); - rtx hi_promote = gen_reg_rtx (TImode); - emit_move_insn (sign_mask, pat); - pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203, - 0x08090A0B, 0x08090A0B); - emit_move_insn (hi_promote, pat); - - emit_insn (gen_vashrv4si3 (sign, ra, spu_const (V4SImode, 31))); - emit_insn (gen_shufb (sign, sign, sign, hi_promote)); - emit_insn (gen_andv4si3 (abs, ra, sign_mask)); - - /* NaN or +inf or -inf */ - if (INTVAL (operands[2]) & 0x70) - { - rtx nan_mask = gen_reg_rtx (V4SImode); - rtx isinf = gen_reg_rtx (V4SImode); - pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0, - 0x7FF00000, 0x0); - emit_move_insn (nan_mask, pat); - emit_insn (gen_ceq_v4si (isinf, abs, nan_mask)); - - /* NaN */ - if (INTVAL (operands[2]) & 0x40) - { - rtx isnan = gen_reg_rtx (V4SImode); - emit_insn (gen_clgt_v4si (isnan, abs, nan_mask)); - emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, isnan), - GEN_INT (4 * 8))); - emit_insn (gen_andv4si3 (temp2, temp_v4si, isinf)); - emit_insn (gen_iorv4si3 (isnan, isnan, temp2)); - emit_insn (gen_shufb (isnan, isnan, isnan, hi_promote)); - emit_insn (gen_iorv4si3 (result, result, isnan)); - } - /* +inf or -inf */ - if (INTVAL (operands[2]) & 0x30) - { - emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, isinf), - GEN_INT (4 * 8))); - emit_insn (gen_andv4si3 (isinf, isinf, temp_v4si)); - emit_insn (gen_shufb (isinf, isinf, isinf, hi_promote)); - - /* +inf */ - if (INTVAL (operands[2]) & 0x20) - { - emit_insn (gen_andc_v4si (temp2, isinf, sign)); - emit_insn (gen_iorv4si3 (result, result, temp2)); - } - /* -inf */ - if (INTVAL (operands[2]) & 0x10) - { - emit_insn (gen_andv4si3 (temp2, isinf, sign)); - emit_insn (gen_iorv4si3 (result, result, temp2)); - } - } - } - - /* 0 or denorm */ - if (INTVAL (operands[2]) & 0xF) - { - rtx iszero = gen_reg_rtx (V4SImode); - emit_insn (gen_ceq_v4si (iszero, abs, CONST0_RTX (V4SImode))); - emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero), - GEN_INT (4 * 8))); - emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si)); - - /* denorm */ - if (INTVAL (operands[2]) & 0x3) - { - rtx isdenorm = gen_reg_rtx (V4SImode); - rtx denorm_mask = gen_reg_rtx (V4SImode); - emit_move_insn (denorm_mask, spu_const (V4SImode, 0xFFFFF)); - emit_insn (gen_clgt_v4si (isdenorm, abs, denorm_mask)); - emit_insn (gen_nor_v4si (isdenorm, isdenorm, iszero)); - emit_insn (gen_shufb (isdenorm, isdenorm, - isdenorm, hi_promote)); - /* +denorm */ - if (INTVAL (operands[2]) & 0x2) - { - emit_insn (gen_andc_v4si (temp2, isdenorm, sign)); - emit_insn (gen_iorv4si3 (result, result, temp2)); - } - /* -denorm */ - if (INTVAL (operands[2]) & 0x1) - { - emit_insn (gen_andv4si3 (temp2, isdenorm, sign)); - emit_insn (gen_iorv4si3 (result, result, temp2)); - } - } - - /* 0 */ - if (INTVAL (operands[2]) & 0xC) - { - emit_insn (gen_shufb (iszero, iszero, iszero, hi_promote)); - /* +0 */ - if (INTVAL (operands[2]) & 0x8) - { - emit_insn (gen_andc_v4si (temp2, iszero, sign)); - emit_insn (gen_iorv4si3 (result, result, temp2)); - } - /* -0 */ - if (INTVAL (operands[2]) & 0x4) - { - emit_insn (gen_andv4si3 (temp2, iszero, sign)); - emit_insn (gen_iorv4si3 (result, result, temp2)); - } - } - } - } - emit_move_insn (operands[0], spu_gen_subreg (V2DImode, result)); - DONE; - } -}) - - -;; branches - -(define_insn "" - [(set (pc) - (if_then_else (match_operator 1 "branch_comparison_operator" - [(match_operand 2 - "spu_reg_operand" "r") - (const_int 0)]) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "br%b2%b1z\t%2,%0" - [(set_attr "type" "br")]) - -(define_insn "" - [(set (pc) - (if_then_else (match_operator 0 "branch_comparison_operator" - [(match_operand 1 - "spu_reg_operand" "r") - (const_int 0)]) - (return) - (pc)))] - "direct_return ()" - "bi%b1%b0z\t%1,$lr" - [(set_attr "type" "br")]) - -(define_insn "" - [(set (pc) - (if_then_else (match_operator 1 "branch_comparison_operator" - [(match_operand 2 - "spu_reg_operand" "r") - (const_int 0)]) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "br%b2%b1z\t%2,%0" - [(set_attr "type" "br")]) - -(define_insn "" - [(set (pc) - (if_then_else (match_operator 0 "branch_comparison_operator" - [(match_operand 1 - "spu_reg_operand" "r") - (const_int 0)]) - (pc) - (return)))] - "direct_return ()" - "bi%b1%b0z\t%1,$lr" - [(set_attr "type" "br")]) - - -;; vector conditional compare patterns -(define_expand "vcond" - [(set (match_operand:VCMP 0 "spu_reg_operand" "=r") - (if_then_else:VCMP - (match_operator 3 "comparison_operator" - [(match_operand:VCMP 4 "spu_reg_operand" "r") - (match_operand:VCMP 5 "spu_reg_operand" "r")]) - (match_operand:VCMP 1 "spu_reg_operand" "r") - (match_operand:VCMP 2 "spu_reg_operand" "r")))] - "" - { - if (spu_emit_vector_cond_expr (operands[0], operands[1], operands[2], - operands[3], operands[4], operands[5])) - DONE; - else - FAIL; - }) - -(define_expand "vcondu" - [(set (match_operand:VCMPU 0 "spu_reg_operand" "=r") - (if_then_else:VCMPU - (match_operator 3 "comparison_operator" - [(match_operand:VCMPU 4 "spu_reg_operand" "r") - (match_operand:VCMPU 5 "spu_reg_operand" "r")]) - (match_operand:VCMPU 1 "spu_reg_operand" "r") - (match_operand:VCMPU 2 "spu_reg_operand" "r")))] - "" - { - if (spu_emit_vector_cond_expr (operands[0], operands[1], operands[2], - operands[3], operands[4], operands[5])) - DONE; - else - FAIL; - }) - - -;; branch on condition - -(define_expand "cbranch4" - [(use (match_operator 0 "ordered_comparison_operator" - [(match_operand:VQHSI 1 "spu_reg_operand" "") - (match_operand:VQHSI 2 "spu_nonmem_operand" "")])) - (use (match_operand 3 ""))] - "" - { spu_emit_branch_or_set (0, operands[0], operands); DONE; }) - -(define_expand "cbranch4" - [(use (match_operator 0 "ordered_comparison_operator" - [(match_operand:DTI 1 "spu_reg_operand" "") - (match_operand:DTI 2 "spu_reg_operand" "")])) - (use (match_operand 3 ""))] - "" - { spu_emit_branch_or_set (0, operands[0], operands); DONE; }) - -(define_expand "cbranch4" - [(use (match_operator 0 "ordered_comparison_operator" - [(match_operand:VSF 1 "spu_reg_operand" "") - (match_operand:VSF 2 "spu_reg_operand" "")])) - (use (match_operand 3 ""))] - "" - { spu_emit_branch_or_set (0, operands[0], operands); DONE; }) - -(define_expand "cbranchdf4" - [(use (match_operator 0 "ordered_comparison_operator" - [(match_operand:DF 1 "spu_reg_operand" "") - (match_operand:DF 2 "spu_reg_operand" "")])) - (use (match_operand 3 ""))] - "" - { spu_emit_branch_or_set (0, operands[0], operands); DONE; }) - - -;; set on condition - -(define_expand "cstore4" - [(use (match_operator 1 "ordered_comparison_operator" - [(match_operand:VQHSI 2 "spu_reg_operand" "") - (match_operand:VQHSI 3 "spu_nonmem_operand" "")])) - (clobber (match_operand:SI 0 "spu_reg_operand"))] - "" - { spu_emit_branch_or_set (1, operands[1], operands); DONE; }) - -(define_expand "cstore4" - [(use (match_operator 1 "ordered_comparison_operator" - [(match_operand:DTI 2 "spu_reg_operand" "") - (match_operand:DTI 3 "spu_reg_operand" "")])) - (clobber (match_operand:SI 0 "spu_reg_operand"))] - "" - { spu_emit_branch_or_set (1, operands[1], operands); DONE; }) - -(define_expand "cstore4" - [(use (match_operator 1 "ordered_comparison_operator" - [(match_operand:VSF 2 "spu_reg_operand" "") - (match_operand:VSF 3 "spu_reg_operand" "")])) - (clobber (match_operand:SI 0 "spu_reg_operand"))] - "" - { spu_emit_branch_or_set (1, operands[1], operands); DONE; }) - -(define_expand "cstoredf4" - [(use (match_operator 1 "ordered_comparison_operator" - [(match_operand:DF 2 "spu_reg_operand" "") - (match_operand:DF 3 "spu_reg_operand" "")])) - (clobber (match_operand:SI 0 "spu_reg_operand"))] - "" - { spu_emit_branch_or_set (1, operands[1], operands); DONE; }) - - -;; conditional move - -;; Define this first one so HAVE_conditional_move is defined. -(define_insn "movcc_dummy" - [(set (match_operand 0 "" "") - (if_then_else (match_operand 1 "" "") - (match_operand 2 "" "") - (match_operand 3 "" "")))] - "!operands[0]" - "") - -(define_expand "movcc" - [(set (match_operand:ALL 0 "spu_reg_operand" "") - (if_then_else:ALL (match_operand 1 "ordered_comparison_operator" "") - (match_operand:ALL 2 "spu_reg_operand" "") - (match_operand:ALL 3 "spu_reg_operand" "")))] - "" - { - spu_emit_branch_or_set(2, operands[1], operands); - DONE; - }) - -;; This pattern is used when the result of a compare is not large -;; enough to use in a selb when expanding conditional moves. -(define_expand "extend_compare" - [(set (match_operand 0 "spu_reg_operand" "=r") - (unspec [(match_operand 1 "spu_reg_operand" "r")] UNSPEC_EXTEND_CMP))] - "" - { - emit_insn (gen_rtx_SET (operands[0], - gen_rtx_UNSPEC (GET_MODE (operands[0]), - gen_rtvec (1, operands[1]), - UNSPEC_EXTEND_CMP))); - DONE; - }) - -(define_insn "extend_compare" - [(set (match_operand:ALL 0 "spu_reg_operand" "=r") - (unspec:ALL [(match_operand 1 "spu_reg_operand" "r")] UNSPEC_EXTEND_CMP))] - "operands != NULL" - "fsm\t%0,%1" - [(set_attr "type" "shuf")]) - - -;; case - -;; operand 0 is index -;; operand 1 is the minimum bound -;; operand 2 is the maximum bound - minimum bound + 1 -;; operand 3 is CODE_LABEL for the table; -;; operand 4 is the CODE_LABEL to go to if index out of range. -(define_expand "casesi" - [(match_operand:SI 0 "spu_reg_operand" "") - (match_operand:SI 1 "immediate_operand" "") - (match_operand:SI 2 "immediate_operand" "") - (match_operand 3 "" "") - (match_operand 4 "" "")] - "" - { - rtx table = gen_reg_rtx (SImode); - rtx index = gen_reg_rtx (SImode); - rtx sindex = gen_reg_rtx (SImode); - rtx addr = gen_reg_rtx (Pmode); - - emit_move_insn (table, gen_rtx_LABEL_REF (SImode, operands[3])); - - emit_insn (gen_subsi3(index, operands[0], force_reg(SImode, operands[1]))); - emit_insn (gen_ashlsi3(sindex, index, GEN_INT (2))); - emit_move_insn (addr, gen_rtx_MEM (SImode, - gen_rtx_PLUS (SImode, table, sindex))); - if (flag_pic) - emit_insn (gen_addsi3 (addr, addr, table)); - - emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1, operands[4]); - emit_jump_insn (gen_tablejump (addr, operands[3])); - DONE; - }) - -(define_insn "tablejump" - [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r")) - (use (label_ref (match_operand 1 "" "")))] - "" - "bi\t%0" - [(set_attr "type" "br")]) - - -;; call - -;; Note that operand 1 is total size of args, in bytes, -;; and what the call insn wants is the number of words. -(define_expand "sibcall" - [(parallel - [(call (match_operand:QI 0 "call_operand" "") - (match_operand:QI 1 "" "")) - (use (reg:SI 0))])] - "" - { - if (! call_operand (operands[0], QImode)) - XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); - }) - -(define_insn "_sibcall" - [(parallel - [(call (match_operand:QI 0 "call_operand" "R,S") - (match_operand:QI 1 "" "i,i")) - (use (reg:SI 0))])] - "SIBLING_CALL_P(insn)" - "@ - bi\t%i0 - br\t%0" - [(set_attr "type" "br,br")]) - -(define_expand "sibcall_value" - [(parallel - [(set (match_operand 0 "" "") - (call (match_operand:QI 1 "call_operand" "") - (match_operand:QI 2 "" ""))) - (use (reg:SI 0))])] - "" - { - if (! call_operand (operands[1], QImode)) - XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); - }) - -(define_insn "_sibcall_value" - [(parallel - [(set (match_operand 0 "" "") - (call (match_operand:QI 1 "call_operand" "R,S") - (match_operand:QI 2 "" "i,i"))) - (use (reg:SI 0))])] - "SIBLING_CALL_P(insn)" - "@ - bi\t%i1 - br\t%1" - [(set_attr "type" "br,br")]) - -;; Note that operand 1 is total size of args, in bytes, -;; and what the call insn wants is the number of words. -(define_expand "call" - [(parallel - [(call (match_operand:QI 0 "call_operand" "") - (match_operand:QI 1 "" "")) - (clobber (reg:SI 0)) - (clobber (reg:SI 130))])] - "" - { - if (! call_operand (operands[0], QImode)) - XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); - }) - -(define_insn "_call" - [(parallel - [(call (match_operand:QI 0 "call_operand" "R,S,T") - (match_operand:QI 1 "" "i,i,i")) - (clobber (reg:SI 0)) - (clobber (reg:SI 130))])] - "" - "@ - bisl\t$lr,%i0 - brsl\t$lr,%0 - brasl\t$lr,%0" - [(set_attr "type" "br")]) - -(define_expand "call_value" - [(parallel - [(set (match_operand 0 "" "") - (call (match_operand:QI 1 "call_operand" "") - (match_operand:QI 2 "" ""))) - (clobber (reg:SI 0)) - (clobber (reg:SI 130))])] - "" - { - if (! call_operand (operands[1], QImode)) - XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); - }) - -(define_insn "_call_value" - [(parallel - [(set (match_operand 0 "" "") - (call (match_operand:QI 1 "call_operand" "R,S,T") - (match_operand:QI 2 "" "i,i,i"))) - (clobber (reg:SI 0)) - (clobber (reg:SI 130))])] - "" - "@ - bisl\t$lr,%i1 - brsl\t$lr,%1 - brasl\t$lr,%1" - [(set_attr "type" "br")]) - -(define_expand "untyped_call" - [(parallel [(call (match_operand 0 "" "") - (const_int 0)) - (match_operand 1 "" "") - (match_operand 2 "" "")])] - "" - { - int i; - rtx reg = gen_rtx_REG (TImode, 3); - - /* We need to use call_value so the return value registers don't get - * clobbered. */ - emit_call_insn (gen_call_value (reg, operands[0], const0_rtx)); - - for (i = 0; i < XVECLEN (operands[2], 0); i++) - { - rtx set = XVECEXP (operands[2], 0, i); - emit_move_insn (SET_DEST (set), SET_SRC (set)); - } - - /* The optimizer does not know that the call sets the function value - registers we stored in the result block. We avoid problems by - claiming that all hard registers are used and clobbered at this - point. */ - emit_insn (gen_blockage ()); - - DONE; - }) - - -;; Patterns used for splitting and combining. - - -;; Function prologue and epilogue. - -(define_expand "prologue" - [(const_int 1)] - "" - { spu_expand_prologue (); DONE; }) - -;; "blockage" is only emitted in epilogue. This is what it took to -;; make "basic block reordering" work with the insns sequence -;; generated by the spu_expand_epilogue (taken from mips.md) - -(define_insn "blockage" - [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] - "" - "" - [(set_attr "type" "convert") - (set_attr "length" "0")]) - -(define_expand "epilogue" - [(const_int 2)] - "" - { spu_expand_epilogue (false); DONE; }) - -(define_expand "sibcall_epilogue" - [(const_int 2)] - "" - { spu_expand_epilogue (true); DONE; }) - - -;; stack manipulations - -;; An insn to allocate new stack space for dynamic use (e.g., alloca). -;; We move the back-chain and decrement the stack pointer. -(define_expand "allocate_stack" - [(set (match_operand 0 "spu_reg_operand" "") - (minus (reg 1) (match_operand 1 "spu_nonmem_operand" ""))) - (set (reg 1) - (minus (reg 1) (match_dup 1)))] - "" - "spu_allocate_stack (operands[0], operands[1]); DONE;") - -;; These patterns say how to save and restore the stack pointer. We need not -;; save the stack pointer at function level since we are careful to preserve -;; the backchain. -;; - -;; At block level the stack pointer is saved and restored, so that the -;; stack space allocated within a block is deallocated when leaving -;; block scope. By default, according to the SPU ABI, the stack -;; pointer and available stack size are saved in a register. Upon -;; restoration, the stack pointer is simply copied back, and the -;; current available stack size is calculated against the restored -;; stack pointer. -;; -;; For nonlocal gotos, we must save the stack pointer and its -;; backchain and restore both. Note that in the nonlocal case, the -;; save area is a memory location. - -(define_expand "save_stack_function" - [(match_operand 0 "general_operand" "") - (match_operand 1 "general_operand" "")] - "" - "DONE;") - -(define_expand "restore_stack_function" - [(match_operand 0 "general_operand" "") - (match_operand 1 "general_operand" "")] - "" - "DONE;") - -(define_expand "restore_stack_block" - [(match_operand 0 "spu_reg_operand" "") - (match_operand 1 "memory_operand" "")] - "" - " - { - spu_restore_stack_block (operands[0], operands[1]); - DONE; - }") - -(define_expand "save_stack_nonlocal" - [(match_operand 0 "memory_operand" "") - (match_operand 1 "spu_reg_operand" "")] - "" - " - { - rtx temp = gen_reg_rtx (Pmode); - - /* Copy the backchain to the first word, sp to the second. We need to - save the back chain because __builtin_apply appears to clobber it. */ - emit_move_insn (temp, gen_rtx_MEM (Pmode, operands[1])); - emit_move_insn (adjust_address_nv (operands[0], SImode, 0), temp); - emit_move_insn (adjust_address_nv (operands[0], SImode, 4), operands[1]); - DONE; - }") - -(define_expand "restore_stack_nonlocal" - [(match_operand 0 "spu_reg_operand" "") - (match_operand 1 "memory_operand" "")] - "" - " - { - spu_restore_stack_nonlocal(operands[0], operands[1]); - DONE; - }") - - -;; vector patterns - -;; Vector initialization -(define_expand "vec_init" - [(match_operand:V 0 "register_operand" "") - (match_operand 1 "" "")] - "" - { - spu_expand_vector_init (operands[0], operands[1]); - DONE; - }) - -(define_expand "vec_set" - [(use (match_operand:SI 2 "spu_nonmem_operand" "")) - (set (match_dup:TI 3) - (unspec:TI [(match_dup:SI 4) - (match_dup:SI 5) - (match_dup:SI 6)] UNSPEC_CPAT)) - (set (match_operand:V 0 "spu_reg_operand" "") - (unspec:V [(match_operand: 1 "spu_reg_operand" "") - (match_dup:V 0) - (match_dup:TI 3)] UNSPEC_SHUFB))] - "" - { - HOST_WIDE_INT size = GET_MODE_SIZE (mode); - rtx offset = GEN_INT (INTVAL (operands[2]) * size); - operands[3] = gen_reg_rtx (TImode); - operands[4] = stack_pointer_rtx; - operands[5] = offset; - operands[6] = GEN_INT (size); - }) - -(define_expand "vec_extract" - [(set (match_operand: 0 "spu_reg_operand" "=r") - (vec_select: (match_operand:V 1 "spu_reg_operand" "r") - (parallel [(match_operand 2 "const_int_operand" "i")])))] - "" - { - if ((INTVAL (operands[2]) * + ) % 16 == 0) - { - emit_insn (gen_spu_convert (operands[0], operands[1])); - DONE; - } - }) - -(define_insn "_vec_extract" - [(set (match_operand: 0 "spu_reg_operand" "=r") - (vec_select: (match_operand:V 1 "spu_reg_operand" "r") - (parallel [(match_operand 2 "const_int_operand" "i")])))] - "" - "rotqbyi\t%0,%1,(%2*+)%%16" - [(set_attr "type" "shuf")]) - -(define_insn "_vec_extractv8hi_ze" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (zero_extend:SI (vec_select:HI (match_operand:V8HI 1 "spu_reg_operand" "r") - (parallel [(const_int 0)]))))] - "" - "rotqmbyi\t%0,%1,-2" - [(set_attr "type" "shuf")]) - - -;; misc - -(define_expand "shufb" - [(set (match_operand 0 "spu_reg_operand" "") - (unspec [(match_operand 1 "spu_reg_operand" "") - (match_operand 2 "spu_reg_operand" "") - (match_operand:TI 3 "spu_reg_operand" "")] UNSPEC_SHUFB))] - "" - { - rtx s = gen__shufb (operands[0], operands[1], operands[2], operands[3]); - PUT_MODE (SET_SRC (s), GET_MODE (operands[0])); - emit_insn (s); - DONE; - }) - -(define_insn "_shufb" - [(set (match_operand 0 "spu_reg_operand" "=r") - (unspec [(match_operand 1 "spu_reg_operand" "r") - (match_operand 2 "spu_reg_operand" "r") - (match_operand:TI 3 "spu_reg_operand" "r")] UNSPEC_SHUFB))] - "operands != NULL" - "shufb\t%0,%1,%2,%3" - [(set_attr "type" "shuf")]) - -; The semantics of vec_permv16qi are nearly identical to those of the SPU -; shufb instruction, except that we need to reduce the selector modulo 32. -(define_expand "vec_permv16qi" - [(set (match_dup 4) (and:V16QI (match_operand:V16QI 3 "spu_reg_operand" "") - (match_dup 6))) - (set (match_operand:V16QI 0 "spu_reg_operand" "") - (unspec:V16QI - [(match_operand:V16QI 1 "spu_reg_operand" "") - (match_operand:V16QI 2 "spu_reg_operand" "") - (match_dup 5)] - UNSPEC_SHUFB))] - "" - { - operands[4] = gen_reg_rtx (V16QImode); - operands[5] = gen_lowpart (TImode, operands[4]); - operands[6] = spu_const (V16QImode, 31); - }) - -(define_insn "nop" - [(unspec_volatile [(const_int 0)] UNSPECV_NOP)] - "" - "nop" - [(set_attr "type" "nop")]) - -(define_insn "nopn" - [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "K")] UNSPECV_NOP)] - "" - "nop\t%0" - [(set_attr "type" "nop")]) - -(define_insn "lnop" - [(unspec_volatile [(const_int 0)] UNSPECV_LNOP)] - "" - "lnop" - [(set_attr "type" "lnop")]) - -;; The operand is so we know why we generated this hbrp. -;; We clobber mem to make sure it isn't moved over any -;; loads, stores or calls while scheduling. -(define_insn "iprefetch" - [(unspec [(match_operand:SI 0 "const_int_operand" "n")] UNSPEC_IPREFETCH) - (clobber (mem:BLK (scratch)))] - "" - "hbrp\t# %0" - [(set_attr "type" "iprefetch")]) - -;; A non-volatile version so it gets scheduled -(define_insn "nopn_nv" - [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_NOP)] - "" - "nop\t%0" - [(set_attr "type" "nop")]) - -(define_insn "hbr" - [(set (reg:SI 130) - (unspec:SI [(match_operand:SI 0 "immediate_operand" "i,i,i") - (match_operand:SI 1 "nonmemory_operand" "r,s,i")] UNSPEC_HBR)) - (unspec [(const_int 0)] UNSPEC_HBR)] - "" - "@ - hbr\t%0,%1 - hbrr\t%0,%1 - hbra\t%0,%1" - [(set_attr "type" "hbr")]) - -(define_insn "sync" - [(unspec_volatile [(const_int 0)] UNSPECV_SYNC) - (clobber (mem:BLK (scratch)))] - "" - "sync" - [(set_attr "type" "br")]) - -(define_insn "syncc" - [(unspec_volatile [(const_int 1)] UNSPECV_SYNC) - (clobber (mem:BLK (scratch)))] - "" - "syncc" - [(set_attr "type" "br")]) - -(define_insn "dsync" - [(unspec_volatile [(const_int 2)] UNSPECV_SYNC) - (clobber (mem:BLK (scratch)))] - "" - "dsync" - [(set_attr "type" "br")]) - - - - ;; Define the subtract-one-and-jump insns so loop.c - ;; knows what to generate. - (define_expand "doloop_end" - [(use (match_operand 0 "" "")) ; loop pseudo - (use (match_operand 1 "" ""))] ; label - "" - " - { - /* Currently SMS relies on the do-loop pattern to recognize loops - where (1) the control part comprises of all insns defining and/or - using a certain 'count' register and (2) the loop count can be - adjusted by modifying this register prior to the loop. -. ??? The possible introduction of a new block to initialize the - new IV can potentially effects branch optimizations. */ - if (optimize > 0 && flag_modulo_sched) - { - rtx s0; - rtx bcomp; - rtx loc_ref; - - if (GET_MODE (operands[0]) != SImode) - FAIL; - - s0 = operands [0]; - emit_move_insn (s0, gen_rtx_PLUS (SImode, s0, GEN_INT (-1))); - bcomp = gen_rtx_NE(SImode, s0, const0_rtx); - loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]); - emit_jump_insn (gen_rtx_SET (pc_rtx, - gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp, - loc_ref, pc_rtx))); - - DONE; - }else - FAIL; - }") - -;; convert between any two modes, avoiding any GCC assumptions -(define_expand "spu_convert" - [(set (match_operand 0 "spu_reg_operand" "") - (unspec [(match_operand 1 "spu_reg_operand" "")] UNSPEC_CONVERT))] - "" - { - rtx c = gen__spu_convert (operands[0], operands[1]); - PUT_MODE (SET_SRC (c), GET_MODE (operands[0])); - emit_insn (c); - DONE; - }) - -(define_insn_and_split "_spu_convert" - [(set (match_operand 0 "spu_reg_operand" "=r") - (unspec [(match_operand 1 "spu_reg_operand" "0")] UNSPEC_CONVERT))] - "" - "#" - "reload_completed" - [(const_int 0)] - { - spu_split_convert (operands); - DONE; - } - [(set_attr "type" "convert") - (set_attr "length" "0")]) - - -;; -(include "spu-builtins.md") - - -(define_expand "smaxv4sf3" - [(set (match_operand:V4SF 0 "register_operand" "=r") - (smax:V4SF (match_operand:V4SF 1 "register_operand" "r") - (match_operand:V4SF 2 "register_operand" "r")))] - "" - " -{ - rtx mask = gen_reg_rtx (V4SImode); - - emit_insn (gen_cgt_v4sf (mask, operands[1], operands[2])); - emit_insn (gen_selb (operands[0], operands[2], operands[1], mask)); - DONE; -}") - -(define_expand "sminv4sf3" - [(set (match_operand:V4SF 0 "register_operand" "=r") - (smin:V4SF (match_operand:V4SF 1 "register_operand" "r") - (match_operand:V4SF 2 "register_operand" "r")))] - "" - " -{ - rtx mask = gen_reg_rtx (V4SImode); - - emit_insn (gen_cgt_v4sf (mask, operands[1], operands[2])); - emit_insn (gen_selb (operands[0], operands[1], operands[2], mask)); - DONE; -}") - -(define_expand "smaxv2df3" - [(set (match_operand:V2DF 0 "register_operand" "=r") - (smax:V2DF (match_operand:V2DF 1 "register_operand" "r") - (match_operand:V2DF 2 "register_operand" "r")))] - "" - " -{ - rtx mask = gen_reg_rtx (V2DImode); - emit_insn (gen_cgt_v2df (mask, operands[1], operands[2])); - emit_insn (gen_selb (operands[0], operands[2], operands[1], - spu_gen_subreg (V4SImode, mask))); - DONE; -}") - -(define_expand "sminv2df3" - [(set (match_operand:V2DF 0 "register_operand" "=r") - (smin:V2DF (match_operand:V2DF 1 "register_operand" "r") - (match_operand:V2DF 2 "register_operand" "r")))] - "" - " -{ - rtx mask = gen_reg_rtx (V2DImode); - emit_insn (gen_cgt_v2df (mask, operands[1], operands[2])); - emit_insn (gen_selb (operands[0], operands[1], operands[2], - spu_gen_subreg (V4SImode, mask))); - DONE; -}") - -(define_insn "vec_widen_smult_odd_v8hi" - [(set (match_operand:V4SI 0 "spu_reg_operand" "=r,r") - (mult:V4SI - (sign_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 1 "spu_reg_operand" "r,r") - (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))) - (sign_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 2 "spu_arith_operand" "r,B") - (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))))] - "" - "@ - mpy\t%0,%1,%2 - mpyi\t%0,%1,%2" - [(set_attr "type" "fp7")]) - -(define_insn "vec_widen_umult_odd_v8hi" - [(set (match_operand:V4SI 0 "spu_reg_operand" "=r,r") - (mult:V4SI - (zero_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 1 "spu_reg_operand" "r,r") - (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))) - (zero_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 2 "spu_arith_operand" "r,B") - (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))))] - "" - "@ - mpyu\t%0,%1,%2 - mpyui\t%0,%1,%2" - [(set_attr "type" "fp7")]) - -(define_insn "vec_widen_smult_even_v8hi" - [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") - (mult:V4SI - (sign_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 1 "spu_reg_operand" "r") - (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))) - (sign_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 2 "spu_reg_operand" "r") - (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))))] - "" - "mpyhh\t%0,%1,%2" - [(set_attr "type" "fp7")]) - -(define_insn "vec_widen_umult_even_v8hi" - [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") - (mult:V4SI - (zero_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 1 "spu_reg_operand" "r") - (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))) - (zero_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 2 "spu_reg_operand" "r") - (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))))] - "" - "mpyhhu\t%0,%1,%2" - [(set_attr "type" "fp7")]) - -(define_expand "vec_widen_umult_hi_v8hi" - [(set (match_operand:V4SI 0 "register_operand" "=r") - (mult:V4SI - (zero_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 1 "register_operand" "r") - (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))) - (zero_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 2 "register_operand" "r") - (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))))] - "" - " -{ - rtx ve = gen_reg_rtx (V4SImode); - rtx vo = gen_reg_rtx (V4SImode); - rtx mask = gen_reg_rtx (TImode); - unsigned char arr[16] = { - 0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13, - 0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17}; - - emit_move_insn (mask, array_to_constant (TImode, arr)); - emit_insn (gen_vec_widen_umult_even_v8hi (ve, operands[1], operands[2])); - emit_insn (gen_vec_widen_umult_odd_v8hi (vo, operands[1], operands[2])); - emit_insn (gen_shufb (operands[0], ve, vo, mask)); - DONE; -}") - -(define_expand "vec_widen_umult_lo_v8hi" - [(set (match_operand:V4SI 0 "register_operand" "=r") - (mult:V4SI - (zero_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 1 "register_operand" "r") - (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))) - (zero_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 2 "register_operand" "r") - (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))))] - "" - " -{ - rtx ve = gen_reg_rtx (V4SImode); - rtx vo = gen_reg_rtx (V4SImode); - rtx mask = gen_reg_rtx (TImode); - unsigned char arr[16] = { - 0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B, - 0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F}; - - emit_move_insn (mask, array_to_constant (TImode, arr)); - emit_insn (gen_vec_widen_umult_even_v8hi (ve, operands[1], operands[2])); - emit_insn (gen_vec_widen_umult_odd_v8hi (vo, operands[1], operands[2])); - emit_insn (gen_shufb (operands[0], ve, vo, mask)); - DONE; -}") - -(define_expand "vec_widen_smult_hi_v8hi" - [(set (match_operand:V4SI 0 "register_operand" "=r") - (mult:V4SI - (sign_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 1 "register_operand" "r") - (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))) - (sign_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 2 "register_operand" "r") - (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))))] - "" - " -{ - rtx ve = gen_reg_rtx (V4SImode); - rtx vo = gen_reg_rtx (V4SImode); - rtx mask = gen_reg_rtx (TImode); - unsigned char arr[16] = { - 0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13, - 0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17}; - - emit_move_insn (mask, array_to_constant (TImode, arr)); - emit_insn (gen_vec_widen_smult_even_v8hi (ve, operands[1], operands[2])); - emit_insn (gen_vec_widen_smult_odd_v8hi (vo, operands[1], operands[2])); - emit_insn (gen_shufb (operands[0], ve, vo, mask)); - DONE; -}") - -(define_expand "vec_widen_smult_lo_v8hi" - [(set (match_operand:V4SI 0 "register_operand" "=r") - (mult:V4SI - (sign_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 1 "register_operand" "r") - (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))) - (sign_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 2 "register_operand" "r") - (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))))] - "" - " -{ - rtx ve = gen_reg_rtx (V4SImode); - rtx vo = gen_reg_rtx (V4SImode); - rtx mask = gen_reg_rtx (TImode); - unsigned char arr[16] = { - 0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B, - 0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F}; - - emit_move_insn (mask, array_to_constant (TImode, arr)); - emit_insn (gen_vec_widen_smult_even_v8hi (ve, operands[1], operands[2])); - emit_insn (gen_vec_widen_smult_odd_v8hi (vo, operands[1], operands[2])); - emit_insn (gen_shufb (operands[0], ve, vo, mask)); - DONE; -}") - -(define_expand "vec_realign_load_" - [(set (match_operand:ALL 0 "register_operand" "=r") - (unspec:ALL [(match_operand:ALL 1 "register_operand" "r") - (match_operand:ALL 2 "register_operand" "r") - (match_operand:TI 3 "register_operand" "r")] UNSPEC_SPU_REALIGN_LOAD))] - "" - " -{ - emit_insn (gen_shufb (operands[0], operands[1], operands[2], operands[3])); - DONE; -}") - -(define_expand "spu_lvsr" - [(set (match_operand:V16QI 0 "register_operand" "") - (unspec:V16QI [(match_operand 1 "memory_operand" "")] UNSPEC_SPU_MASK_FOR_LOAD))] - "" - " -{ - rtx addr; - rtx offset = gen_reg_rtx (V8HImode); - rtx addr_bits = gen_reg_rtx (SImode); - rtx addr_bits_vec = gen_reg_rtx (V8HImode); - rtx splatqi = gen_reg_rtx (TImode); - rtx result = gen_reg_rtx (V8HImode); - unsigned char arr[16] = { - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; - unsigned char arr2[16] = { - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03}; - - emit_move_insn (offset, array_to_constant (V8HImode, arr)); - emit_move_insn (splatqi, array_to_constant (TImode, arr2)); - - gcc_assert (GET_CODE (operands[1]) == MEM); - addr = force_reg (Pmode, XEXP (operands[1], 0)); - emit_insn (gen_andsi3 (addr_bits, addr, GEN_INT (0xF))); - emit_insn (gen_shufb (addr_bits_vec, addr_bits, addr_bits, splatqi)); - - /* offset - (addr & 0xF) - It is safe to use a single sfh, because each byte of offset is > 15 and - each byte of addr is <= 15. */ - emit_insn (gen_subv8hi3 (result, offset, addr_bits_vec)); - - result = simplify_gen_subreg (V16QImode, result, V8HImode, 0); - emit_move_insn (operands[0], result); - - DONE; -}") - -(define_expand "vec_unpacku_hi_v8hi" - [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") - (zero_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 1 "spu_reg_operand" "r") - (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))] - "" -{ - rtx mask = gen_reg_rtx (TImode); - unsigned char arr[16] = { - 0x80, 0x80, 0x00, 0x01, 0x80, 0x80, 0x02, 0x03, - 0x80, 0x80, 0x04, 0x05, 0x80, 0x80, 0x06, 0x07}; - - emit_move_insn (mask, array_to_constant (TImode, arr)); - emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask)); - - DONE; -}) - -(define_expand "vec_unpacku_lo_v8hi" - [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") - (zero_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 1 "spu_reg_operand" "r") - (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))] -"" -{ - rtx mask = gen_reg_rtx (TImode); - unsigned char arr[16] = { - 0x80, 0x80, 0x08, 0x09, 0x80, 0x80, 0x0A, 0x0B, - 0x80, 0x80, 0x0C, 0x0D, 0x80, 0x80, 0x0E, 0x0F}; - - emit_move_insn (mask, array_to_constant (TImode, arr)); - emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask)); - - DONE; -}) - -(define_expand "vec_unpacks_hi_v8hi" - [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") - (sign_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 1 "spu_reg_operand" "r") - (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))] - "" -{ - rtx tmp1 = gen_reg_rtx (V8HImode); - rtx tmp2 = gen_reg_rtx (V4SImode); - rtx mask = gen_reg_rtx (TImode); - unsigned char arr[16] = { - 0x80, 0x80, 0x00, 0x01, 0x80, 0x80, 0x02, 0x03, - 0x80, 0x80, 0x04, 0x05, 0x80, 0x80, 0x06, 0x07}; - - emit_move_insn (mask, array_to_constant (TImode, arr)); - emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask)); - emit_insn (gen_spu_xshw (tmp2, tmp1)); - emit_move_insn (operands[0], tmp2); - - DONE; -}) - -(define_expand "vec_unpacks_lo_v8hi" - [(set (match_operand:V4SI 0 "spu_reg_operand" "=r") - (sign_extend:V4SI - (vec_select:V4HI - (match_operand:V8HI 1 "spu_reg_operand" "r") - (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))] -"" -{ - rtx tmp1 = gen_reg_rtx (V8HImode); - rtx tmp2 = gen_reg_rtx (V4SImode); - rtx mask = gen_reg_rtx (TImode); - unsigned char arr[16] = { - 0x80, 0x80, 0x08, 0x09, 0x80, 0x80, 0x0A, 0x0B, - 0x80, 0x80, 0x0C, 0x0D, 0x80, 0x80, 0x0E, 0x0F}; - - emit_move_insn (mask, array_to_constant (TImode, arr)); - emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask)); - emit_insn (gen_spu_xshw (tmp2, tmp1)); - emit_move_insn (operands[0], tmp2); - -DONE; -}) - -(define_expand "vec_unpacku_hi_v16qi" - [(set (match_operand:V8HI 0 "spu_reg_operand" "=r") - (zero_extend:V8HI - (vec_select:V8QI - (match_operand:V16QI 1 "spu_reg_operand" "r") - (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3) - (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))] - "" -{ - rtx mask = gen_reg_rtx (TImode); - unsigned char arr[16] = { - 0x80, 0x00, 0x80, 0x01, 0x80, 0x02, 0x80, 0x03, - 0x80, 0x04, 0x80, 0x05, 0x80, 0x06, 0x80, 0x07}; - - emit_move_insn (mask, array_to_constant (TImode, arr)); - emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask)); - - DONE; -}) - -(define_expand "vec_unpacku_lo_v16qi" - [(set (match_operand:V8HI 0 "spu_reg_operand" "=r") - (zero_extend:V8HI - (vec_select:V8QI - (match_operand:V16QI 1 "spu_reg_operand" "r") - (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11) - (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))] -"" -{ - rtx mask = gen_reg_rtx (TImode); - unsigned char arr[16] = { - 0x80, 0x08, 0x80, 0x09, 0x80, 0x0A, 0x80, 0x0B, - 0x80, 0x0C, 0x80, 0x0D, 0x80, 0x0E, 0x80, 0x0F}; - - emit_move_insn (mask, array_to_constant (TImode, arr)); - emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask)); - - DONE; -}) - -(define_expand "vec_unpacks_hi_v16qi" - [(set (match_operand:V8HI 0 "spu_reg_operand" "=r") - (sign_extend:V8HI - (vec_select:V8QI - (match_operand:V16QI 1 "spu_reg_operand" "r") - (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3) - (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))] -"" -{ - rtx tmp1 = gen_reg_rtx (V16QImode); - rtx tmp2 = gen_reg_rtx (V8HImode); - rtx mask = gen_reg_rtx (TImode); - unsigned char arr[16] = { - 0x80, 0x00, 0x80, 0x01, 0x80, 0x02, 0x80, 0x03, - 0x80, 0x04, 0x80, 0x05, 0x80, 0x06, 0x80, 0x07}; - - emit_move_insn (mask, array_to_constant (TImode, arr)); - emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask)); - emit_insn (gen_spu_xsbh (tmp2, tmp1)); - emit_move_insn (operands[0], tmp2); - - DONE; -}) - -(define_expand "vec_unpacks_lo_v16qi" - [(set (match_operand:V8HI 0 "spu_reg_operand" "=r") - (sign_extend:V8HI - (vec_select:V8QI - (match_operand:V16QI 1 "spu_reg_operand" "r") - (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11) - (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))] -"" -{ - rtx tmp1 = gen_reg_rtx (V16QImode); - rtx tmp2 = gen_reg_rtx (V8HImode); - rtx mask = gen_reg_rtx (TImode); - unsigned char arr[16] = { - 0x80, 0x08, 0x80, 0x09, 0x80, 0x0A, 0x80, 0x0B, - 0x80, 0x0C, 0x80, 0x0D, 0x80, 0x0E, 0x80, 0x0F}; - - emit_move_insn (mask, array_to_constant (TImode, arr)); - emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask)); - emit_insn (gen_spu_xsbh (tmp2, tmp1)); - emit_move_insn (operands[0], tmp2); - -DONE; -}) - - -(define_expand "vec_pack_trunc_v8hi" - [(set (match_operand:V16QI 0 "spu_reg_operand" "=r") - (vec_concat:V16QI - (truncate:V8QI (match_operand:V8HI 1 "spu_reg_operand" "r")) - (truncate:V8QI (match_operand:V8HI 2 "spu_reg_operand" "r"))))] - "" - " -{ - rtx mask = gen_reg_rtx (TImode); - unsigned char arr[16] = { - 0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F, - 0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F}; - - emit_move_insn (mask, array_to_constant (TImode, arr)); - emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask)); - - DONE; -}") - -(define_expand "vec_pack_trunc_v4si" - [(set (match_operand:V8HI 0 "spu_reg_operand" "=r") - (vec_concat:V8HI - (truncate:V4HI (match_operand:V4SI 1 "spu_reg_operand" "r")) - (truncate:V4HI (match_operand:V4SI 2 "spu_reg_operand" "r"))))] - "" - " -{ - rtx mask = gen_reg_rtx (TImode); - unsigned char arr[16] = { - 0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F, - 0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F}; - - emit_move_insn (mask, array_to_constant (TImode, arr)); - emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask)); - - DONE; -}") - -(define_insn "stack_protect_set" - [(set (match_operand:SI 0 "memory_operand" "=m") - (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET)) - (set (match_scratch:SI 2 "=&r") (const_int 0))] - "" - "lq%p1\t%2,%1\;stq%p0\t%2,%0\;xor\t%2,%2,%2" - [(set_attr "length" "12") - (set_attr "type" "multi1")] -) - -(define_expand "stack_protect_test" - [(match_operand 0 "memory_operand" "") - (match_operand 1 "memory_operand" "") - (match_operand 2 "" "")] - "" -{ - rtx compare_result; - rtx bcomp, loc_ref; - - compare_result = gen_reg_rtx (SImode); - - emit_insn (gen_stack_protect_test_si (compare_result, - operands[0], - operands[1])); - - bcomp = gen_rtx_NE (SImode, compare_result, const0_rtx); - - loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[2]); - - emit_jump_insn (gen_rtx_SET (pc_rtx, - gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp, - loc_ref, pc_rtx))); - - DONE; -}) - -(define_insn "stack_protect_test_si" - [(set (match_operand:SI 0 "spu_reg_operand" "=&r") - (unspec:SI [(match_operand:SI 1 "memory_operand" "m") - (match_operand:SI 2 "memory_operand" "m")] - UNSPEC_SP_TEST)) - (set (match_scratch:SI 3 "=&r") (const_int 0))] - "" - "lq%p1\t%0,%1\;lq%p2\t%3,%2\;ceq\t%0,%0,%3\;xor\t%3,%3,%3" - [(set_attr "length" "16") - (set_attr "type" "multi1")] -) - -; Atomic operations -; -; SPU execution is always single-threaded, so there is no need for real -; atomic operations. We provide the atomic primitives anyway so that -; code expecting the builtins to be present (like libgfortran) will work. - -;; Types that we should provide atomic instructions for. -(define_mode_iterator AINT [QI HI SI DI TI]) - -(define_code_iterator ATOMIC [plus minus ior xor and mult]) -(define_code_attr atomic_name - [(plus "add") (minus "sub") - (ior "or") (xor "xor") (and "and") (mult "nand")]) -(define_code_attr atomic_pred - [(plus "spu_arith_operand") (minus "spu_reg_operand") - (ior "spu_logical_operand") (xor "spu_logical_operand") - (and "spu_logical_operand") (mult "spu_logical_operand")]) - -(define_expand "atomic_load" - [(set (match_operand:AINT 0 "spu_reg_operand" "") ;; output - (match_operand:AINT 1 "memory_operand" "")) ;; memory - (use (match_operand:SI 2 "const_int_operand" ""))] ;; model - "" -{ - if (MEM_ADDR_SPACE (operands[1])) - FAIL; - - emit_move_insn (operands[0], operands[1]); - DONE; -}) - -(define_expand "atomic_store" - [(set (match_operand:AINT 0 "memory_operand" "") ;; memory - (match_operand:AINT 1 "spu_reg_operand" "")) ;; input - (use (match_operand:SI 2 "const_int_operand" ""))] ;; model - "" -{ - if (MEM_ADDR_SPACE (operands[0])) - FAIL; - - emit_move_insn (operands[0], operands[1]); - DONE; -}) - -(define_expand "atomic_compare_and_swap" - [(match_operand:SI 0 "spu_reg_operand" "") ;; bool out - (match_operand:AINT 1 "spu_reg_operand" "") ;; val out - (match_operand:AINT 2 "memory_operand" "") ;; memory - (match_operand:AINT 3 "spu_nonmem_operand" "") ;; expected - (match_operand:AINT 4 "spu_nonmem_operand" "") ;; desired - (match_operand:SI 5 "const_int_operand" "") ;; is_weak - (match_operand:SI 6 "const_int_operand" "") ;; model succ - (match_operand:SI 7 "const_int_operand" "")] ;; model fail - "" -{ - rtx boolval, retval, label; - - if (MEM_ADDR_SPACE (operands[2])) - FAIL; - - boolval = gen_reg_rtx (SImode); - retval = gen_reg_rtx (mode); - label = gen_label_rtx (); - - emit_move_insn (retval, operands[2]); - emit_move_insn (boolval, const0_rtx); - - emit_cmp_and_jump_insns (retval, operands[3], NE, NULL_RTX, - mode, 1, label); - - emit_move_insn (operands[2], operands[4]); - emit_move_insn (boolval, const1_rtx); - - emit_label (label); - - emit_move_insn (operands[0], boolval); - emit_move_insn (operands[1], retval); - DONE; -}) - -(define_expand "atomic_exchange" - [(match_operand:AINT 0 "spu_reg_operand" "") ;; output - (match_operand:AINT 1 "memory_operand" "") ;; memory - (match_operand:AINT 2 "spu_nonmem_operand" "") ;; input - (match_operand:SI 3 "const_int_operand" "")] ;; model - "" -{ - rtx retval; - - if (MEM_ADDR_SPACE (operands[1])) - FAIL; - - retval = gen_reg_rtx (mode); - - emit_move_insn (retval, operands[1]); - emit_move_insn (operands[1], operands[2]); - emit_move_insn (operands[0], retval); - DONE; -}) - -(define_expand "atomic_" - [(ATOMIC:AINT - (match_operand:AINT 0 "memory_operand" "") ;; memory - (match_operand:AINT 1 "" "")) ;; operand - (match_operand:SI 2 "const_int_operand" "")] ;; model - "" -{ - if (MEM_ADDR_SPACE (operands[0])) - FAIL; - - spu_expand_atomic_op (, operands[0], operands[1], - NULL_RTX, NULL_RTX); - DONE; -}) - -(define_expand "atomic_fetch_" - [(match_operand:AINT 0 "spu_reg_operand" "") ;; output - (ATOMIC:AINT - (match_operand:AINT 1 "memory_operand" "") ;; memory - (match_operand:AINT 2 "" "")) ;; operand - (match_operand:SI 3 "const_int_operand" "")] ;; model - "" -{ - if (MEM_ADDR_SPACE (operands[1])) - FAIL; - - spu_expand_atomic_op (, operands[1], operands[2], - operands[0], NULL_RTX); - DONE; -}) - -(define_expand "atomic__fetch" - [(match_operand:AINT 0 "spu_reg_operand" "") ;; output - (ATOMIC:AINT - (match_operand:AINT 1 "memory_operand" "") ;; memory - (match_operand:AINT 2 "" "")) ;; operand - (match_operand:SI 3 "const_int_operand" "")] ;; model - "" -{ - if (MEM_ADDR_SPACE (operands[1])) - FAIL; - - spu_expand_atomic_op (, operands[1], operands[2], - NULL_RTX, operands[0]); - DONE; -}) - diff --git a/gcc/config/spu/spu.opt b/gcc/config/spu/spu.opt deleted file mode 100644 index 9eb18cc..0000000 --- a/gcc/config/spu/spu.opt +++ /dev/null @@ -1,105 +0,0 @@ -; Options for the SPU port of the compiler -; Copyright (C) 2006-2019 Free Software Foundation, Inc. - -; This file is free software; you can redistribute it and/or modify it under -; the terms of the GNU General Public License as published by the Free -; Software Foundation; either version 3 of the License, or (at your option) -; any later version. - -; This file is distributed in the hope that it will be useful, but WITHOUT -; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -; for more details. -; -; You should have received a copy of the GNU General Public License -; along with GCC; see the file COPYING3. If not see -; . - -mwarn-reloc -Target Report Mask(WARN_RELOC) -Emit warnings when run-time relocations are generated. - -merror-reloc -Target Report Mask(ERROR_RELOC) -Emit errors when run-time relocations are generated. - -mbranch-cost= -Target RejectNegative Joined UInteger Var(spu_branch_cost) Init(20) -Specify cost of branches (Default 20). - -msafe-dma -Target Report RejectNegative Mask(SAFE_DMA) -Make sure loads and stores are not moved past DMA instructions. - -munsafe-dma -Target Report RejectNegative InverseMask(SAFE_DMA) -volatile must be specified on any memory that is effected by DMA. - -mdual-nops -Target Report Var(spu_dual_nops,10) Init(10) -Insert nops when it might improve performance by allowing dual issue (default). - -mdual-nops= -Target RejectNegative Joined UInteger Var(spu_dual_nops) -Insert nops when it might improve performance by allowing dual issue (default). - -mstdmain -Target Report Mask(STD_MAIN) -Use standard main function as entry for startup. - -mbranch-hints -Target Report Mask(BRANCH_HINTS) -Generate branch hints for branches. - -mhint-max-nops= -Target RejectNegative Joined UInteger Var(spu_max_nops) Init(2) -Maximum number of nops to insert for a hint (Default 2). - -mhint-max-distance= -Target RejectNegative Joined Var(spu_max_distance_str) -Approximate maximum number of instructions to allow between a hint and its branch [125]. - -msmall-mem -Target Report RejectNegative InverseMask(LARGE_MEM) -Generate code for 18 bit addressing. - -mlarge-mem -Target Report RejectNegative Mask(LARGE_MEM) -Generate code for 32 bit addressing. - -mfixed-range= -Target RejectNegative Joined Var(spu_fixed_range_string) -Specify range of registers to make fixed. - -msafe-hints -Target Report Mask(SAFE_HINTS) -Insert hbrp instructions after hinted branch targets to avoid the SPU hang issue. - -march= -Target RejectNegative Joined Var(spu_arch_string) -Generate code for given CPU. - -mtune= -Target RejectNegative Joined Var(spu_tune_string) -Schedule code for given CPU. - -mea32 -Target Report RejectNegative Var(spu_ea_model,32) Init(32) -Access variables in 32-bit PPU objects (default). - -mea64 -Target Report RejectNegative Var(spu_ea_model,64) -Access variables in 64-bit PPU objects. - -maddress-space-conversion -Target Report Mask(ADDRESS_SPACE_CONVERSION) -Allow conversions between __ea and generic pointers (default). - -mcache-size= -Target Report RejectNegative Joined UInteger -Size (in KB) of software data cache. - -matomic-updates -Target Report -Atomically write back software data cache lines (default). - diff --git a/gcc/config/spu/spu_cache.h b/gcc/config/spu/spu_cache.h deleted file mode 100644 index cb6fe31..0000000 --- a/gcc/config/spu/spu_cache.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (C) 2008-2019 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - . */ - -#ifndef _SPU_CACHE_H -#define _SPU_CACHE_H - -void *__cache_fetch_dirty (__ea void *ea, int n_bytes_dirty); -void *__cache_fetch (__ea void *ea); -void __cache_evict (__ea void *ea); -void __cache_flush (void); -void __cache_touch (__ea void *ea); - -#define cache_fetch_dirty(_ea, _n_bytes_dirty) \ - __cache_fetch_dirty(_ea, _n_bytes_dirty) - -#define cache_fetch(_ea) __cache_fetch(_ea) -#define cache_touch(_ea) __cache_touch(_ea) -#define cache_evict(_ea) __cache_evict(_ea) -#define cache_flush() __cache_flush() - -#endif diff --git a/gcc/config/spu/spu_internals.h b/gcc/config/spu/spu_internals.h deleted file mode 100644 index fb23b4a..0000000 --- a/gcc/config/spu/spu_internals.h +++ /dev/null @@ -1,421 +0,0 @@ -/* Definitions of Synergistic Processing Unit (SPU). */ -/* Copyright (C) 2006-2019 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - . */ - -#ifndef _SPU_INTERNALS_H -#define _SPU_INTERNALS_H - -/* For a typical GCC implementation, the vector keyword is defined here - * as a macro. If this macro conflicts with user code the user needs to - * undefine it. An extended GCC implementation may implement this - * keyword differently, such that it never conflicts, and will define - * the macro __VECTOR_KEYWORD_SUPPORTED__. */ -#ifndef __VECTOR_KEYWORD_SUPPORTED__ -#define vector __vector -#endif - - -/* The spu specific instruction macros, si_*(), correspond 1-1 with - * SPU instructions in the ISA. The arguments are the same with the - * following exceptions: - * - any instruction which both reads and writes rt will have an - * extra parameter in the macro. - * - instructions which append zero to the immediate field assume - * the value given in a macro already has the zeroes appended. - * - integer/float convert functions expect a value from 0 to 127, - * i.e., the bias is added by the compiler. - * - * Parameters named 'imm' accept an integer literal. - * Parameters named 'r[abcdt]' accept a qword argument. - * Parameters named 'scalar' accept a scalar argument. - */ - -#define qword __vector signed char - -#define si_lqd(ra,imm) __builtin_si_lqd(ra,imm) -#define si_lqx(ra,rb) __builtin_si_lqx(ra,rb) -#define si_lqa(imm) __builtin_si_lqa(imm) -#define si_lqr(imm) __builtin_si_lqr(imm) -#define si_stqd(rt,ra,imm) __builtin_si_stqd(rt,ra,imm) -#define si_stqx(rt,ra,rb) __builtin_si_stqx(rt,ra,rb) -#define si_stqa(rt,imm) __builtin_si_stqa(rt,imm) -#define si_stqr(rt,imm) __builtin_si_stqr(rt,imm) -#define si_cbd(ra,imm) __builtin_si_cbd(ra,imm) -#define si_cbx(ra,rb) __builtin_si_cbx(ra,rb) -#define si_chd(ra,imm) __builtin_si_chd(ra,imm) -#define si_chx(ra,rb) __builtin_si_chx(ra,rb) -#define si_cwd(ra,imm) __builtin_si_cwd(ra,imm) -#define si_cwx(ra,rb) __builtin_si_cwx(ra,rb) -#define si_cdd(ra,imm) __builtin_si_cdd(ra,imm) -#define si_cdx(ra,rb) __builtin_si_cdx(ra,rb) -#define si_ilh(imm) __builtin_si_ilh(imm) -#define si_ilhu(imm) __builtin_si_ilhu(imm) -#define si_il(imm) __builtin_si_il(imm) -#define si_ila(imm) __builtin_si_ila(imm) -#define si_iohl(ra,imm) __builtin_si_iohl(ra,imm) -#define si_fsmbi(imm) __builtin_si_fsmbi(imm) -#define si_ah(ra,rb) __builtin_si_ah(ra,rb) -#define si_ahi(ra,imm) __builtin_si_ahi(ra,imm) -#define si_a(ra,rb) __builtin_si_a(ra,rb) -#define si_ai(ra,imm) __builtin_si_ai(ra,imm) -#define si_addx(ra,rb,rt) __builtin_si_addx(ra,rb,rt) -#define si_cg(ra,rb) __builtin_si_cg(ra,rb) -#define si_cgx(ra,rb,rt) __builtin_si_cgx(ra,rb,rt) -#define si_sfh(ra,rb) __builtin_si_sfh(ra,rb) -#define si_sfhi(imm,ra) __builtin_si_sfhi(imm,ra) -#define si_sf(ra,rb) __builtin_si_sf(ra,rb) -#define si_sfi(ra,imm) __builtin_si_sfi(ra,imm) -#define si_sfx(ra,rb,rt) __builtin_si_sfx(ra,rb,rt) -#define si_bg(ra,rb) __builtin_si_bg(ra,rb) -#define si_bgx(ra,rb,rt) __builtin_si_bgx(ra,rb,rt) -#define si_mpy(ra,rb) __builtin_si_mpy(ra,rb) -#define si_mpyu(ra,rb) __builtin_si_mpyu(ra,rb) -#define si_mpyi(ra,imm) __builtin_si_mpyi(ra,imm) -#define si_mpyui(ra,imm) __builtin_si_mpyui(ra,imm) -#define si_mpya(ra,rb,rc) __builtin_si_mpya(ra,rb,rc) -#define si_mpyh(ra,rb) __builtin_si_mpyh(ra,rb) -#define si_mpys(ra,rb) __builtin_si_mpys(ra,rb) -#define si_mpyhh(ra,rb) __builtin_si_mpyhh(ra,rb) -#define si_mpyhhu(ra,rb) __builtin_si_mpyhhu(ra,rb) -#define si_mpyhha(ra,rb,rc) __builtin_si_mpyhha(ra,rb,rc) -#define si_mpyhhau(ra,rb,rc) __builtin_si_mpyhhau(ra,rb,rc) -#define si_clz(ra) __builtin_si_clz(ra) -#define si_cntb(ra) __builtin_si_cntb(ra) -#define si_fsmb(ra) __builtin_si_fsmb(ra) -#define si_fsmh(ra) __builtin_si_fsmh(ra) -#define si_fsm(ra) __builtin_si_fsm(ra) -#define si_gbb(ra) __builtin_si_gbb(ra) -#define si_gbh(ra) __builtin_si_gbh(ra) -#define si_gb(ra) __builtin_si_gb(ra) -#define si_avgb(ra,rb) __builtin_si_avgb(ra,rb) -#define si_absdb(ra,rb) __builtin_si_absdb(ra,rb) -#define si_sumb(ra,rb) __builtin_si_sumb(ra,rb) -#define si_xsbh(ra) __builtin_si_xsbh(ra) -#define si_xshw(ra) __builtin_si_xshw(ra) -#define si_xswd(ra) __builtin_si_xswd(ra) -#define si_and(ra,rb) __builtin_si_and(ra,rb) -#define si_andc(ra,rb) __builtin_si_andc(ra,rb) -#define si_andbi(ra,imm) __builtin_si_andbi(ra,imm) -#define si_andhi(ra,imm) __builtin_si_andhi(ra,imm) -#define si_andi(ra,imm) __builtin_si_andi(ra,imm) -#define si_or(ra,rb) __builtin_si_or(ra,rb) -#define si_orc(ra,rb) __builtin_si_orc(ra,rb) -#define si_orbi(ra,imm) __builtin_si_orbi(ra,imm) -#define si_orhi(ra,imm) __builtin_si_orhi(ra,imm) -#define si_ori(ra,imm) __builtin_si_ori(ra,imm) -#define si_orx(ra) __builtin_si_orx(ra) -#define si_xor(ra,rb) __builtin_si_xor(ra,rb) -#define si_xorbi(ra,imm) __builtin_si_xorbi(ra,imm) -#define si_xorhi(ra,imm) __builtin_si_xorhi(ra,imm) -#define si_xori(ra,imm) __builtin_si_xori(ra,imm) -#define si_nand(ra,rb) __builtin_si_nand(ra,rb) -#define si_nor(ra,rb) __builtin_si_nor(ra,rb) -#define si_eqv(ra,rb) __builtin_si_eqv(ra,rb) -#define si_selb(ra,rb,rc) __builtin_si_selb(ra,rb,rc) -#define si_shufb(ra,rb,rc) __builtin_si_shufb(ra,rb,rc) -#define si_shlh(ra,rb) __builtin_si_shlh(ra,rb) -#define si_shlhi(ra,imm) __builtin_si_shlhi(ra,imm) -#define si_shl(ra,rb) __builtin_si_shl(ra,rb) -#define si_shli(ra,imm) __builtin_si_shli(ra,imm) -#define si_shlqbi(ra,rb) __builtin_si_shlqbi(ra,rb) -#define si_shlqbii(ra,imm) __builtin_si_shlqbii(ra,imm) -#define si_shlqby(ra,rb) __builtin_si_shlqby(ra,rb) -#define si_shlqbyi(ra,imm) __builtin_si_shlqbyi(ra,imm) -#define si_shlqbybi(ra,rb) __builtin_si_shlqbybi(ra,rb) -#define si_roth(ra,rb) __builtin_si_roth(ra,rb) -#define si_rothi(ra,imm) __builtin_si_rothi(ra,imm) -#define si_rot(ra,rb) __builtin_si_rot(ra,rb) -#define si_roti(ra,imm) __builtin_si_roti(ra,imm) -#define si_rotqby(ra,rb) __builtin_si_rotqby(ra,rb) -#define si_rotqbyi(ra,imm) __builtin_si_rotqbyi(ra,imm) -#define si_rotqbybi(ra,rb) __builtin_si_rotqbybi(ra,rb) -#define si_rotqbi(ra,rb) __builtin_si_rotqbi(ra,rb) -#define si_rotqbii(ra,imm) __builtin_si_rotqbii(ra,imm) -#define si_rothm(ra,rb) __builtin_si_rothm(ra,rb) -#define si_rothmi(ra,imm) __builtin_si_rothmi(ra,imm) -#define si_rotm(ra,rb) __builtin_si_rotm(ra,rb) -#define si_rotmi(ra,imm) __builtin_si_rotmi(ra,imm) -#define si_rotqmby(ra,rb) __builtin_si_rotqmby(ra,rb) -#define si_rotqmbyi(ra,imm) __builtin_si_rotqmbyi(ra,imm) -#define si_rotqmbi(ra,rb) __builtin_si_rotqmbi(ra,rb) -#define si_rotqmbii(ra,imm) __builtin_si_rotqmbii(ra,imm) -#define si_rotqmbybi(ra,rb) __builtin_si_rotqmbybi(ra,rb) -#define si_rotmah(ra,rb) __builtin_si_rotmah(ra,rb) -#define si_rotmahi(ra,imm) __builtin_si_rotmahi(ra,imm) -#define si_rotma(ra,rb) __builtin_si_rotma(ra,rb) -#define si_rotmai(ra,imm) __builtin_si_rotmai(ra,imm) -#define si_heq(ra,rb) __builtin_si_heq(ra,rb) -#define si_heqi(ra,imm) __builtin_si_heqi(ra,imm) -#define si_hgt(ra,rb) __builtin_si_hgt(ra,rb) -#define si_hgti(ra,imm) __builtin_si_hgti(ra,imm) -#define si_hlgt(ra,rb) __builtin_si_hlgt(ra,rb) -#define si_hlgti(ra,imm) __builtin_si_hlgti(ra,imm) -#define si_ceqb(ra,rb) __builtin_si_ceqb(ra,rb) -#define si_ceqbi(ra,imm) __builtin_si_ceqbi(ra,imm) -#define si_ceqh(ra,rb) __builtin_si_ceqh(ra,rb) -#define si_ceqhi(ra,imm) __builtin_si_ceqhi(ra,imm) -#define si_ceq(ra,rb) __builtin_si_ceq(ra,rb) -#define si_ceqi(ra,imm) __builtin_si_ceqi(ra,imm) -#define si_cgtb(ra,rb) __builtin_si_cgtb(ra,rb) -#define si_cgtbi(ra,imm) __builtin_si_cgtbi(ra,imm) -#define si_cgth(ra,rb) __builtin_si_cgth(ra,rb) -#define si_cgthi(ra,imm) __builtin_si_cgthi(ra,imm) -#define si_cgt(ra,rb) __builtin_si_cgt(ra,rb) -#define si_cgti(ra,imm) __builtin_si_cgti(ra,imm) -#define si_clgtb(ra,rb) __builtin_si_clgtb(ra,rb) -#define si_clgtbi(ra,imm) __builtin_si_clgtbi(ra,imm) -#define si_clgth(ra,rb) __builtin_si_clgth(ra,rb) -#define si_clgthi(ra,imm) __builtin_si_clgthi(ra,imm) -#define si_clgt(ra,rb) __builtin_si_clgt(ra,rb) -#define si_clgti(ra,imm) __builtin_si_clgti(ra,imm) -#define si_bisled(ra) __builtin_si_bisled(ra,0) -#define si_bisledd(ra) __builtin_si_bisledd(ra,0) -#define si_bislede(ra) __builtin_si_bislede(ra,0) -#define si_fa(ra,rb) __builtin_si_fa(ra,rb) -#define si_dfa(ra,rb) __builtin_si_dfa(ra,rb) -#define si_fs(ra,rb) __builtin_si_fs(ra,rb) -#define si_dfs(ra,rb) __builtin_si_dfs(ra,rb) -#define si_fm(ra,rb) __builtin_si_fm(ra,rb) -#define si_dfm(ra,rb) __builtin_si_dfm(ra,rb) -#define si_fma(ra,rb,rc) __builtin_si_fma(ra,rb,rc) -#define si_dfma(ra,rb,rc) __builtin_si_dfma(ra,rb,rc) -#define si_dfnma(ra,rb,rc) __builtin_si_dfnma(ra,rb,rc) -#define si_fnms(ra,rb,rc) __builtin_si_fnms(ra,rb,rc) -#define si_dfnms(ra,rb,rc) __builtin_si_dfnms(ra,rb,rc) -#define si_fms(ra,rb,rc) __builtin_si_fms(ra,rb,rc) -#define si_dfms(ra,rb,rc) __builtin_si_dfms(ra,rb,rc) -#define si_frest(ra) __builtin_si_frest(ra) -#define si_frsqest(ra) __builtin_si_frsqest(ra) -#define si_fi(ra,rb) __builtin_si_fi(ra,rb) -#define si_csflt(ra,imm) __builtin_si_csflt(ra,imm) -#define si_cflts(ra,imm) __builtin_si_cflts(ra,imm) -#define si_cuflt(ra,imm) __builtin_si_cuflt(ra,imm) -#define si_cfltu(ra,imm) __builtin_si_cfltu(ra,imm) -#define si_frds(ra) __builtin_si_frds(ra) -#define si_fesd(ra) __builtin_si_fesd(ra) -#define si_fceq(ra,rb) __builtin_si_fceq(ra,rb) -#define si_fcmeq(ra,rb) __builtin_si_fcmeq(ra,rb) -#define si_fcgt(ra,rb) __builtin_si_fcgt(ra,rb) -#define si_fcmgt(ra,rb) __builtin_si_fcmgt(ra,rb) -#define si_stop(imm) __builtin_si_stop(imm) -#define si_stopd(ra,rb,rc) __builtin_si_stopd(ra,rb,rc) -#define si_lnop() __builtin_si_lnop() -#define si_nop() __builtin_si_nop() -#define si_sync() __builtin_si_sync() -#define si_syncc() __builtin_si_syncc() -#define si_dsync() __builtin_si_dsync() -#define si_mfspr(imm) __builtin_si_mfspr(imm) -#define si_mtspr(imm,ra) __builtin_si_mtspr(imm,ra) -#define si_fscrrd() __builtin_si_fscrrd() -#define si_fscrwr(ra) __builtin_si_fscrwr(ra) -#define si_rdch(imm) __builtin_si_rdch(imm) -#define si_rchcnt(imm) __builtin_si_rchcnt(imm) -#define si_wrch(imm,ra) __builtin_si_wrch(imm,ra) - -/* celledp only instructions */ -#ifdef __SPU_EDP__ -#define si_dfceq(ra,rb) __builtin_si_dfceq(ra,rb) -#define si_dfcmeq(ra,rb) __builtin_si_dfcmeq(ra,rb) -#define si_dfcgt(ra,rb) __builtin_si_dfcgt(ra,rb) -#define si_dfcmgt(ra,rb) __builtin_si_dfcmgt(ra,rb) -#define si_dftsv(ra,imm) __builtin_si_dftsv(ra,imm) -#endif /* __SPU_EDP__ */ - -#define si_from_char(scalar) __builtin_si_from_char(scalar) -#define si_from_uchar(scalar) __builtin_si_from_uchar(scalar) -#define si_from_short(scalar) __builtin_si_from_short(scalar) -#define si_from_ushort(scalar) __builtin_si_from_ushort(scalar) -#define si_from_int(scalar) __builtin_si_from_int(scalar) -#define si_from_uint(scalar) __builtin_si_from_uint(scalar) -#define si_from_llong(scalar) __builtin_si_from_long(scalar) -#define si_from_ullong(scalar) __builtin_si_from_ulong(scalar) -#define si_from_float(scalar) __builtin_si_from_float(scalar) -#define si_from_double(scalar) __builtin_si_from_double(scalar) -#define si_from_ptr(scalar) __builtin_si_from_ptr(scalar) - -#define si_to_char(ra) __builtin_si_to_char(ra) -#define si_to_uchar(ra) __builtin_si_to_uchar(ra) -#define si_to_short(ra) __builtin_si_to_short(ra) -#define si_to_ushort(ra) __builtin_si_to_ushort(ra) -#define si_to_int(ra) __builtin_si_to_int(ra) -#define si_to_uint(ra) __builtin_si_to_uint(ra) -#define si_to_llong(ra) __builtin_si_to_long(ra) -#define si_to_ullong(ra) __builtin_si_to_ulong(ra) -#define si_to_float(ra) __builtin_si_to_float(ra) -#define si_to_double(ra) __builtin_si_to_double(ra) -#define si_to_ptr(ra) __builtin_si_to_ptr(ra) - -#define __align_hint(ptr,base,offset) __builtin_spu_align_hint(ptr,base,offset) - -/* generic spu_* intrinsics */ - -#define spu_splats(scalar) __builtin_spu_splats(scalar) -#define spu_convtf(ra,imm) __builtin_spu_convtf(ra,imm) -#define spu_convts(ra,imm) __builtin_spu_convts(ra,imm) -#define spu_convtu(ra,imm) __builtin_spu_convtu(ra,imm) -#define spu_extend(ra) __builtin_spu_extend(ra) -#define spu_roundtf(ra) __builtin_spu_roundtf(ra) -#define spu_add(ra,rb) __builtin_spu_add(ra,rb) -#define spu_addx(ra,rb,rt) __builtin_spu_addx(ra,rb,rt) -#define spu_genc(ra,rb) __builtin_spu_genc(ra,rb) -#define spu_gencx(ra,rb,rt) __builtin_spu_gencx(ra,rb,rt) -#define spu_madd(ra,rb,rc) __builtin_spu_madd(ra,rb,rc) -#define spu_nmadd(ra,rb,rc) __builtin_spu_nmadd(ra,rb,rc) -#define spu_mhhadd(ra,rb,rc) __builtin_spu_mhhadd(ra,rb,rc) -#define spu_msub(ra,rb,rc) __builtin_spu_msub(ra,rb,rc) -#define spu_mul(ra,rb) __builtin_spu_mul(ra,rb) -#define spu_mulh(ra,rb) __builtin_spu_mulh(ra,rb) -#define spu_mule(ra,rb) __builtin_spu_mule(ra,rb) -#define spu_mulo(ra,rb) __builtin_spu_mulo(ra,rb) -#define spu_mulsr(ra,rb) __builtin_spu_mulsr(ra,rb) -#define spu_nmsub(ra,rb,rc) __builtin_spu_nmsub(ra,rb,rc) -#define spu_sub(ra,rb) __builtin_spu_sub(ra,rb) -#define spu_subx(ra,rb,rt) __builtin_spu_subx(ra,rb,rt) -#define spu_genb(ra,rb) __builtin_spu_genb(ra,rb) -#define spu_genbx(ra,rb,rt) __builtin_spu_genbx(ra,rb,rt) -#define spu_absd(ra,rb) __builtin_spu_absd(ra,rb) -#define spu_avg(ra,rb) __builtin_spu_avg(ra,rb) -#define spu_sumb(ra,rb) __builtin_spu_sumb(ra,rb) -#define spu_bisled(ra) __builtin_spu_bisled(ra, 0) -#define spu_bisled_d(ra) __builtin_spu_bisled_d(ra, 0) -#define spu_bisled_e(ra) __builtin_spu_bisled_e(ra, 0) -#define spu_cmpabseq(ra,rb) __builtin_spu_cmpabseq(ra,rb) -#define spu_cmpabsgt(ra,rb) __builtin_spu_cmpabsgt(ra,rb) -#define spu_cmpeq(ra,rb) __builtin_spu_cmpeq(ra,rb) -#define spu_cmpgt(ra,rb) __builtin_spu_cmpgt(ra,rb) -#define spu_testsv(ra,imm) __builtin_spu_testsv(ra,imm) -#define spu_hcmpeq(ra,rb) __builtin_spu_hcmpeq(ra,rb) -#define spu_hcmpgt(ra,rb) __builtin_spu_hcmpgt(ra,rb) -#define spu_cntb(ra) __builtin_spu_cntb(ra) -#define spu_cntlz(ra) __builtin_spu_cntlz(ra) -#define spu_gather(ra) __builtin_spu_gather(ra) -#define spu_maskb(ra) __builtin_spu_maskb(ra) -#define spu_maskh(ra) __builtin_spu_maskh(ra) -#define spu_maskw(ra) __builtin_spu_maskw(ra) -#define spu_sel(ra,rb,rc) __builtin_spu_sel(ra,rb,rc) -#define spu_shuffle(ra,rb,rc) __builtin_spu_shuffle(ra,rb,rc) -#define spu_and(ra,rb) __builtin_spu_and(ra,rb) -#define spu_andc(ra,rb) __builtin_spu_andc(ra,rb) -#define spu_eqv(ra,rb) __builtin_spu_eqv(ra,rb) -#define spu_nand(ra,rb) __builtin_spu_nand(ra,rb) -#define spu_nor(ra,rb) __builtin_spu_nor(ra,rb) -#define spu_or(ra,rb) __builtin_spu_or(ra,rb) -#define spu_orc(ra,rb) __builtin_spu_orc(ra,rb) -#define spu_orx(ra) __builtin_spu_orx(ra) -#define spu_xor(ra,rb) __builtin_spu_xor(ra,rb) -#define spu_rl(ra,rb) __builtin_spu_rl(ra,rb) -#define spu_rlqw(ra,count) __builtin_spu_rlqw(ra,count) -#define spu_rlqwbyte(ra,count) __builtin_spu_rlqwbyte(ra,count) -#define spu_rlqwbytebc(ra,count) __builtin_spu_rlqwbytebc(ra,count) -#define spu_rlmask(ra,rb) __builtin_spu_rlmask(ra,rb) -#define spu_rlmaska(ra,rb) __builtin_spu_rlmaska(ra,rb) -#define spu_rlmaskqw(ra,rb) __builtin_spu_rlmaskqw(ra,rb) -#define spu_rlmaskqwbyte(ra,rb) __builtin_spu_rlmaskqwbyte(ra,rb) -#define spu_rlmaskqwbytebc(ra,rb) __builtin_spu_rlmaskqwbytebc(ra,rb) -#define spu_sl(ra,rb) __builtin_spu_sl(ra,rb) -#define spu_slqw(ra,rb) __builtin_spu_slqw(ra,rb) -#define spu_slqwbyte(ra,rb) __builtin_spu_slqwbyte(ra,rb) -#define spu_slqwbytebc(ra,rb) __builtin_spu_slqwbytebc(ra,rb) -#define spu_sr(ra,rb) __builtin_spu_sr(ra,rb) -#define spu_sra(ra,rb) __builtin_spu_sra(ra,rb) -#define spu_srqw(ra,rb) __builtin_spu_srqw(ra,rb) -#define spu_srqwbyte(ra,rb) __builtin_spu_srqwbyte(ra,rb) -#define spu_srqwbytebc(ra,rb) __builtin_spu_srqwbytebc(ra,rb) -#define spu_extract(ra,pos) __builtin_spu_extract(ra,pos) -#define spu_insert(scalar,ra,pos) __builtin_spu_insert(scalar,ra,pos) -#define spu_promote(scalar,pos) __builtin_spu_promote(scalar,pos) - -#ifdef __cplusplus -extern "C" { -#endif - -/* The type checking for some of these won't be accurate but they need - * to be defines because of the immediate values. */ -#define spu_idisable() __builtin_spu_idisable() -#define spu_ienable() __builtin_spu_ienable() -#define spu_mfspr(imm) si_to_uint(si_mfspr((imm))) -#define spu_mtspr(imm, ra) si_mtspr((imm),si_from_uint (ra)) -#define spu_mffpscr() ((vec_uint4)si_fscrrd()) -#define spu_mtfpscr(a) si_fscrwr((qword)a) -#define spu_dsync() si_dsync() -#define spu_stop(imm) si_stop(imm) -#define spu_sync() si_sync() -#define spu_sync_c() si_syncc() -#define spu_readch(imm) si_to_uint(si_rdch((imm))) -#define spu_readchqw(imm) ((vec_uint4)si_rdch((imm))) -#define spu_readchcnt(imm) si_to_uint(si_rchcnt((imm))) -#define spu_writech(imm, ra) si_wrch((imm), si_from_uint(ra)) -#define spu_writechqw(imm, ra) si_wrch((imm), (qword)(ra)) - -/* The following functions are static and always_inline to make sure - * they don't show up in object files which they aren't used in. */ - -static __inline__ vec_float4 spu_re (vec_float4 ra) __attribute__((__always_inline__)); -static __inline__ vec_float4 spu_rsqrte (vec_float4 ra) __attribute__((__always_inline__)); - -static __inline__ vec_float4 -spu_re (vec_float4 ra) -{ - return (vec_float4) si_fi ((qword) (ra), si_frest ((qword) (ra))); -} -static __inline__ vec_float4 -spu_rsqrte (vec_float4 ra) -{ - return (vec_float4) si_fi ((qword) (ra), si_frsqest ((qword) (ra))); -} - -/* composite intrinsics */ -static __inline__ void spu_mfcdma32(volatile void *ls, unsigned int ea, unsigned int size, unsigned int tagid, unsigned int cmd) __attribute__((__always_inline__)); -static __inline__ void spu_mfcdma64(volatile void *ls, unsigned int eahi, unsigned int ealow, unsigned int size, unsigned int tagid, unsigned int cmd) __attribute__((__always_inline__)); -static __inline__ unsigned int spu_mfcstat(unsigned int type) __attribute__((__always_inline__)); - -static __inline__ void -spu_mfcdma32(volatile void *ls, unsigned int ea, unsigned int size, unsigned int tagid, unsigned int cmd) -{ - si_wrch(MFC_LSA,si_from_ptr(ls)); - si_wrch(MFC_EAL,si_from_uint(ea)); - si_wrch(MFC_Size,si_from_uint(size)); - si_wrch(MFC_TagID,si_from_uint(tagid)); - si_wrch(MFC_Cmd,si_from_uint(cmd)); -} -static __inline__ void -spu_mfcdma64(volatile void *ls, unsigned int eahi, unsigned int ealow, unsigned int size, unsigned int tagid, unsigned int cmd) -{ - si_wrch(MFC_LSA,si_from_ptr(ls)); - si_wrch(MFC_EAH,si_from_uint(eahi)); - si_wrch(MFC_EAL,si_from_uint(ealow)); - si_wrch(MFC_Size,si_from_uint(size)); - si_wrch(MFC_TagID,si_from_uint(tagid)); - si_wrch(MFC_Cmd,si_from_uint(cmd)); -} -static __inline__ unsigned int -spu_mfcstat(unsigned int type) -{ - si_wrch(MFC_WrTagUpdate,si_from_uint(type)); - return si_to_uint(si_rdch(MFC_RdTagStat)); -} -#ifdef __cplusplus - -} -#endif /* __cplusplus */ - -#endif /* SPUINTRIN_H */ - diff --git a/gcc/config/spu/spu_intrinsics.h b/gcc/config/spu/spu_intrinsics.h deleted file mode 100644 index 81ed50a..0000000 --- a/gcc/config/spu/spu_intrinsics.h +++ /dev/null @@ -1,83 +0,0 @@ -/* Definitions of Synergistic Processing Unit (SPU). */ -/* Copyright (C) 2006-2019 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - . */ - -#ifndef _SPU_INTRINSICS_H -#define _SPU_INTRINSICS_H - -#define vec_uchar16 __vector unsigned char -#define vec_char16 __vector signed char -#define vec_ushort8 __vector unsigned short -#define vec_short8 __vector signed short -#define vec_uint4 __vector unsigned int -#define vec_int4 __vector signed int -#define vec_ullong2 __vector unsigned long long -#define vec_llong2 __vector signed long long -#define vec_float4 __vector float -#define vec_double2 __vector double - -/* SPU Channel Defines - */ -#define SPU_RdEventStat 0 -#define SPU_WrEventMask 1 -#define SPU_WrEventAck 2 -#define SPU_RdSigNotify1 3 -#define SPU_RdSigNotify2 4 -#define SPU_WrDec 7 -#define SPU_RdDec 8 -#define SPU_RdEventMask 11 -#define SPU_RdMachStat 13 -#define SPU_WrSRR0 14 -#define SPU_RdSRR0 15 -#define SPU_WrOutMbox 28 -#define SPU_RdInMbox 29 -#define SPU_WrOutIntrMbox 30 - -/* MFC Channel Defines. - */ -#define MFC_WrMSSyncReq 9 -#define MFC_RdTagMask 12 -#define MFC_LSA 16 -#define MFC_EAH 17 -#define MFC_EAL 18 -#define MFC_Size 19 -#define MFC_TagID 20 -#define MFC_Cmd 21 -#define MFC_WrTagMask 22 -#define MFC_WrTagUpdate 23 -#define MFC_RdTagStat 24 -#define MFC_RdListStallStat 25 -#define MFC_WrListStallAck 26 -#define MFC_RdAtomicStat 27 - -/* Bit flag mnemonics for test special value. - */ -#define SPU_SV_NEG_DENORM 0x01 /* negative denormalized number */ -#define SPU_SV_POS_DENORM 0x02 /* positive denormalized number */ -#define SPU_SV_NEG_ZERO 0x04 /* negative zero */ -#define SPU_SV_POS_ZERO 0x08 /* positive zero */ -#define SPU_SV_NEG_INFINITY 0x10 /* negative infinity */ -#define SPU_SV_POS_INFINITY 0x20 /* positive infinity */ -#define SPU_SV_NAN 0x40 /* not a number */ - -#include - -#endif /* _SPU_INTRINSICS_H */ diff --git a/gcc/config/spu/spu_mfcio.h b/gcc/config/spu/spu_mfcio.h deleted file mode 100644 index db35a33..0000000 --- a/gcc/config/spu/spu_mfcio.h +++ /dev/null @@ -1,342 +0,0 @@ -/* Copyright (C) 2006-2019 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - . */ - -#ifndef __SPU_MFCIO_H__ -#define __SPU_MFCIO_H__ 1 - -#include -#ifdef __IN_LIBGCC2 -typedef unsigned long long uint64_t; -#else -#include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - - -/****************************************************************/ -/* DMA list element structure*/ -/****************************************************************/ - -#ifdef __GNUC__ -__extension__ -#endif -typedef struct mfc_list_element { - uint64_t notify : 1; /** Stall-and-notify bit */ - uint64_t reserved : 16; - uint64_t size : 15; /** Transfer size */ - uint64_t eal : 32; /** Lower word of effective address */ -} mfc_list_element_t; - -/****************************************************************/ -/* DMA max/min size definitions. */ -/****************************************************************/ - -#define MFC_MIN_DMA_SIZE_SHIFT 4 /* 16 bytes */ -#define MFC_MAX_DMA_SIZE_SHIFT 14 /* 16384 bytes */ - -#define MFC_MIN_DMA_SIZE (1 << MFC_MIN_DMA_SIZE_SHIFT) -#define MFC_MAX_DMA_SIZE (1 << MFC_MAX_DMA_SIZE_SHIFT) - -#define MFC_MIN_DMA_SIZE_MASK (MFC_MIN_DMA_SIZE - 1) -#define MFC_MAX_DMA_SIZE_MASK (MFC_MAX_DMA_SIZE - 1) - -#define MFC_MIN_DMA_LIST_ELEMENTS 1 -#define MFC_MAX_DMA_LIST_ELEMENTS 2048 - -#define MFC_MIN_DMA_LIST_SIZE (MFC_MIN_DMA_LIST_ELEMENTS << 3) /* 8 bytes */ -#define MFC_MAX_DMA_LIST_SIZE (MFC_MAX_DMA_LIST_ELEMENTS << 3) /* 16K bytes */ - -/****************************************************************/ -/* MFC DMA command modifiers to identify classes of operations. */ -/****************************************************************/ - -/* Note: These commands modifier may be used in conjunction with the base - command types (i.e. MFC_PUT_CMD, MFC_GET_CMD, and MFC_SNDSIG_CMD) - to construct the various command permutations. */ - -#define MFC_BARRIER_ENABLE 0x0001 -#define MFC_FENCE_ENABLE 0x0002 -#define MFC_LIST_ENABLE 0x0004 -#define MFC_RESULT_ENABLE 0x0010 - -/****************************************************************/ -/* MFC DMA Put Commands */ -/****************************************************************/ - -#define MFC_PUT_CMD 0x0020 -#define MFC_PUTB_CMD (MFC_PUT_CMD | MFC_BARRIER_ENABLE) -#define MFC_PUTF_CMD (MFC_PUT_CMD | MFC_FENCE_ENABLE) -#define MFC_PUTL_CMD (MFC_PUT_CMD | MFC_LIST_ENABLE) -#define MFC_PUTLB_CMD (MFC_PUTL_CMD | MFC_BARRIER_ENABLE) -#define MFC_PUTLF_CMD (MFC_PUTL_CMD | MFC_FENCE_ENABLE) - -#define MFC_PUTR_CMD (MFC_PUT_CMD | MFC_RESULT_ENABLE) -#define MFC_PUTRB_CMD (MFC_PUTR_CMD | MFC_BARRIER_ENABLE) -#define MFC_PUTRF_CMD (MFC_PUTR_CMD | MFC_FENCE_ENABLE) -#define MFC_PUTRL_CMD (MFC_PUTR_CMD | MFC_LIST_ENABLE) -#define MFC_PUTRLB_CMD (MFC_PUTRL_CMD | MFC_BARRIER_ENABLE) -#define MFC_PUTRLF_CMD (MFC_PUTRL_CMD | MFC_FENCE_ENABLE) - -/****************************************************************/ -/* MFC DMA Get Commands */ -/****************************************************************/ - -#define MFC_GET_CMD 0x0040 -#define MFC_GETB_CMD (MFC_GET_CMD | MFC_BARRIER_ENABLE) -#define MFC_GETF_CMD (MFC_GET_CMD | MFC_FENCE_ENABLE) -#define MFC_GETL_CMD (MFC_GET_CMD | MFC_LIST_ENABLE) -#define MFC_GETLB_CMD (MFC_GETL_CMD | MFC_BARRIER_ENABLE) -#define MFC_GETLF_CMD (MFC_GETL_CMD | MFC_FENCE_ENABLE) - -/****************************************************************/ -/* MFC Synchronization Commands */ -/****************************************************************/ - -#define MFC_SNDSIG_CMD 0x00A0 -#define MFC_SNDSIGB_CMD (MFC_SNDSIG_CMD | MFC_BARRIER_ENABLE) -#define MFC_SNDSIGF_CMD (MFC_SNDSIG_CMD | MFC_FENCE_ENABLE) -#define MFC_BARRIER_CMD 0x00C0 -#define MFC_EIEIO_CMD 0x00C8 -#define MFC_SYNC_CMD 0x00CC - -/****************************************************************/ -/* MFC Atomic Commands */ -/****************************************************************/ - -#define MFC_GETLLAR_CMD 0x00D0 -#define MFC_PUTLLC_CMD 0x00B4 -#define MFC_PUTLLUC_CMD 0x00B0 -#define MFC_PUTQLLUC_CMD 0x00B8 - -/****************************************************************/ -/* MFC SL1 Storage Control Commands */ -/****************************************************************/ - -#define MFC_SDCRT_CMD 0x0080 -#define MFC_SDCRTST_CMD 0x0081 -#define MFC_SDCRZ_CMD 0x0089 -#define MFC_SDCRST_CMD 0x008D -#define MFC_SDCRF_CMD 0x008F - -/****************************************************************/ -/* Channel Defines */ -/****************************************************************/ - -/* Events Defines for channels - * 0 (SPU_RdEventStat), - * 1 (SPU_WrEventMask), and - * 2 (SPU_WrEventAck). - */ -#define MFC_TAG_STATUS_UPDATE_EVENT 0x00000001 -#define MFC_LIST_STALL_NOTIFY_EVENT 0x00000002 -#define MFC_COMMAND_QUEUE_AVAILABLE_EVENT 0x00000008 -#define MFC_IN_MBOX_AVAILABLE_EVENT 0x00000010 -#define MFC_DECREMENTER_EVENT 0x00000020 -#define MFC_OUT_INTR_MBOX_AVAILABLE_EVENT 0x00000040 -#define MFC_OUT_MBOX_AVAILABLE_EVENT 0x00000080 -#define MFC_SIGNAL_NOTIFY_2_EVENT 0x00000100 -#define MFC_SIGNAL_NOTIFY_1_EVENT 0x00000200 -#define MFC_LLR_LOST_EVENT 0x00000400 -#define MFC_PRIV_ATTN_EVENT 0x00000800 -#define MFC_MULTI_SRC_SYNC_EVENT 0x00001000 - -/* Tag Status Update defines for channel 23 (MFC_WrTagUpdate) */ -#define MFC_TAG_UPDATE_IMMEDIATE 0x0 -#define MFC_TAG_UPDATE_ANY 0x1 -#define MFC_TAG_UPDATE_ALL 0x2 - -/* Atomic Command Status defines for channel 27 (MFC_RdAtomicStat) */ -#define MFC_PUTLLC_STATUS 0x00000001 -#define MFC_PUTLLUC_STATUS 0x00000002 -#define MFC_GETLLAR_STATUS 0x00000004 - - -/****************************************************************/ -/* Definitions for constructing a 32-bit command word */ -/* including the transfer and replacement class id and the */ -/* command opcode. */ -/****************************************************************/ -#define MFC_CMD_WORD(_tid, _rid, _cmd) (((_tid)<<24)|((_rid)<<16)|(_cmd)) - - -/* Addressing Utilities */ -#define mfc_ea2h(ea) (unsigned int)((unsigned long long)(ea)>>32) -#define mfc_ea2l(ea) (unsigned int)(ea) -#define mfc_hl2ea(h,l) si_to_ullong(si_selb(si_from_uint(h),\ - si_rotqbyi(si_from_uint(l), -4),\ - si_fsmbi(0x0f0f))) -#define mfc_ceil128(v) (((v) + 127) & ~127) - -/* MFC DMA */ -#define mfc_put( ls,ea,size,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),mfc_ea2l(ea),size,tag,MFC_CMD_WORD(tid,rid,MFC_PUT_CMD)) -#define mfc_putf( ls,ea,size,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),mfc_ea2l(ea),size,tag,MFC_CMD_WORD(tid,rid,MFC_PUTF_CMD)) -#define mfc_putb( ls,ea,size,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),mfc_ea2l(ea),size,tag,MFC_CMD_WORD(tid,rid,MFC_PUTB_CMD)) -#define mfc_get( ls,ea,size,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),mfc_ea2l(ea),size,tag,MFC_CMD_WORD(tid,rid,MFC_GET_CMD)) -#define mfc_getf( ls,ea,size,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),mfc_ea2l(ea),size,tag,MFC_CMD_WORD(tid,rid,MFC_GETF_CMD)) -#define mfc_getb( ls,ea,size,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),mfc_ea2l(ea),size,tag,MFC_CMD_WORD(tid,rid,MFC_GETB_CMD)) - -/* MFC list DMA */ -#define mfc_putl( ls,ea,lsa,size,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),(unsigned int)(lsa),size,tag,MFC_CMD_WORD(tid,rid,MFC_PUTL_CMD)) -#define mfc_putlf( ls,ea,lsa,size,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),(unsigned int)(lsa),size,tag,MFC_CMD_WORD(tid,rid,MFC_PUTLF_CMD)) -#define mfc_putlb( ls,ea,lsa,size,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),(unsigned int)(lsa),size,tag,MFC_CMD_WORD(tid,rid,MFC_PUTLB_CMD)) -#define mfc_getl( ls,ea,lsa,size,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),(unsigned int)(lsa),size,tag,MFC_CMD_WORD(tid,rid,MFC_GETL_CMD)) -#define mfc_getlf( ls,ea,lsa,size,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),(unsigned int)(lsa),size,tag,MFC_CMD_WORD(tid,rid,MFC_GETLF_CMD)) -#define mfc_getlb( ls,ea,lsa,size,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),(unsigned int)(lsa),size,tag,MFC_CMD_WORD(tid,rid,MFC_GETLB_CMD)) - -/* MFC Atomic Update DMA */ -#define mfc_getllar( ls,ea,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),mfc_ea2l(ea),128, 0,MFC_CMD_WORD(tid,rid,MFC_GETLLAR_CMD)) -#define mfc_putllc( ls,ea,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),mfc_ea2l(ea),128, 0,MFC_CMD_WORD(tid,rid,MFC_PUTLLC_CMD)) -#define mfc_putlluc( ls,ea,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),mfc_ea2l(ea),128, 0,MFC_CMD_WORD(tid,rid,MFC_PUTLLUC_CMD)) -#define mfc_putqlluc(ls,ea,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),mfc_ea2l(ea),128,tag,MFC_CMD_WORD(tid,rid,MFC_PUTQLLUC_CMD)) - -/* MFC Synchronization Commands */ -#define mfc_sndsig( ls,ea,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),mfc_ea2l(ea),4,tag,MFC_CMD_WORD(tid,rid,MFC_SNDSIG_CMD)) -#define mfc_sndsigb(ls,ea,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),mfc_ea2l(ea),4,tag,MFC_CMD_WORD(tid,rid,MFC_SNDSIGB_CMD)) -#define mfc_sndsigf(ls,ea,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),mfc_ea2l(ea),4,tag,MFC_CMD_WORD(tid,rid,MFC_SNDSIGF_CMD)) -#define mfc_barrier(tag) spu_mfcdma32(0,0,0,tag,MFC_BARRIER_CMD) -#define mfc_eieio(tag,tid,rid) spu_mfcdma32(0,0,0,tag,MFC_CMD_WORD(tid,rid,MFC_EIEIO_CMD)) -#define mfc_sync(tag) spu_mfcdma32(0,0,0,tag,MFC_SYNC_CMD) - -/* MFC SL1 Storage Control Commands */ -#define mfc_sdcrt( ea,size,tag,tid,rid) spu_mfcdma64(0,mfc_ea2h(ea),mfc_ea2l(ea),size,tag,MFC_CMD_WORD(tid,rid,MFC_SDCRT_CMD)) -#define mfc_sdcrtst(ea,size,tag,tid,rid) spu_mfcdma64(0,mfc_ea2h(ea),mfc_ea2l(ea),size,tag,MFC_CMD_WORD(tid,rid,MFC_SDCRTST_CMD)) -#define mfc_sdcrz( ea,size,tag,tid,rid) spu_mfcdma64(0,mfc_ea2h(ea),mfc_ea2l(ea),size,tag,MFC_CMD_WORD(tid,rid,MFC_SDCRZ_CMD)) -#define mfc_sdcrst( ea,size,tag,tid,rid) spu_mfcdma64(0,mfc_ea2h(ea),mfc_ea2l(ea),size,tag,MFC_CMD_WORD(tid,rid,MFC_SDCRST_CMD)) -#define mfc_sdcrf( ea,size,tag,tid,rid) spu_mfcdma64(0,mfc_ea2h(ea),mfc_ea2l(ea),size,tag,MFC_CMD_WORD(tid,rid,MFC_SDCRF_CMD)) - -/* DMA Queue */ -#define mfc_stat_cmd_queue() spu_readchcnt(MFC_Cmd) - -/* MFC Tag-Status */ -#define mfc_write_tag_mask(mask) spu_writech(MFC_WrTagMask,mask) -#define mfc_read_tag_mask() spu_readch(MFC_RdTagMask) - -#define mfc_write_tag_update(ts) spu_writech(MFC_WrTagUpdate,ts) -#define mfc_write_tag_update_immediate() mfc_write_tag_update(MFC_TAG_UPDATE_IMMEDIATE) -#define mfc_write_tag_update_any() mfc_write_tag_update(MFC_TAG_UPDATE_ANY) -#define mfc_write_tag_update_all() mfc_write_tag_update(MFC_TAG_UPDATE_ALL) -#define mfc_stat_tag_update() spu_readchcnt(MFC_WrTagUpdate) - -#define mfc_read_tag_status() spu_readch(MFC_RdTagStat) -#define mfc_read_tag_status_immediate() (mfc_write_tag_update_immediate(), mfc_read_tag_status()) -#define mfc_read_tag_status_any() (mfc_write_tag_update_any(), mfc_read_tag_status()) -#define mfc_read_tag_status_all() (mfc_write_tag_update_all(), mfc_read_tag_status()) -#define mfc_stat_tag_status() spu_readchcnt(MFC_RdTagStat) - -/* MFC List Stall-and-Notify Tag */ -#define mfc_read_list_stall_status() spu_readch(MFC_RdListStallStat) -#define mfc_stat_list_stall_status() spu_readchcnt(MFC_RdListStallStat) -#define mfc_write_list_stall_ack(tag) spu_writech(MFC_WrListStallAck,tag) - -/* Atomic DMA */ -#define mfc_read_atomic_status() spu_readch(MFC_RdAtomicStat) -#define mfc_stat_atomic_status() spu_readchcnt(MFC_RdAtomicStat) - -/* MFC Multi-source Synchronization */ -#define mfc_write_multi_src_sync_request() spu_writech(MFC_WrMSSyncReq,0) -#define mfc_stat_multi_src_sync_request() spu_readchcnt(MFC_WrMSSyncReq) - -/* SPU Signal */ -#define spu_read_signal1() spu_readch(SPU_RdSigNotify1) -#define spu_stat_signal1() spu_readchcnt(SPU_RdSigNotify1) -#define spu_read_signal2() spu_readch(SPU_RdSigNotify2) -#define spu_stat_signal2() spu_readchcnt(SPU_RdSigNotify2) - -/* SPU/PPE Mailbox */ -#define spu_read_in_mbox() spu_readch(SPU_RdInMbox) -#define spu_stat_in_mbox() spu_readchcnt(SPU_RdInMbox) -#define spu_write_out_mbox(a) spu_writech(SPU_WrOutMbox,a) -#define spu_stat_out_mbox() spu_readchcnt(SPU_WrOutMbox) -#define spu_write_out_intr_mbox(a) spu_writech(SPU_WrOutIntrMbox,a) -#define spu_stat_out_intr_mbox() spu_readchcnt(SPU_WrOutIntrMbox) - -/* SPU Decrementer */ -#define spu_read_decrementer() spu_readch(SPU_RdDec) -#define spu_write_decrementer(cnt) spu_writech(SPU_WrDec,(cnt)) - -/* SPU Event */ -#define spu_read_event_status() spu_readch(SPU_RdEventStat) -#define spu_stat_event_status() spu_readchcnt(SPU_RdEventStat) -#define spu_write_event_mask(mask) spu_writech(SPU_WrEventMask,(mask)) -#define spu_write_event_ack(ack) spu_writech(SPU_WrEventAck,(ack)) -#define spu_read_event_mask() spu_readch(SPU_RdEventMask) - -/* SPU State Management */ -#define spu_read_machine_status() spu_readch(SPU_RdMachStat) -#define spu_write_srr0(srr0) spu_writech(SPU_WrSRR0,srr0) -#define spu_read_srr0() spu_readch(SPU_RdSRR0) - -/* Interrupt-Safe Critical Sections */ - -static __inline__ unsigned int mfc_begin_critical_section (void) - __attribute__ ((__always_inline__)); - -static __inline__ unsigned int -mfc_begin_critical_section (void) -{ -#ifdef SPU_MFCIO_INTERRUPT_SAFE - unsigned int __status = spu_read_machine_status (); - spu_idisable (); - return __status; -#else - return 0; -#endif -} - -static __inline__ void mfc_end_critical_section (unsigned int) - __attribute__ ((__always_inline__)); - -static __inline__ void -mfc_end_critical_section (unsigned int __status __attribute__ ((__unused__))) -{ -#ifdef SPU_MFCIO_INTERRUPT_SAFE - if (__status & 1) - spu_ienable (); -#endif -} - -/* MFC Tag Manager */ - -#define MFC_TAG_INVALID 0xFFFFFFFF -#define MFC_TAG_VALID 0x00000000 - -#define mfc_tag_reserve() \ - __mfc_tag_reserve() -#define mfc_tag_release(tag) \ - __mfc_tag_release((tag)) -#define mfc_multi_tag_reserve(nr_tags) \ - __mfc_multi_tag_reserve((nr_tags)) -#define mfc_multi_tag_release(tag, nr_tags) \ - __mfc_multi_tag_release((tag),(nr_tags)) - -extern unsigned int __mfc_tag_reserve (void); -extern unsigned int __mfc_tag_release (unsigned int); -extern unsigned int __mfc_multi_tag_reserve (unsigned int); -extern unsigned int __mfc_multi_tag_release (unsigned int, unsigned int); - -#ifdef __cplusplus -} -#endif - -#endif /* __SPU_MFCIO_H__ */ diff --git a/gcc/config/spu/t-spu-elf b/gcc/config/spu/t-spu-elf deleted file mode 100644 index fe9591d..0000000 --- a/gcc/config/spu/t-spu-elf +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright (C) 2006-2019 Free Software Foundation, Inc. -# -# This file is free software; you can redistribute it and/or modify it under -# the terms of the GNU General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) -# any later version. -# -# This file is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# . - -# Multi-lib support. -MULTILIB_OPTIONS=mea64 - -spu.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ - $(RTL_H) $(REGS_H) hard-reg-set.h dumpfile.h \ - real.h insn-config.h conditions.h insn-attr.h flags.h $(RECOG_H) \ - $(OBSTACK_H) $(TREE_H) $(EXPR_H) $(OPTABS_H) except.h function.h \ - output.h $(BASIC_BLOCK_H) $(GGC_H) $(HASHTAB_H) \ - $(TM_P_H) $(TARGET_H) $(TARGET_DEF_H) langhooks.h reload.h $(CFGLOOP_H) \ - $(srcdir)/config/spu/spu-protos.h \ - $(srcdir)/config/spu/spu-builtins.def - -spu-c.o: $(srcdir)/config/spu/spu-c.c \ - $(srcdir)/config/spu/spu-protos.h \ - $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(CPPLIB_H) \ - $(TM_P_H) $(C_COMMON_H) $(C_PRAGMA_H) coretypes.h $(TM_H) insn-codes.h - $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ - $(srcdir)/config/spu/spu-c.c diff --git a/gcc/config/spu/vec_types.h b/gcc/config/spu/vec_types.h deleted file mode 100644 index 2c3f18f..0000000 --- a/gcc/config/spu/vec_types.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (C) 2006-2019 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - . */ - -#ifndef _VEC_TYPES_H_ -#define _VEC_TYPES_H_ 1 - -#include - -/* Define additional PowerPC SIMD/Vector Multi-media eXtension - * single keyword vector data types for use in mapping VMX code - * to the SPU. - */ -#define vec_bchar16 __vector unsigned char -#define vec_bshort8 __vector unsigned short -#define vec_pixel8 __vector unsigned short -#define vec_bint4 __vector unsigned int - -#endif /* _VEC_TYPES_H_ */ diff --git a/gcc/config/spu/vmx2spu.h b/gcc/config/spu/vmx2spu.h deleted file mode 100644 index 75ab594..0000000 --- a/gcc/config/spu/vmx2spu.h +++ /dev/null @@ -1,3985 +0,0 @@ -/* Copyright (C) 2006-2019 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - . */ - -#ifndef _VMX2SPU_H_ -#define _VMX2SPU_H_ 1 - -#ifdef __cplusplus - -#ifdef __SPU__ - -#include -#include - -/* This file maps generic VMX intrinsics and predicates to the SPU using - * overloaded C++ functions. - */ - -/************************************************************************ - * INTRINSICS - ************************************************************************/ - -/* vec_abs (vector absolute value) - * ======= - */ -static inline vec_char16 vec_abs(vec_char16 a) -{ - vec_char16 minus_a; - - minus_a = (vec_char16)(spu_add((vec_ushort8)(spu_and(spu_xor(a, 0xFF), 0x7F)), 0x101)); - return (spu_sel(minus_a, a, spu_cmpgt(a, -1))); -} - -static inline vec_short8 vec_abs(vec_short8 a) -{ - return (spu_sel(spu_sub(0, a), a, spu_cmpgt(a, -1))); -} - -static inline vec_int4 vec_abs(vec_int4 a) -{ - return (spu_sel(spu_sub(0, a), a, spu_cmpgt(a, -1))); -} - -static inline vec_float4 vec_abs(vec_float4 a) -{ - return ((vec_float4)(spu_rlmask(spu_sl((vec_uint4)(a), 1), -1))); -} - -/* vec_abss (vector absolute value saturate) - * ======== - */ -static inline vec_char16 vec_abss(vec_char16 a) -{ - vec_char16 minus_a; - - minus_a = (vec_char16)spu_add((vec_short8)(spu_xor(a, -1)), - (vec_short8)(spu_and(spu_cmpgt((vec_uchar16)(a), 0x80), 1))); - return (spu_sel(minus_a, a, spu_cmpgt(a, -1))); -} - -static inline vec_short8 vec_abss(vec_short8 a) -{ - vec_short8 minus_a; - - minus_a = spu_add(spu_sub(0, a), (vec_short8)(spu_cmpeq(a, ((vec_short8){0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000})))); - return (spu_sel(minus_a, a, spu_cmpgt(a, -1))); -} - -static inline vec_int4 vec_abss(vec_int4 a) -{ - vec_int4 minus_a; - - minus_a = spu_add(spu_sub(0, a), (vec_int4)(spu_cmpeq(a, ((vec_int4){0x80000000,0x80000000,0x80000000,0x80000000})))); - return (spu_sel(minus_a, a, spu_cmpgt(a, -1))); -} - - -/* vec_add (vector add) - * ======= - */ -static inline vec_uchar16 vec_add(vec_uchar16 a, vec_uchar16 b) -{ - return ((vec_uchar16)(spu_sel(spu_add((vec_ushort8)(a), (vec_ushort8)(b)), - spu_add(spu_and((vec_ushort8)(a), 0xFF00), spu_and((vec_ushort8)(b), 0xFF00)), - spu_splats((unsigned short)(0xFF00))))); -} - -static inline vec_char16 vec_add(vec_char16 a, vec_char16 b) -{ - return ((vec_char16)vec_add((vec_uchar16)(a), (vec_uchar16)(b))); -} - -static inline vec_char16 vec_add(vec_bchar16 a, vec_char16 b) -{ - return ((vec_char16)vec_add((vec_uchar16)(a), (vec_uchar16)(b))); -} - -static inline vec_char16 vec_add(vec_char16 a, vec_bchar16 b) -{ - return ((vec_char16)vec_add((vec_uchar16)(a), (vec_uchar16)(b))); -} - -static inline vec_ushort8 vec_add(vec_ushort8 a, vec_ushort8 b) -{ - return (spu_add(a, b)); -} - -static inline vec_short8 vec_add(vec_short8 a, vec_short8 b) -{ - return (spu_add(a, b)); -} - -static inline vec_short8 vec_add(vec_bshort8 a, vec_short8 b) -{ - return (spu_add((vec_short8)(a), b)); -} - -static inline vec_short8 vec_add(vec_short8 a, vec_bshort8 b) -{ - return (spu_add(a, (vec_short8)(b))); -} - -static inline vec_uint4 vec_add(vec_uint4 a, vec_uint4 b) -{ - return (spu_add(a, b)); -} - -static inline vec_int4 vec_add(vec_int4 a, vec_int4 b) -{ - return (spu_add(a, b)); -} - -static inline vec_int4 vec_add(vec_bint4 a, vec_int4 b) -{ - return (spu_add((vec_int4)(a), b)); -} - -static inline vec_int4 vec_add(vec_int4 a, vec_bint4 b) -{ - return (spu_add(a, (vec_int4)(b))); -} - -static inline vec_float4 vec_add(vec_float4 a, vec_float4 b) -{ - return (spu_add(a, b)); -} - -/* vec_addc (vector add carryout unsigned word) - * ======== - */ -#define vec_addc(_a, _b) spu_genc(_a, _b) - -/* vec_adds (vector add saturated) - * ======== - */ -static inline vec_uchar16 vec_adds(vec_uchar16 a, vec_uchar16 b) -{ - vec_uchar16 s1, s2, s, d; - - s1 = (vec_uchar16)(spu_add(spu_rlmask((vec_ushort8)(a), -8), spu_rlmask((vec_ushort8)(b), -8))); - s2 = (vec_uchar16)(spu_add(spu_and((vec_ushort8)(a), 0xFF), spu_and((vec_ushort8)(b), 0xFF))); - s = spu_shuffle(s1, s2, ((vec_uchar16){0, 16, 2, 18, 4, 20, 6, 22, - 8, 24, 10, 26, 12, 28, 14, 30})); - d = spu_shuffle(s1, s2, ((vec_uchar16){1, 17, 3, 19, 5, 21, 7, 23, - 9, 25, 11, 27, 13, 29, 15, 31})); - return (spu_or(d, spu_cmpeq(s, 1))); -} - -static inline vec_char16 vec_adds(vec_char16 a, vec_char16 b) -{ - vec_uchar16 s1, s2, s, d; - - s1 = (vec_uchar16)(spu_add(spu_rlmask((vec_ushort8)(a), -8), spu_rlmask((vec_ushort8)(b), -8))); - s2 = (vec_uchar16)(spu_add(spu_and((vec_ushort8)(a), 0xFF), spu_and((vec_ushort8)(b), 0xFF))); - s = spu_shuffle(s1, s2, ((vec_uchar16){1, 17, 3, 19, 5, 21, 7, 23, - 9, 25, 11, 27, 13, 29, 15, 31})); - d = spu_sel(s, spu_splats((unsigned char)0x7F), spu_cmpgt(spu_and(s, (vec_uchar16)(spu_nor(a, b))), 0x7F)); - d = spu_sel(d, spu_splats((unsigned char)0x80), spu_cmpgt(spu_nor(s, (vec_uchar16)(spu_nand(a, b))), 0x7F)); - return ((vec_char16)(d)); -} - -static inline vec_char16 vec_adds(vec_bchar16 a, vec_char16 b) -{ - return (vec_adds((vec_char16)(a), b)); -} - -static inline vec_char16 vec_adds(vec_char16 a, vec_bchar16 b) -{ - return (vec_adds(a, (vec_char16)(b))); -} - -static inline vec_ushort8 vec_adds(vec_ushort8 a, vec_ushort8 b) -{ - vec_ushort8 s, d; - - s = spu_add(a, b); - d = spu_or(s, spu_rlmaska(spu_sel(spu_xor(s, -1), a, spu_eqv(a, b)), -15)); - return (d); -} - -static inline vec_short8 vec_adds(vec_short8 a, vec_short8 b) -{ - vec_short8 s, d; - - s = spu_add(a, b); - d = spu_sel(s, spu_splats((signed short)0x7FFF), (vec_ushort8)(spu_rlmaska(spu_and(s, spu_nor(a, b)), -15))); - d = spu_sel(d, spu_splats((signed short)0x8000), (vec_ushort8)(spu_rlmaska(spu_nor(s, spu_nand(a, b)), -15))); - return (d); -} - -static inline vec_short8 vec_adds(vec_bshort8 a, vec_short8 b) -{ - return (vec_adds((vec_short8)(a), b)); -} - -static inline vec_short8 vec_adds(vec_short8 a, vec_bshort8 b) -{ - return (vec_adds(a, (vec_short8)(b))); -} - -static inline vec_uint4 vec_adds(vec_uint4 a, vec_uint4 b) -{ - return (spu_or(spu_add(a, b), spu_rlmaska(spu_sl(spu_genc(a, b), 31), -31))); -} - -static inline vec_int4 vec_adds(vec_int4 a, vec_int4 b) -{ - vec_int4 s, d; - - s = spu_add(a, b); - d = spu_sel(s, spu_splats((signed int)0x7FFFFFFF), (vec_uint4)spu_rlmaska(spu_and(s, spu_nor(a, b)), -31)); - d = spu_sel(d, spu_splats((signed int)0x80000000), (vec_uint4)spu_rlmaska(spu_nor(s, spu_nand(a, b)), -31)); - return (d); -} - -static inline vec_int4 vec_adds(vec_bint4 a, vec_int4 b) -{ - return (vec_adds((vec_int4)(a), b)); -} - -static inline vec_int4 vec_adds(vec_int4 a, vec_bint4 b) -{ - return (vec_adds(a, (vec_int4)(b))); -} - -/* vec_and (vector logical and) - * ======= - */ -static inline vec_uchar16 vec_and(vec_uchar16 a, vec_uchar16 b) -{ - return (spu_and(a, b)); -} - -static inline vec_char16 vec_and(vec_char16 a, vec_char16 b) -{ - return (spu_and(a, b)); -} - -static inline vec_char16 vec_and(vec_bchar16 a, vec_char16 b) -{ - return (spu_and((vec_char16)(a), b)); -} - -static inline vec_char16 vec_and(vec_char16 a, vec_bchar16 b) -{ - return (spu_and(a, (vec_char16)(b))); -} - -static inline vec_ushort8 vec_and(vec_ushort8 a, vec_ushort8 b) -{ - return (spu_and(a, b)); -} - -static inline vec_short8 vec_and(vec_short8 a, vec_short8 b) -{ - return (spu_and(a, b)); -} - -static inline vec_short8 vec_and(vec_bshort8 a, vec_short8 b) -{ - return (spu_and((vec_short8)(a), b)); -} - -static inline vec_short8 vec_and(vec_short8 a, vec_bshort8 b) -{ - return (spu_and(a, (vec_short8)(b))); -} - -static inline vec_uint4 vec_and(vec_uint4 a, vec_uint4 b) -{ - return (spu_and(a, b)); -} - -static inline vec_int4 vec_and(vec_int4 a, vec_int4 b) -{ - return (spu_and(a, b)); -} - -static inline vec_int4 vec_and(vec_bint4 a, vec_int4 b) -{ - return (spu_and((vec_int4)(a), b)); -} - -static inline vec_int4 vec_and(vec_int4 a, vec_bint4 b) -{ - return (spu_and(a, (vec_int4)(b))); -} - -static inline vec_float4 vec_and(vec_float4 a, vec_float4 b) -{ - return (spu_and(a, b)); -} - -static inline vec_float4 vec_and(vec_bint4 a, vec_float4 b) -{ - return (spu_and((vec_float4)(a),b)); -} - -static inline vec_float4 vec_and(vec_float4 a, vec_bint4 b) -{ - return (spu_and(a, (vec_float4)(b))); -} - - -/* vec_andc (vector logical and with complement) - * ======== - */ -static inline vec_uchar16 vec_andc(vec_uchar16 a, vec_uchar16 b) -{ - return (spu_andc(a, b)); -} - -static inline vec_char16 vec_andc(vec_char16 a, vec_char16 b) -{ - return (spu_andc(a, b)); -} - -static inline vec_char16 vec_andc(vec_bchar16 a, vec_char16 b) -{ - return (spu_andc((vec_char16)(a), b)); -} - -static inline vec_char16 vec_andc(vec_char16 a, vec_bchar16 b) -{ - return (spu_andc(a, (vec_char16)(b))); -} - -static inline vec_ushort8 vec_andc(vec_ushort8 a, vec_ushort8 b) -{ - return (spu_andc(a, b)); -} - -static inline vec_short8 vec_andc(vec_short8 a, vec_short8 b) -{ - return (spu_andc(a, b)); -} - -static inline vec_short8 vec_andc(vec_bshort8 a, vec_short8 b) -{ - return (spu_andc((vec_short8)(a), b)); -} - -static inline vec_short8 vec_andc(vec_short8 a, vec_bshort8 b) -{ - return (spu_andc(a, (vec_short8)(b))); -} - -static inline vec_uint4 vec_andc(vec_uint4 a, vec_uint4 b) -{ - return (spu_andc(a, b)); -} - -static inline vec_int4 vec_andc(vec_int4 a, vec_int4 b) -{ - return (spu_andc(a, b)); -} - -static inline vec_int4 vec_andc(vec_bint4 a, vec_int4 b) -{ - return (spu_andc((vec_int4)(a), b)); -} - -static inline vec_int4 vec_andc(vec_int4 a, vec_bint4 b) -{ - return (spu_andc(a, (vec_int4)(b))); -} - -static inline vec_float4 vec_andc(vec_float4 a, vec_float4 b) -{ - return (spu_andc(a,b)); -} - -static inline vec_float4 vec_andc(vec_bint4 a, vec_float4 b) -{ - return (spu_andc((vec_float4)(a),b)); -} - -static inline vec_float4 vec_andc(vec_float4 a, vec_bint4 b) -{ - return (spu_andc(a, (vec_float4)(b))); -} - -/* vec_avg (vector average) - * ======= - */ -static inline vec_uchar16 vec_avg(vec_uchar16 a, vec_uchar16 b) -{ - return (spu_avg(a, b)); -} - -static inline vec_char16 vec_avg(vec_char16 a, vec_char16 b) -{ - return ((vec_char16)(spu_xor(spu_avg((vec_uchar16)(a), (vec_uchar16)(b)), - (vec_uchar16)(spu_and(spu_xor(a,b), 0x80))))); -} - -static inline vec_ushort8 vec_avg(vec_ushort8 a, vec_ushort8 b) -{ - return (spu_add(spu_add(spu_rlmask(a, -1), spu_rlmask(b, -1)), - spu_and(spu_or(a, b), 1))); -} - -static inline vec_short8 vec_avg(vec_short8 a, vec_short8 b) -{ - return (spu_add(spu_add(spu_rlmaska(a, -1), spu_rlmaska(b, -1)), - spu_and(spu_or(a, b), 1))); -} - -static inline vec_uint4 vec_avg(vec_uint4 a, vec_uint4 b) -{ - return (spu_add(spu_add(spu_rlmask(a, -1), spu_rlmask(b, -1)), - spu_and(spu_or(a, b), 1))); -} - -static inline vec_int4 vec_avg(vec_int4 a, vec_int4 b) -{ - return (spu_add(spu_add(spu_rlmaska(a, -1), spu_rlmaska(b, -1)), - spu_and(spu_or(a, b), 1))); -} - - -/* vec_ceil (vector ceiling) - * ======== - */ -static inline vec_float4 vec_ceil(vec_float4 a) -{ - vec_int4 exp; - vec_uint4 mask; - - a = spu_add(a, (vec_float4)(spu_and(spu_xor(spu_rlmaska((vec_int4)a, -31), -1), spu_splats((signed int)0x3F7FFFFF)))); - exp = spu_sub(127, (vec_int4)(spu_and(spu_rlmask((vec_uint4)(a), -23), 0xFF))); - mask = spu_rlmask(spu_splats((unsigned int)0x7FFFFF), exp); - mask = spu_sel(spu_splats((unsigned int)0), mask, spu_cmpgt(exp, -31)); - mask = spu_or(mask, spu_xor((vec_uint4)(spu_rlmaska(spu_add(exp, -1), -31)), -1)); - - return ((vec_float4)(spu_andc((vec_uint4)(a), mask))); -} - - -/* vec_cmpb (vector compare bounds floating-point) - * ======== - */ -static inline vec_int4 vec_cmpb(vec_float4 a, vec_float4 b) -{ - vec_int4 b0 = (vec_int4)spu_splats(0x80000000); - vec_int4 b1 = (vec_int4)spu_splats(0x40000000); - - return (spu_or(spu_and((vec_int4)spu_cmpgt(a, b), b0), - spu_and((vec_int4)spu_cmpgt(spu_xor(b, (vec_float4)(b0)), a), b1))); -} - -/* vec_cmpeq (vector compare equal) - * ========= - */ -#define vec_cmpeq(_a, _b) spu_cmpeq(_a, _b) - - -/* vec_cmpge (vector compare greater than or equal) - * ========= - */ -static inline vec_bint4 vec_cmpge(vec_float4 a, vec_float4 b) -{ - return (spu_xor(spu_cmpgt(b, a), -1)); -} - - -/* vec_cmpgt (vector compare greater than) - * ========= - */ -#define vec_cmpgt(_a, _b) spu_cmpgt(_a, _b) - - -/* vec_cmple (vector compare less than or equal) - * ========= - */ -static inline vec_bint4 vec_cmple(vec_float4 a, vec_float4 b) -{ - return (spu_xor(spu_cmpgt(a, b), -1)); -} - - -/* vec_cmplt (vector compare less than) - * ========= - */ -#define vec_cmplt(_a, _b) spu_cmpgt(_b, _a) - - -/* vec_ctf (vector convert from fixed-point word) - * ======= - */ -#define vec_ctf(_a, _b) spu_convtf(_a, _b) - - -/* vec_cts (vector convert to signed fixed-point word saturate) - * ======= - */ -#define vec_cts(_a, _b) spu_convts(_a, _b) - - -/* vec_ctu (vector convert to unsigned fixed-point word saturate) - * ======= - */ -#define vec_ctu(_a, _b) spu_convtu(_a, _b) - - -/* vec_dss (vector data stream stop) - * ======= - */ -#define vec_dss(_a) - - -/* vec_dssall (vector data stream stop all) - * ========== - */ -#define vec_dssall() - - -/* vec_dst (vector data stream touch) - * ======= - */ -#define vec_dst(_a, _b, _c) - - -/* vec_dstst (vector data stream touch for store) - * ========= - */ -#define vec_dstst(_a, _b, _c) - - -/* vec_dststt (vector data stream touch for store transient) - * ========== - */ -#define vec_dststt(_a, _b, _c) - - -/* vec_dstt (vector data stream touch transient) - * ======== - */ -#define vec_dstt(_a, _b, _c) - - -/* vec_expte (vector is 2 raised tp the exponent estimate floating-point) - * ========= - */ -static inline vec_float4 vec_expte(vec_float4 a) -{ - vec_float4 bias, frac, exp; - vec_int4 ia; - - bias = (vec_float4)(spu_andc(spu_splats((signed int)0x3F7FFFFF), spu_rlmaska((vec_int4)(a), -31))); - ia = spu_convts(spu_add(a, bias), 0); - frac = spu_sub(spu_convtf(ia, 0), a); - exp = (vec_float4)(spu_sl(spu_add(ia, 127), 23)); - - return (spu_mul(spu_madd(spu_madd(spu_splats(0.17157287f), frac, spu_splats(-0.67157287f)), - frac, spu_splats(1.0f)), exp)); -} - - -/* vec_floor (vector floor) - * ========= - */ -static inline vec_float4 vec_floor(vec_float4 a) -{ - vec_int4 exp; - vec_uint4 mask; - - a = spu_sub(a, (vec_float4)(spu_and(spu_rlmaska((vec_int4)a, -31), spu_splats((signed int)0x3F7FFFFF)))); - exp = spu_sub(127, (vec_int4)(spu_and(spu_rlmask((vec_uint4)(a), -23), 0xFF))); - mask = spu_rlmask(spu_splats((unsigned int)0x7FFFFF), exp); - mask = spu_sel(spu_splats((unsigned int)0), mask, spu_cmpgt(exp, -31)); - mask = spu_or(mask, spu_xor((vec_uint4)(spu_rlmaska(spu_add(exp, -1), -31)), -1)); - - return ((vec_float4)(spu_andc((vec_uint4)(a), mask))); -} - - -/* vec_ld (vector load indexed) - * ====== - */ -static inline vec_uchar16 vec_ld(int a, unsigned char *b) -{ - return (*((vec_uchar16 *)(b+a))); -} - -static inline vec_uchar16 vec_ld(int a, vec_uchar16 *b) -{ - return (*((vec_uchar16 *)((unsigned char *)(b)+a))); -} - -static inline vec_char16 vec_ld(int a, signed char *b) -{ - return (*((vec_char16 *)(b+a))); -} - -static inline vec_char16 vec_ld(int a, vec_char16 *b) -{ - return (*((vec_char16 *)((signed char *)(b)+a))); -} - -static inline vec_ushort8 vec_ld(int a, unsigned short *b) -{ - return (*((vec_ushort8 *)((unsigned char *)(b)+a))); -} - -static inline vec_ushort8 vec_ld(int a, vec_ushort8 *b) -{ - return (*((vec_ushort8 *)((unsigned char *)(b)+a))); -} - -static inline vec_short8 vec_ld(int a, signed short *b) -{ - return (*((vec_short8 *)((unsigned char *)(b)+a))); -} - -static inline vec_short8 vec_ld(int a, vec_short8 *b) -{ - return (*((vec_short8 *)((signed char *)(b)+a))); -} - -static inline vec_uint4 vec_ld(int a, unsigned int *b) -{ - return (*((vec_uint4 *)((unsigned char *)(b)+a))); -} - -static inline vec_uint4 vec_ld(int a, vec_uint4 *b) -{ - return (*((vec_uint4 *)((unsigned char *)(b)+a))); -} - -static inline vec_int4 vec_ld(int a, signed int *b) -{ - return (*((vec_int4 *)((unsigned char *)(b)+a))); -} - -static inline vec_int4 vec_ld(int a, vec_int4 *b) -{ - return (*((vec_int4 *)((signed char *)(b)+a))); -} - -static inline vec_float4 vec_ld(int a, float *b) -{ - return (*((vec_float4 *)((unsigned char *)(b)+a))); -} - -static inline vec_float4 vec_ld(int a, vec_float4 *b) -{ - return (*((vec_float4 *)((unsigned char *)(b)+a))); -} - -/* vec_lde (vector load element indexed) - * ======= - */ -static inline vec_uchar16 vec_lde(int a, unsigned char *b) -{ - return (*((vec_uchar16 *)(b+a))); -} - -static inline vec_char16 vec_lde(int a, signed char *b) -{ - return (*((vec_char16 *)(b+a))); -} - -static inline vec_ushort8 vec_lde(int a, unsigned short *b) -{ - return (*((vec_ushort8 *)((unsigned char *)(b)+a))); -} - -static inline vec_short8 vec_lde(int a, signed short *b) -{ - return (*((vec_short8 *)((unsigned char *)(b)+a))); -} - - -static inline vec_uint4 vec_lde(int a, unsigned int *b) -{ - return (*((vec_uint4 *)((unsigned char *)(b)+a))); -} - -static inline vec_int4 vec_lde(int a, signed int *b) -{ - return (*((vec_int4 *)((unsigned char *)(b)+a))); -} - - -static inline vec_float4 vec_lde(int a, float *b) -{ - return (*((vec_float4 *)((unsigned char *)(b)+a))); -} - -/* vec_ldl (vector load indexed LRU) - * ======= - */ -#define vec_ldl(_a, _b) vec_ld(_a, _b) - - -/* vec_loge (vector log2 estimate floating-point) - * ======== - */ -static inline vec_float4 vec_loge(vec_float4 a) -{ - vec_int4 exp; - vec_float4 frac; - - exp = spu_add((vec_int4)(spu_and(spu_rlmask((vec_uint4)(a), -23), 0xFF)), -127); - frac = (vec_float4)(spu_sub((vec_int4)(a), spu_sl(exp, 23))); - - return (spu_madd(spu_madd(spu_splats(-0.33985f), frac, spu_splats(2.01955f)), - frac, spu_sub(spu_convtf(exp, 0), spu_splats(1.6797f)))); -} - - -/* vec_lvsl (vector load for shift left) - * ======== - */ -static inline vec_uchar16 vec_lvsl(int a, unsigned char *b) -{ - return ((vec_uchar16)spu_add((vec_ushort8)(spu_splats((unsigned char)((a + (int)(b)) & 0xF))), - ((vec_ushort8){0x0001, 0x0203, 0x0405, 0x0607, - 0x0809, 0x0A0B, 0x0C0D, 0x0E0F}))); -} - -static inline vec_uchar16 vec_lvsl(int a, signed char *b) -{ - return (vec_lvsl(a, (unsigned char *)b)); -} - -static inline vec_uchar16 vec_lvsl(int a, unsigned short *b) -{ - return (vec_lvsl(a, (unsigned char *)b)); -} - -static inline vec_uchar16 vec_lvsl(int a, short *b) -{ - return (vec_lvsl(a, (unsigned char *)b)); -} - -static inline vec_uchar16 vec_lvsl(int a, unsigned int *b) -{ - return (vec_lvsl(a, (unsigned char *)b)); -} - -static inline vec_uchar16 vec_lvsl(int a, int *b) -{ - return (vec_lvsl(a, (unsigned char *)b)); -} - -static inline vec_uchar16 vec_lvsl(int a, float *b) -{ - return (vec_lvsl(a, (unsigned char *)b)); -} - - -/* vec_lvsr (vector load for shift right) - * ======== - */ -static inline vec_uchar16 vec_lvsr(int a, unsigned char *b) -{ - return ((vec_uchar16)(spu_sub(((vec_ushort8){0x1011, 0x1213, 0x1415, 0x1617, - 0x1819, 0x1A1B, 0x1C1D, 0x1E1F}), - (vec_ushort8)(spu_splats((unsigned char)((a + (int)(b)) & 0xF)))))); -} - -static inline vec_uchar16 vec_lvsr(int a, signed char *b) -{ - return (vec_lvsr(a, (unsigned char *)b)); -} - -static inline vec_uchar16 vec_lvsr(int a, unsigned short *b) -{ - return (vec_lvsr(a, (unsigned char *)b)); -} - -static inline vec_uchar16 vec_lvsr(int a, short *b) -{ - return (vec_lvsr(a, (unsigned char *)b)); -} - -static inline vec_uchar16 vec_lvsr(int a, unsigned int *b) -{ - return (vec_lvsr(a, (unsigned char *)b)); -} - -static inline vec_uchar16 vec_lvsr(int a, int *b) -{ - return (vec_lvsr(a, (unsigned char *)b)); -} - -static inline vec_uchar16 vec_lvsr(int a, float *b) -{ - return (vec_lvsr(a, (unsigned char *)b)); -} - -/* vec_madd (vector multiply add) - * ======== - */ -#define vec_madd(_a, _b, _c) spu_madd(_a, _b, _c) - - - -/* vec_madds (vector multiply add saturate) - * ========= - */ -static inline vec_short8 vec_madds(vec_short8 a, vec_short8 b, vec_short8 c) -{ - return (vec_adds(c, spu_sel((vec_short8)(spu_sl(spu_mule(a, b), 1)), - (vec_short8)(spu_rlmask(spu_mulo(a, b), -15)), - ((vec_ushort8){0, 0xFFFF, 0, 0xFFFF, 0, 0xFFFF, 0, 0xFFFF})))); -} - -/* vec_max (vector maximum) - * ======= - */ -static inline vec_uchar16 vec_max(vec_uchar16 a, vec_uchar16 b) -{ - return (spu_sel(b, a, spu_cmpgt(a, b))); -} - -static inline vec_char16 vec_max(vec_char16 a, vec_char16 b) -{ - return (spu_sel(b, a, spu_cmpgt(a, b))); -} - -static inline vec_char16 vec_max(vec_bchar16 a, vec_char16 b) -{ - return (spu_sel(b, (vec_char16)(a), spu_cmpgt((vec_char16)(a), b))); -} - -static inline vec_char16 vec_max(vec_char16 a, vec_bchar16 b) -{ - return (spu_sel((vec_char16)(b), a, spu_cmpgt(a, (vec_char16)(b)))); -} - -static inline vec_ushort8 vec_max(vec_ushort8 a, vec_ushort8 b) -{ - return (spu_sel(b, a, spu_cmpgt(a, b))); -} - -static inline vec_short8 vec_max(vec_short8 a, vec_short8 b) -{ - return (spu_sel(b, a, spu_cmpgt(a, b))); -} - -static inline vec_short8 vec_max(vec_bshort8 a, vec_short8 b) -{ - return (spu_sel(b, (vec_short8)(a), spu_cmpgt((vec_short8)(a), b))); -} - -static inline vec_short8 vec_max(vec_short8 a, vec_bshort8 b) -{ - return (spu_sel((vec_short8)(b), a, spu_cmpgt(a, (vec_short8)(b)))); -} - -static inline vec_uint4 vec_max(vec_uint4 a, vec_uint4 b) -{ - return (spu_sel(b, a, spu_cmpgt(a, b))); -} - -static inline vec_int4 vec_max(vec_int4 a, vec_int4 b) -{ - return (spu_sel(b, a, spu_cmpgt(a, b))); -} - -static inline vec_int4 vec_max(vec_bint4 a, vec_int4 b) -{ - return (spu_sel(b, (vec_int4)(a), spu_cmpgt((vec_int4)(a), b))); -} - -static inline vec_int4 vec_max(vec_int4 a, vec_bint4 b) -{ - return (spu_sel((vec_int4)(b), a, spu_cmpgt(a, (vec_int4)(b)))); -} - -static inline vec_float4 vec_max(vec_float4 a, vec_float4 b) -{ - return (spu_sel(b, a, spu_cmpgt(a, b))); -} - - -/* vec_mergeh (vector merge high) - * ========== - */ -static inline vec_uchar16 vec_mergeh(vec_uchar16 a, vec_uchar16 b) -{ - return (spu_shuffle(a, b, ((vec_uchar16){0, 16, 1, 17, 2, 18, 3, 19, - 4, 20, 5, 21, 6, 22, 7, 23}))); -} - -static inline vec_char16 vec_mergeh(vec_char16 a, vec_char16 b) -{ - return (spu_shuffle(a, b, ((vec_uchar16){0, 16, 1, 17, 2, 18, 3, 19, - 4, 20, 5, 21, 6, 22, 7, 23}))); -} - -static inline vec_ushort8 vec_mergeh(vec_ushort8 a, vec_ushort8 b) -{ - return (spu_shuffle(a, b, ((vec_uchar16){0, 1, 16, 17, 2, 3, 18, 19, - 4, 5, 20, 21, 6, 7, 22, 23}))); -} - -static inline vec_short8 vec_mergeh(vec_short8 a, vec_short8 b) -{ - return (spu_shuffle(a, b, ((vec_uchar16){0, 1, 16, 17, 2, 3, 18, 19, - 4, 5, 20, 21, 6, 7, 22, 23}))); -} - -static inline vec_uint4 vec_mergeh(vec_uint4 a, vec_uint4 b) -{ - return (spu_shuffle(a, b, ((vec_uchar16){0, 1, 2, 3, 16, 17, 18, 19, - 4, 5, 6, 7, 20, 21, 22, 23}))); -} - -static inline vec_int4 vec_mergeh(vec_int4 a, vec_int4 b) -{ - return (spu_shuffle(a, b, ((vec_uchar16){0, 1, 2, 3, 16, 17, 18, 19, - 4, 5, 6, 7, 20, 21, 22, 23}))); -} - -static inline vec_float4 vec_mergeh(vec_float4 a, vec_float4 b) -{ - return (spu_shuffle(a, b, ((vec_uchar16){0, 1, 2, 3, 16, 17, 18, 19, - 4, 5, 6, 7, 20, 21, 22, 23}))); -} - -/* vec_mergel (vector merge low) - * ========== - */ -static inline vec_uchar16 vec_mergel(vec_uchar16 a, vec_uchar16 b) -{ - return (spu_shuffle(a, b, ((vec_uchar16){ 8, 24, 9, 25, 10, 26, 11, 27, - 12, 28, 13, 29, 14, 30, 15, 31}))); -} - -static inline vec_char16 vec_mergel(vec_char16 a, vec_char16 b) -{ - return (spu_shuffle(a, b, ((vec_uchar16){ 8, 24, 9, 25, 10, 26, 11, 27, - 12, 28, 13, 29, 14, 30, 15, 31}))); -} - -static inline vec_ushort8 vec_mergel(vec_ushort8 a, vec_ushort8 b) -{ - return (spu_shuffle(a, b, ((vec_uchar16){ 8, 9, 24, 25, 10, 11, 26, 27, - 12, 13, 28, 29, 14, 15, 30, 31}))); -} - -static inline vec_short8 vec_mergel(vec_short8 a, vec_short8 b) -{ - return (spu_shuffle(a, b, ((vec_uchar16){ 8, 9, 24, 25, 10, 11, 26, 27, - 12, 13, 28, 29, 14, 15, 30, 31}))); -} - -static inline vec_uint4 vec_mergel(vec_uint4 a, vec_uint4 b) -{ - return (spu_shuffle(a, b, ((vec_uchar16){ 8, 9, 10, 11, 24, 25, 26, 27, - 12, 13, 14, 15, 28, 29, 30, 31}))); -} - -static inline vec_int4 vec_mergel(vec_int4 a, vec_int4 b) -{ - return (spu_shuffle(a, b, ((vec_uchar16){ 8, 9, 10, 11, 24, 25, 26, 27, - 12, 13, 14, 15, 28, 29, 30, 31}))); -} - -static inline vec_float4 vec_mergel(vec_float4 a, vec_float4 b) -{ - return (spu_shuffle(a, b, ((vec_uchar16){ 8, 9, 10, 11, 24, 25, 26, 27, - 12, 13, 14, 15, 28, 29, 30, 31}))); -} - -/* vec_mfvscr (vector move from vector status and control register) - * ========== - */ -static inline vec_ushort8 vec_mfvscr() -{ - return ((vec_ushort8)spu_splats(0)); /* not supported */ -} - - -/* vec_min (vector minimum) - * ======= - */ -static inline vec_uchar16 vec_min(vec_uchar16 a, vec_uchar16 b) -{ - return (spu_sel(a, b, spu_cmpgt(a, b))); -} - -static inline vec_char16 vec_min(vec_char16 a, vec_char16 b) -{ - return (spu_sel(a, b, spu_cmpgt(a, b))); -} - -static inline vec_char16 vec_min(vec_bchar16 a, vec_char16 b) -{ - return (spu_sel((vec_char16)(a), b, spu_cmpgt((vec_char16)(a), b))); -} - -static inline vec_char16 vec_min(vec_char16 a, vec_bchar16 b) -{ - return (spu_sel(a, (vec_char16)(b), spu_cmpgt(a, (vec_char16)(b)))); -} - -static inline vec_ushort8 vec_min(vec_ushort8 a, vec_ushort8 b) -{ - return (spu_sel(a, b, spu_cmpgt(a, b))); -} - -static inline vec_short8 vec_min(vec_short8 a, vec_short8 b) -{ - return (spu_sel(a, b, spu_cmpgt(a, b))); -} - -static inline vec_short8 vec_min(vec_bshort8 a, vec_short8 b) -{ - return (spu_sel((vec_short8)(a), b, spu_cmpgt((vec_short8)(a), b))); -} - -static inline vec_short8 vec_min(vec_short8 a, vec_bshort8 b) -{ - return (spu_sel(a, (vec_short8)(b), spu_cmpgt(a, (vec_short8)(b)))); -} - -static inline vec_uint4 vec_min(vec_uint4 a, vec_uint4 b) -{ - return (spu_sel(a, b, spu_cmpgt(a, b))); -} - -static inline vec_int4 vec_min(vec_int4 a, vec_int4 b) -{ - return (spu_sel(a, b, spu_cmpgt(a, b))); -} - -static inline vec_int4 vec_min(vec_bint4 a, vec_int4 b) -{ - return (spu_sel((vec_int4)(a), b, spu_cmpgt((vec_int4)(a), b))); -} - -static inline vec_int4 vec_min(vec_int4 a, vec_bint4 b) -{ - return (spu_sel(a, (vec_int4)(b), spu_cmpgt(a, (vec_int4)(b)))); -} - -static inline vec_float4 vec_min(vec_float4 a, vec_float4 b) -{ - return (spu_sel(a, b, spu_cmpgt(a, b))); -} - -/* vec_mladd (vector multiply low and add unsigned half word) - * ========= - */ -static inline vec_short8 vec_mladd(vec_short8 a, vec_short8 b, vec_short8 c) -{ - return ((vec_short8)(spu_shuffle(spu_madd((vec_short8)(spu_rl((vec_uint4)(a), -16)), - (vec_short8)(spu_rl((vec_uint4)(b), -16)), - (vec_int4)(spu_rl((vec_uint4)(c), -16))), - spu_madd(a, b, spu_extend(c)), - ((vec_uchar16){ 2, 3, 18, 19, 6, 7, 22, 23, - 10, 11, 26, 27, 14, 15, 30, 31})))); -} - - -static inline vec_ushort8 vec_mladd(vec_ushort8 a, vec_ushort8 b, vec_ushort8 c) -{ - return ((vec_ushort8)(vec_mladd((vec_short8)(a), (vec_short8)(b), (vec_short8)(c)))); -} - -static inline vec_short8 vec_mladd(vec_ushort8 a, vec_short8 b, vec_short8 c) -{ - return (vec_mladd((vec_short8)(a), b, c)); -} - -static inline vec_short8 vec_mladd(vec_short8 a, vec_ushort8 b, vec_ushort8 c) -{ - return (vec_mladd(a, (vec_short8)(b), (vec_short8)(c))); -} - - -/* vec_mradds (vector multiply round and add saturate) - * ========== - */ -static inline vec_short8 vec_mradds(vec_short8 a, vec_short8 b, vec_short8 c) -{ - vec_int4 round = (vec_int4)spu_splats(0x4000); - vec_short8 hi, lo; - - hi = (vec_short8)(spu_sl(spu_add(spu_mule(a, b), round), 1)); - lo = (vec_short8)(spu_rlmask(spu_add(spu_mulo(a, b), round), -15)); - - return (vec_adds(spu_sel(hi, lo, ((vec_ushort8){0, 0xFFFF, 0, 0xFFFF, 0, 0xFFFF, 0, 0xFFFF})), c)); -} - - -/* vec_msum (vector multiply sum) - * ======== - */ -static inline vec_uint4 vec_msum(vec_uchar16 a, vec_uchar16 b, vec_uint4 c) -{ - vec_ushort8 a1, a2, b1, b2; - vec_uint4 p1, p2; - - a1 = spu_and((vec_ushort8)(a), 0xFF); - a2 = spu_rlmask((vec_ushort8)(a), -8); - b1 = spu_and((vec_ushort8)(b), 0xFF); - b2 = spu_rlmask((vec_ushort8)(b), -8); - - p1 = spu_add(spu_mulo(a1, b1), spu_mulo(spu_rlqwbyte(a1, -2), spu_rlqwbyte(b1, -2))); - p2 = spu_add(spu_mulo(a2, b2), spu_mulo(spu_rlqwbyte(a2, -2), spu_rlqwbyte(b2, -2))); - return (spu_add(p2, spu_add(p1, c))); -} - -static inline vec_int4 vec_msum(vec_char16 a, vec_uchar16 b, vec_int4 c) -{ - vec_short8 a1, a2, b1, b2; - vec_int4 p1, p2; - - a1 = (vec_short8)(spu_extend(a)); - a2 = spu_rlmaska((vec_short8)(a), -8); - b1 = (vec_short8)(spu_and((vec_ushort8)(b), 0xFF)); - b2 = (vec_short8)spu_rlmask((vec_ushort8)(b), -8); - - p1 = spu_add(spu_mulo(a1, b1), spu_mulo(spu_rlqwbyte(a1, -2), spu_rlqwbyte(b1, -2))); - p2 = spu_add(spu_mulo(a2, b2), spu_mulo(spu_rlqwbyte(a2, -2), spu_rlqwbyte(b2, -2))); - return (spu_add(p2, spu_add(p1, c))); -} - -static inline vec_uint4 vec_msum(vec_ushort8 a, vec_ushort8 b, vec_uint4 c) -{ - return (spu_add(spu_add(spu_mulo(a, b), spu_mulo(spu_rlqwbyte(a, -2), spu_rlqwbyte(b, -2))), c)); -} - -static inline vec_int4 vec_msum(vec_short8 a, vec_short8 b, vec_int4 c) -{ - return (spu_add(spu_add(spu_mulo(a, b), spu_mulo(spu_rlqwbyte(a, -2), spu_rlqwbyte(b, -2))), c)); -} - - -/* vec_msums (vector multiply sum saturate) - * ======== - */ -static inline vec_uint4 vec_msums(vec_ushort8 a, vec_ushort8 b, vec_uint4 c) -{ - vec_uint4 p1, p2; - - p1 = spu_mulo(a, b); - p2 = spu_mulo(spu_rlqwbyte(a, -2), spu_rlqwbyte(b, -2)); - - return (vec_adds(p2, vec_adds(p1, c))); -} - -static inline vec_int4 vec_msums(vec_short8 a, vec_short8 b, vec_int4 c) -{ - return (vec_adds(spu_add(spu_mulo(a, b), spu_mulo(spu_rlqwbyte(a, -2), spu_rlqwbyte(b, -2))), c)); -} - -/* vec_mtvscr (vector move to vector status and control register) - * ========== - */ -#define vec_mtvscr(_a) /* not supported */ - - -/* vec_mule (vector multiply even) - * ======== - */ -static inline vec_ushort8 vec_mule(vec_uchar16 a, vec_uchar16 b) -{ - vec_ushort8 hi, lo; - - hi = (vec_ushort8)spu_mulo((vec_ushort8)(spu_rlmask((vec_uint4)(a), -24)), - (vec_ushort8)(spu_rlmask((vec_uint4)(b), -24))); - lo = (vec_ushort8)spu_mulo((vec_ushort8)(spu_rlmask((vec_short8)(a), -8)), - (vec_ushort8)(spu_rlmask((vec_short8)(b), -8))); - - return (spu_shuffle(hi, lo, ((vec_uchar16){ 2, 3, 18, 19, 6, 7, 22, 23, - 10, 11, 26, 27, 14, 15, 30, 31}))); -} - -static inline vec_short8 vec_mule(vec_char16 a, vec_char16 b) -{ - vec_short8 hi, lo; - - hi = (vec_short8)spu_mulo((vec_short8)(spu_rlmaska((vec_uint4)(a), -24)), - (vec_short8)(spu_rlmaska((vec_uint4)(b), -24))); - lo = (vec_short8)spu_mulo((vec_short8)(spu_rlmaska((vec_short8)(a), -8)), - (vec_short8)(spu_rlmaska((vec_short8)(b), -8))); - - return (spu_shuffle(hi, lo, ((vec_uchar16){ 2, 3, 18, 19, 6, 7, 22, 23, - 10, 11, 26, 27, 14, 15, 30, 31}))); -} - -static inline vec_uint4 vec_mule(vec_ushort8 a, vec_ushort8 b) -{ - return (spu_mulo((vec_ushort8)spu_rlmask((vec_uint4)(a), -16), - (vec_ushort8)spu_rlmask((vec_uint4)(b), -16))); -} - - -static inline vec_int4 vec_mule(vec_short8 a, vec_short8 b) -{ - return (spu_mulo((vec_short8)spu_rlmaska((vec_int4)(a), -16), - (vec_short8)spu_rlmaska((vec_int4)(b), -16))); -} - - -/* vec_mulo (vector multiply odd) - * ======== - */ -static inline vec_ushort8 vec_mulo(vec_uchar16 a, vec_uchar16 b) -{ - vec_ushort8 hi, lo; - - hi = (vec_ushort8)spu_mulo((vec_ushort8)(spu_and(spu_rlmask((vec_uint4)(a), -16), 0xFF)), - (vec_ushort8)(spu_and(spu_rlmask((vec_uint4)(b), -16), 0xFF))); - lo = (vec_ushort8)spu_mulo(spu_and((vec_ushort8)(a), 0xFF), spu_and((vec_ushort8)(b), 0xFF)); - - return (spu_shuffle(hi, lo, ((vec_uchar16){ 2, 3, 18, 19, 6, 7, 22, 23, - 10, 11, 26, 27, 14, 15, 30, 31}))); -} - -static inline vec_short8 vec_mulo(vec_char16 a, vec_char16 b) -{ - vec_short8 aa, bb, hi, lo; - - aa = spu_extend(a); - bb = spu_extend(b); - - hi = (vec_short8)spu_mulo((vec_short8)(spu_rlmaska((vec_uint4)(aa), -16)), - (vec_short8)(spu_rlmaska((vec_uint4)(bb), -16))); - lo = (vec_short8)spu_mulo(aa, bb); - return (spu_shuffle(hi, lo, ((vec_uchar16){ 2, 3, 18, 19, 6, 7, 22, 23, - 10, 11, 26, 27, 14, 15, 30, 31}))); -} - -static inline vec_uint4 vec_mulo(vec_ushort8 a, vec_ushort8 b) -{ - return (spu_mulo(a, b)); -} - - -static inline vec_int4 vec_mulo(vec_short8 a, vec_short8 b) -{ - return (spu_mulo(a, b)); -} - - -/* vec_nmsub (vector negative multiply subtract) - * ========= - */ -#define vec_nmsub(_a, _b, _c) spu_nmsub(_a, _b, _c) - - -/* vec_nor (vector logical nor) - * ======= - */ -#define vec_nor(_a, _b) spu_nor(_a, _b) - - -/* vec_or (vector logical or) - * ====== - */ -static inline vec_uchar16 vec_or(vec_uchar16 a, vec_uchar16 b) -{ - return (spu_or(a, b)); -} - -static inline vec_char16 vec_or(vec_char16 a, vec_char16 b) -{ - return (spu_or(a, b)); -} - -static inline vec_char16 vec_or(vec_bchar16 a, vec_char16 b) -{ - return (spu_or((vec_char16)(a), b)); -} - -static inline vec_char16 vec_or(vec_char16 a, vec_bchar16 b) -{ - return (spu_or(a, (vec_char16)(b))); -} - -static inline vec_ushort8 vec_or(vec_ushort8 a, vec_ushort8 b) -{ - return (spu_or(a, b)); -} - -static inline vec_short8 vec_or(vec_short8 a, vec_short8 b) -{ - return (spu_or(a, b)); -} - -static inline vec_short8 vec_or(vec_bshort8 a, vec_short8 b) -{ - return (spu_or((vec_short8)(a), b)); -} - -static inline vec_short8 vec_or(vec_short8 a, vec_bshort8 b) -{ - return (spu_or(a, (vec_short8)(b))); -} - -static inline vec_uint4 vec_or(vec_uint4 a, vec_uint4 b) -{ - return (spu_or(a, b)); -} - -static inline vec_int4 vec_or(vec_int4 a, vec_int4 b) -{ - return (spu_or(a, b)); -} - -static inline vec_int4 vec_or(vec_bint4 a, vec_int4 b) -{ - return (spu_or((vec_int4)(a), b)); -} - -static inline vec_int4 vec_or(vec_int4 a, vec_bint4 b) -{ - return (spu_or(a, (vec_int4)(b))); -} - -static inline vec_float4 vec_or(vec_float4 a, vec_float4 b) -{ - return (spu_or(a, b)); -} - -static inline vec_float4 vec_or(vec_bint4 a, vec_float4 b) -{ - return (spu_or((vec_float4)(a),b)); -} - -static inline vec_float4 vec_or(vec_float4 a, vec_bint4 b) -{ - return (spu_or(a, (vec_float4)(b))); -} - - -/* vec_pack (vector pack) - * ======== - */ -static inline vec_uchar16 vec_pack(vec_ushort8 a, vec_ushort8 b) -{ - return ((vec_uchar16)spu_shuffle(a, b, ((vec_uchar16){ 1, 3, 5, 7, 9, 11, 13, 15, - 17, 19, 21, 23, 25, 27, 29, 31}))); -} - -static inline vec_char16 vec_pack(vec_short8 a, vec_short8 b) -{ - return ((vec_char16)spu_shuffle(a, b, ((vec_uchar16){ 1, 3, 5, 7, 9, 11, 13, 15, - 17, 19, 21, 23, 25, 27, 29, 31}))); -} - -static inline vec_ushort8 vec_pack(vec_uint4 a, vec_uint4 b) -{ - return ((vec_ushort8)spu_shuffle(a, b, ((vec_uchar16){ 2, 3, 6, 7, 10, 11, 14, 15, - 18, 19, 22, 23, 26, 27, 30, 31}))); -} - -static inline vec_short8 vec_pack(vec_int4 a, vec_int4 b) -{ - return ((vec_short8)spu_shuffle(a, b, ((vec_uchar16){ 2, 3, 6, 7, 10, 11, 14, 15, - 18, 19, 22, 23, 26, 27, 30, 31}))); -} - - -/* vec_packpx (vector pack pixel) - * ========== - */ -static inline vec_pixel8 vec_packpx(vec_uint4 a, vec_uint4 b) -{ - vec_uint4 x03FF = (vec_uint4)(spu_splats((unsigned short)0x03FF)); - vec_uint4 x001F = (vec_uint4)(spu_splats((unsigned short)0x001F)); - - return ((vec_pixel8)(spu_shuffle(spu_sel(spu_sel(spu_sl(a, 7), spu_sl(a, 10), x03FF), - spu_sl(a, 13), x001F), - spu_sel(spu_sel(spu_sl(b, 7), spu_sl(b, 10), x03FF), - spu_sl(b, 13), x001F), - ((vec_uchar16){ 0, 1, 4, 5, 8, 9, 12, 13, - 16, 17, 20, 21, 24, 25, 28, 29})))); -} - - -/* vec_packs (vector pack saturate) - * ========= - */ -static inline vec_uchar16 vec_packs(vec_ushort8 a, vec_ushort8 b) -{ - vec_ushort8 max = spu_splats((unsigned short)0x00FF); - - return ((vec_uchar16)(spu_shuffle(spu_sel(a, max, spu_cmpgt(a, 255)), - spu_sel(b, max, spu_cmpgt(b, 255)), - ((vec_uchar16){ 1, 3, 5, 7, 9, 11, 13, 15, - 17, 19, 21, 23, 25, 27, 29, 31})))); -} - -static inline vec_char16 vec_packs(vec_short8 a, vec_short8 b) -{ - vec_short8 max = spu_splats((signed short)0x007F); - vec_short8 min = spu_splats((signed short)0xFF80); - - return ((vec_char16)(spu_shuffle(spu_sel(min, spu_sel(a, max, spu_cmpgt(a, 127)), spu_cmpgt(a, -128)), - spu_sel(min, spu_sel(b, max, spu_cmpgt(b, 127)), spu_cmpgt(b, -128)), - ((vec_uchar16){ 1, 3, 5, 7, 9, 11, 13, 15, - 17, 19, 21, 23, 25, 27, 29, 31})))); -} - -static inline vec_ushort8 vec_packs(vec_uint4 a, vec_uint4 b) -{ - vec_uint4 max = spu_splats((unsigned int)0x0000FFFF); - - return ((vec_ushort8)(spu_shuffle(spu_sel(a, max, spu_cmpgt(a, max)), - spu_sel(b, max, spu_cmpgt(b, max)), - ((vec_uchar16){ 2, 3, 6, 7, 10, 11, 14, 15, - 18, 19, 22, 23, 26, 27, 30, 31})))); -} - -static inline vec_short8 vec_packs(vec_int4 a, vec_int4 b) -{ - vec_int4 max = spu_splats((signed int)0x00007FFF); - vec_int4 min = spu_splats((signed int)0xFFFF8000); - - return ((vec_short8)(spu_shuffle(spu_sel(min, spu_sel(a, max, spu_cmpgt(a, max)), spu_cmpgt(a, min)), - spu_sel(min, spu_sel(b, max, spu_cmpgt(b, max)), spu_cmpgt(b, min)), - ((vec_uchar16){ 2, 3, 6, 7, 10, 11, 14, 15, - 18, 19, 22, 23, 26, 27, 30, 31})))); -} - - -/* vec_packsu (vector pack saturate unsigned) - * ========== - */ -static inline vec_uchar16 vec_packsu(vec_ushort8 a, vec_ushort8 b) -{ - return ((vec_uchar16)spu_shuffle(spu_or(a, (vec_ushort8)(spu_cmpgt(a, 255))), - spu_or(b, (vec_ushort8)(spu_cmpgt(b, 255))), - ((vec_uchar16){ 1, 3, 5, 7, 9, 11, 13, 15, - 17, 19, 21, 23, 25, 27, 29, 31}))); -} - -static inline vec_uchar16 vec_packsu(vec_short8 a, vec_short8 b) -{ - vec_short8 max = spu_splats((signed short)0x00FF); - vec_short8 min = spu_splats((signed short)0x0000); - - return ((vec_uchar16)(spu_shuffle(spu_sel(min, spu_sel(a, max, spu_cmpgt(a, 255)), spu_cmpgt(a, 0)), - spu_sel(min, spu_sel(b, max, spu_cmpgt(b, 255)), spu_cmpgt(b, 0)), - ((vec_uchar16){ 1, 3, 5, 7, 9, 11, 13, 15, - 17, 19, 21, 23, 25, 27, 29, 31})))); - - return (vec_packsu((vec_ushort8)(a), (vec_ushort8)(b))); -} - -static inline vec_ushort8 vec_packsu(vec_uint4 a, vec_uint4 b) -{ - vec_uint4 max = spu_splats((unsigned int)0xFFFF); - - return ((vec_ushort8)spu_shuffle(spu_or(a, (vec_uint4)(spu_cmpgt(a, max))), - spu_or(b, (vec_uint4)(spu_cmpgt(b, max))), - ((vec_uchar16){ 2, 3, 6, 7, 10, 11, 14, 15, - 18, 19, 22, 23, 26, 27, 30, 31}))); -} - -static inline vec_ushort8 vec_packsu(vec_int4 a, vec_int4 b) -{ - vec_int4 max = spu_splats((signed int)0x0000FFFF); - vec_int4 min = spu_splats((signed int)0x00000000); - - return ((vec_ushort8)(spu_shuffle(spu_sel(min, spu_sel(a, max, spu_cmpgt(a, max)), spu_cmpgt(a, min)), - spu_sel(min, spu_sel(b, max, spu_cmpgt(b, max)), spu_cmpgt(b, min)), - ((vec_uchar16){ 2, 3, 6, 7, 10, 11, 14, 15, - 18, 19, 22, 23, 26, 27, 30, 31})))); -} - - -/* vec_perm (vector permute) - * ======== - */ -static inline vec_uchar16 vec_perm(vec_uchar16 a, vec_uchar16 b, vec_uchar16 c) -{ - return (spu_shuffle(a, b, spu_and(c, 0x1F))); -} - -static inline vec_char16 vec_perm(vec_char16 a, vec_char16 b, vec_uchar16 c) -{ - return ((vec_char16)(vec_perm((vec_uchar16)(a), (vec_uchar16)(b), c))); -} - -static inline vec_ushort8 vec_perm(vec_ushort8 a, vec_ushort8 b, vec_uchar16 c) -{ - return ((vec_ushort8)(vec_perm((vec_uchar16)(a), (vec_uchar16)(b), c))); -} - -static inline vec_short8 vec_perm(vec_short8 a, vec_short8 b, vec_uchar16 c) -{ - return ((vec_short8)(vec_perm((vec_uchar16)(a), (vec_uchar16)(b), c))); -} - -static inline vec_uint4 vec_perm(vec_uint4 a, vec_uint4 b, vec_uchar16 c) -{ - return ((vec_uint4)(vec_perm((vec_uchar16)(a), (vec_uchar16)(b), c))); -} - -static inline vec_int4 vec_perm(vec_int4 a, vec_int4 b, vec_uchar16 c) -{ - return ((vec_int4)(vec_perm((vec_uchar16)(a), (vec_uchar16)(b), c))); -} - -static inline vec_float4 vec_perm(vec_float4 a, vec_float4 b, vec_uchar16 c) -{ - return ((vec_float4)(vec_perm((vec_uchar16)(a), (vec_uchar16)(b), c))); -} - - -/* vec_re (vector reciprocal estimate) - * ====== - */ -#define vec_re(_a) spu_re(_a) - - -/* vec_rl (vector rotate left) - * ====== - */ -static inline vec_uchar16 vec_rl(vec_uchar16 a, vec_uchar16 b) -{ - vec_ushort8 r1, r2; - - r1 = spu_rl(spu_and((vec_ushort8)(a), 0xFF), (vec_short8)spu_and((vec_ushort8)(b), 7)); - r2 = spu_rl(spu_and((vec_ushort8)(a), -256), (vec_short8)spu_and(spu_rlmask((vec_ushort8)(b), -8), 7)); - return ((vec_uchar16)(spu_sel(spu_or(r2, spu_sl(r2, 8)), spu_or(r1, spu_rlmask(r1, -8)), spu_splats((unsigned short)0xFF)))); -} - -static inline vec_char16 vec_rl(vec_char16 a, vec_uchar16 b) -{ - return ((vec_char16)(vec_rl((vec_uchar16)(a), b))); -} - -static inline vec_ushort8 vec_rl(vec_ushort8 a, vec_ushort8 b) -{ - return (spu_rl(a, (vec_short8)(b))); -} - -static inline vec_short8 vec_rl(vec_short8 a, vec_ushort8 b) -{ - return (spu_rl(a, (vec_short8)(b))); -} - -static inline vec_uint4 vec_rl(vec_uint4 a, vec_uint4 b) -{ - return (spu_rl(a, (vec_int4)(b))); -} - -static inline vec_int4 vec_rl(vec_int4 a, vec_uint4 b) -{ - return (spu_rl(a, (vec_int4)(b))); -} - - -/* vec_round (vector round) - * ========= - */ -static inline vec_float4 vec_round(vec_float4 a) -{ - vec_float4 s_half, s_one, d; - vec_uint4 odd; - vec_uint4 msb = spu_splats((unsigned int)0x80000000); - vec_float4 half = spu_splats(0.5f); - vec_int4 exp; - vec_uint4 mask; - - s_half = (vec_float4)(spu_sel((vec_uint4)(half), (vec_uint4)(a), msb)); - a = spu_add(a, s_half); - s_one = spu_add(s_half, s_half); - exp = spu_sub(127, (vec_int4)(spu_and(spu_rlmask((vec_uint4)(a), -23), 0xFF))); - mask = spu_rlmask(spu_splats((unsigned int)0x7FFFFF), exp); - mask = spu_sel(spu_splats((unsigned int)0), mask, spu_cmpgt(exp, -31)); - mask = spu_or(mask, spu_xor((vec_uint4)(spu_rlmaska(spu_add(exp, -1), -31)), -1)); - - odd = spu_and((vec_uint4)(spu_convts(a, 0)), 1); - s_one = spu_andc(s_one, (vec_float4)spu_cmpeq(mask, 0)); - s_one = spu_and(s_one, spu_and((vec_float4)spu_cmpeq(spu_and((vec_uint4)(a), mask), 0), - (vec_float4)spu_cmpeq(odd, 1))); - d = spu_andc(a, (vec_float4)(mask)); - d = spu_sub(d, s_one); - return (d); -} - -/* vec_rsqrte (vector reciprocal square root estimate) - * ========== - */ -#define vec_rsqrte(_a) spu_rsqrte(_a) - - -/* vec_sel (vector select) - * ======= - */ -#define vec_sel(_a, _b, _c) spu_sel(_a, _b, _c) - - -/* vec_sl (vector shift left) - * ====== - */ -static inline vec_uchar16 vec_sl(vec_uchar16 a, vec_uchar16 b) -{ - vec_ushort8 hi, lo; - - lo = spu_and(spu_sl((vec_ushort8)(a), spu_and((vec_ushort8)(b), 7)), 0xFF); - hi = spu_sl(spu_and((vec_ushort8)(a), -256), spu_and(spu_rlmask((vec_ushort8)(b), -8), 7)); - - return ((vec_uchar16)(spu_or(hi, lo))); -} - -static inline vec_char16 vec_sl(vec_char16 a, vec_uchar16 b) -{ - return ((vec_char16)(vec_sl((vec_uchar16)(a), b))); -} - -static inline vec_ushort8 vec_sl(vec_ushort8 a, vec_ushort8 b) -{ - return (spu_sl(a, spu_and(b, 15))); -} - -static inline vec_short8 vec_sl(vec_short8 a, vec_ushort8 b) -{ - return (spu_sl(a, spu_and((vec_ushort8)(b), 15))); -} - -static inline vec_uint4 vec_sl(vec_uint4 a, vec_uint4 b) -{ - return (spu_sl(a, spu_and(b, 31))); -} - -static inline vec_int4 vec_sl(vec_int4 a, vec_uint4 b) -{ - return (spu_sl(a, spu_and(b, 31))); -} - - -/* vec_sld (vector shift left double) - * ======= - */ -#define vec_sld(_a, _b, _c) spu_shuffle(_a, _b, ((vec_uchar16){ 0+(_c), 1+(_c), 2+(_c), 3+(_c), \ - 4+(_c), 5+(_c), 6+(_c), 7+(_c), \ - 8+(_c), 9+(_c), 10+(_c), 11+(_c), \ - 12+(_c), 13+(_c), 14+(_c), 15+(_c)})) - - -/* vec_sll (vector shift left long) - * ======= - */ -#define vec_sll(_a, _b) spu_slqw(_a, spu_extract((vec_uint4)(_b), 0)) - - -/* vec_slo (vector shift left by octet) - * ======= - */ -#define vec_slo(_a, _b) spu_slqwbytebc(_a, spu_extract((vec_uint4)(_b), 3) & 0x7F) - - -/* vec_splat (vector splat) - * ========= - */ -#define vec_splat(_a, _b) spu_splats(spu_extract(_a, _b)) - - -/* vec_splat_s8 (vector splat signed byte) - * ============ - */ -#define vec_splat_s8(_a) spu_splats((signed char)(_a)) - - -/* vec_splat_s16 (vector splat signed half-word) - * ============= - */ -#define vec_splat_s16(_a) spu_splats((signed short)(_a)) - - -/* vec_splat_s32 (vector splat signed word) - * ============= - */ -#define vec_splat_s32(_a) spu_splats((signed int)(_a)) - - -/* vec_splat_u8 (vector splat unsigned byte) - * ============ - */ -#define vec_splat_u8(_a) spu_splats((unsigned char)(_a)) - - -/* vec_splat_u16 (vector splat unsigned half-word) - * ============= - */ -#define vec_splat_u16(_a) spu_splats((unsigned short)(_a)) - - -/* vec_splat_u32 (vector splat unsigned word) - * ============= - */ -#define vec_splat_u32(_a) spu_splats((unsigned int)(_a)) - - -/* vec_sr (vector shift right) - * ====== - */ -static inline vec_uchar16 vec_sr(vec_uchar16 a, vec_uchar16 b) -{ - vec_ushort8 hi, lo; - - lo = spu_rlmask(spu_and((vec_ushort8)(a), 0xFF), spu_sub(0, (vec_short8)(spu_and((vec_ushort8)(b), 7)))); - hi = spu_and(spu_rlmask((vec_ushort8)(a), spu_sub(0, (vec_short8)(spu_and(spu_rlmask((vec_ushort8)(b), -8), 7)))), -256); - - return ((vec_uchar16)(spu_or(hi, lo))); -} - -static inline vec_char16 vec_sr(vec_char16 a, vec_uchar16 b) -{ - return ((vec_char16)(vec_sr((vec_uchar16)(a), b))); -} - -static inline vec_ushort8 vec_sr(vec_ushort8 a, vec_ushort8 b) -{ - return (spu_rlmask(a, spu_sub(0, (vec_short8)(spu_and(b, 15))))); -} - -static inline vec_short8 vec_sr(vec_short8 a, vec_ushort8 b) -{ - return ((vec_short8)(vec_sr((vec_ushort8)(a), b))); -} - -static inline vec_uint4 vec_sr(vec_uint4 a, vec_uint4 b) -{ - return (spu_rlmask(a, spu_sub(0, (vec_int4)(spu_and(b, 31))))); -} - -static inline vec_int4 vec_sr(vec_int4 a, vec_uint4 b) -{ - return ((vec_int4)(vec_sr((vec_uint4)(a), b))); -} - - -/* vec_sra (vector shift right algebraic) - * ======= - */ -static inline vec_char16 vec_sra(vec_char16 a, vec_uchar16 b) -{ - vec_short8 hi, lo; - - lo = spu_and(spu_rlmaska(spu_extend(a), spu_sub(0, (vec_short8)(spu_and((vec_ushort8)(b), 7)))), 0xFF); - hi = spu_and(spu_rlmaska((vec_short8)(a), spu_sub(0, (vec_short8)(spu_and(spu_rlmask((vec_ushort8)(b), -8), 7)))), -256); - - return ((vec_char16)(spu_or(hi, lo))); -} - -static inline vec_uchar16 vec_sra(vec_uchar16 a, vec_uchar16 b) -{ - return ((vec_uchar16)(vec_sra((vec_char16)(a), b))); -} - -static inline vec_short8 vec_sra(vec_short8 a, vec_ushort8 b) -{ - return (spu_rlmaska(a, spu_sub(0, (vec_short8)(spu_and(b, 15))))); -} - -static inline vec_ushort8 vec_sra(vec_ushort8 a, vec_ushort8 b) -{ - return ((vec_ushort8)(vec_sra((vec_short8)(a), b))); -} - -static inline vec_int4 vec_sra(vec_int4 a, vec_uint4 b) -{ - return (spu_rlmaska(a, spu_sub(0, (vec_int4)(spu_and(b, 31))))); -} - -static inline vec_uint4 vec_sra(vec_uint4 a, vec_uint4 b) -{ - return ((vec_uint4)(vec_sra((vec_int4)(a), b))); -} - - -/* vec_srl (vector shift right long) - * ======= - */ -#define vec_srl(_a, _b) spu_rlmaskqw(_a, 0-spu_extract((vec_int4)(_b), 3)) - - -/* vec_sro (vector shift right by octet) - * ======= - */ -#define vec_sro(_a, _b) spu_rlmaskqwbyte(_a, 0 - ((spu_extract((vec_int4)(_b), 3) >> 3) & 0xF)) - -/* vec_st (vector store indexed) - * ====== - */ -static inline void vec_st(vec_uchar16 a, int b, unsigned char *c) -{ - *((vec_uchar16 *)(c+b)) = a; -} - -static inline void vec_st(vec_uchar16 a, int b, vec_uchar16 *c) -{ - *((vec_uchar16 *)((unsigned char *)(c)+b)) = a; -} - -static inline void vec_st(vec_char16 a, int b, signed char *c) -{ - *((vec_char16 *)(c+b)) = a; -} - -static inline void vec_st(vec_char16 a, int b, vec_char16 *c) -{ - *((vec_char16 *)((signed char *)(c)+b)) = a; -} - -static inline void vec_st(vec_bchar16 a, int b, signed char *c) -{ - *((vec_bchar16 *)((signed char *)(c)+b)) = a; -} - -static inline void vec_st(vec_ushort8 a, int b, unsigned short *c) -{ - *((vec_ushort8 *)((unsigned char *)(c)+b)) = a; -} - -static inline void vec_st(vec_ushort8 a, int b, vec_ushort8 *c) -{ - *((vec_ushort8 *)((unsigned char *)(c)+b)) = a; -} - -static inline void vec_st(vec_short8 a, int b, signed short *c) -{ - *((vec_short8 *)((unsigned char *)(c)+b)) = a; -} - -static inline void vec_st(vec_short8 a, int b, vec_short8 *c) -{ - *((vec_short8 *)((signed char *)(c)+b)) = a; -} - -static inline void vec_st(vec_bshort8 a, int b, signed short *c) -{ - *((vec_bshort8 *)((signed char *)(c)+b)) = a; -} - -static inline void vec_st(vec_uint4 a, int b, unsigned int *c) -{ - *((vec_uint4 *)((unsigned char *)(c)+b)) = a; -} - -static inline void vec_st(vec_uint4 a, int b, vec_uint4 *c) -{ - *((vec_uint4 *)((unsigned char *)(c)+b)) = a; -} - -static inline void vec_st(vec_int4 a, int b, signed int *c) -{ - *((vec_int4 *)((unsigned char *)(c)+b)) = a; -} - -static inline void vec_st(vec_int4 a, int b, vec_int4 *c) -{ - *((vec_int4 *)((signed char *)(c)+b)) = a; -} - -static inline void vec_st(vec_bint4 a, int b, signed int *c) -{ - *((vec_bint4 *)((signed char *)(c)+b)) = a; -} - -static inline void vec_st(vec_float4 a, int b, float *c) -{ - *((vec_float4 *)((unsigned char *)(c)+b)) = a; -} - -static inline void vec_st(vec_float4 a, int b, vec_float4 *c) -{ - *((vec_float4 *)((unsigned char *)(c)+b)) = a; -} - - -/* vec_ste (vector store element indexed) - * ======= - */ -static inline void vec_ste(vec_uchar16 a, int b, unsigned char *c) -{ - unsigned char *ptr; - - ptr = c + b; - *ptr = spu_extract(a, (int)(ptr) & 15); -} - -static inline void vec_ste(vec_char16 a, int b, signed char *c) -{ - vec_ste((vec_uchar16)(a), b, (unsigned char *)(c)); -} - -static inline void vec_ste(vec_bchar16 a, int b, signed char *c) -{ - vec_ste((vec_uchar16)(a), b, (unsigned char *)(c)); -} - -static inline void vec_ste(vec_ushort8 a, int b, unsigned short *c) -{ - unsigned short *ptr; - - ptr = (unsigned short *)(((unsigned int)(c) + b) & ~1); - *ptr = spu_extract(a, ((int)(ptr) >> 1) & 7); -} - -static inline void vec_ste(vec_short8 a, int b, signed short *c) -{ - vec_ste((vec_ushort8)(a), b, (unsigned short *)(c)); -} - -static inline void vec_ste(vec_bshort8 a, int b, signed short *c) -{ - vec_ste((vec_ushort8)(a), b, (unsigned short *)(c)); -} - -static inline void vec_ste(vec_uint4 a, int b, unsigned int *c) -{ - unsigned int *ptr; - - ptr = (unsigned int *)(((unsigned int)(c) + b) & ~3); - *ptr = spu_extract(a, ((int)(ptr) >> 2) & 3); -} - -static inline void vec_ste(vec_int4 a, int b, signed int *c) -{ - vec_ste((vec_uint4)(a), b, (unsigned int *)(c)); -} - -static inline void vec_ste(vec_bint4 a, int b, signed int *c) -{ - vec_ste((vec_uint4)(a), b, (unsigned int *)(c)); -} - -static inline void vec_ste(vec_float4 a, int b, float *c) -{ - vec_ste((vec_uint4)(a), b, (unsigned int *)(c)); -} - - -/* vec_stl (vector store indexed LRU) - * ======= - */ -#define vec_stl(_a, _b, _c) vec_st(_a, _b, _c) - - -/* vec_sub (vector subtract) - * ======= - */ -static inline vec_uchar16 vec_sub(vec_uchar16 a, vec_uchar16 b) -{ - return ((vec_uchar16)(spu_sel(spu_sub((vec_ushort8)(a), (vec_ushort8)(b)), - spu_sub(spu_and((vec_ushort8)(a), -256), spu_and((vec_ushort8)(b), -256)), - spu_splats((unsigned short)0xFF00)))); -} - -static inline vec_char16 vec_sub(vec_char16 a, vec_char16 b) -{ - return ((vec_char16)(vec_sub((vec_uchar16)(a), (vec_uchar16)(b)))); -} - -static inline vec_char16 vec_sub(vec_bchar16 a, vec_char16 b) -{ - return ((vec_char16)(vec_sub((vec_uchar16)(a), (vec_uchar16)(b)))); -} - -static inline vec_char16 vec_sub(vec_char16 a, vec_bchar16 b) -{ - return ((vec_char16)(vec_sub((vec_uchar16)(a), (vec_uchar16)(b)))); -} - -static inline vec_ushort8 vec_sub(vec_ushort8 a, vec_ushort8 b) -{ - return (spu_sub(a, b)); -} - -static inline vec_short8 vec_sub(vec_short8 a, vec_short8 b) -{ - return (spu_sub(a, b)); -} - -static inline vec_short8 vec_sub(vec_bshort8 a, vec_short8 b) -{ - return (spu_sub((vec_short8)(a), b)); -} - -static inline vec_short8 vec_sub(vec_short8 a, vec_bshort8 b) -{ - return (spu_sub(a, (vec_short8)(b))); -} - -static inline vec_uint4 vec_sub(vec_uint4 a, vec_uint4 b) -{ - return (spu_sub(a, b)); -} - -static inline vec_int4 vec_sub(vec_int4 a, vec_int4 b) -{ - return (spu_sub(a, b)); -} - -static inline vec_int4 vec_sub(vec_bint4 a, vec_int4 b) -{ - return (spu_sub((vec_int4)(a), b)); -} - -static inline vec_int4 vec_sub(vec_int4 a, vec_bint4 b) -{ - return (spu_sub(a, (vec_int4)(b))); -} - -static inline vec_float4 vec_sub(vec_float4 a, vec_float4 b) -{ - return (spu_sub(a, b)); -} - - -/* vec_subc (vector subtract carryout) - * ======== - */ -#define vec_subc(_a, _b) spu_genb(_a, _b) - - -/* vec_subs (vector subtract saturate) - * ======== - */ -static inline vec_uchar16 vec_subs(vec_uchar16 a, vec_uchar16 b) -{ - vec_ushort8 s1, s2; - vec_uchar16 s, d; - - s1 = spu_sub(spu_rlmask((vec_ushort8)(a), -8), spu_rlmask((vec_ushort8)(b), -8)); - s2 = spu_sub(spu_and((vec_ushort8)(a), 0xFF), spu_and((vec_ushort8)(b), 0xFF)); - s = (vec_uchar16)(spu_shuffle(s1, s2, ((vec_uchar16){0, 16, 2, 18, 4, 20, 6, 22, - 8, 24, 10, 26, 12, 28, 14, 30}))); - d = (vec_uchar16)(spu_shuffle(s1, s2, ((vec_uchar16){1, 17, 3, 19, 5, 21, 7, 23, - 9, 25, 11, 27, 13, 29, 15, 31}))); - return (spu_andc(d, s)); -} - -static inline vec_char16 vec_subs(vec_char16 a, vec_char16 b) -{ - vec_ushort8 s1, s2; - vec_uchar16 s, d; - - s1 = spu_sub(spu_rlmask((vec_ushort8)(a), -8), spu_rlmask((vec_ushort8)(b), -8)); - s2 = spu_sub(spu_and((vec_ushort8)(a), 0xFF), spu_and((vec_ushort8)(b), 0xFF)); - s = (vec_uchar16)(spu_shuffle(s1, s2, ((vec_uchar16){1, 17, 3, 19, 5, 21, 7, 23, - 9, 25, 11, 27, 13, 29, 15, 31}))); - d = spu_sel(s, spu_splats((unsigned char)0x7F), spu_cmpgt(spu_nor((vec_uchar16)(a), spu_nand(s, (vec_uchar16)(b))), 0x7F)); - d = spu_sel(d, spu_splats((unsigned char)0x80), spu_cmpgt(spu_and((vec_uchar16)(a), spu_nor(s, (vec_uchar16)(b))), 0x7F)); - - return ((vec_char16)(d)); -} - -static inline vec_char16 vec_subs(vec_bchar16 a, vec_char16 b) -{ - return (vec_subs((vec_char16)(a), b)); -} - -static inline vec_char16 vec_subs(vec_char16 a, vec_bchar16 b) -{ - return (vec_subs(a, (vec_char16)(b))); -} - -static inline vec_ushort8 vec_subs(vec_ushort8 a, vec_ushort8 b) -{ - return (spu_andc(spu_sub(a, b), spu_cmpgt(b, a))); -} - -static inline vec_short8 vec_subs(vec_short8 a, vec_short8 b) -{ - vec_short8 s; - vec_short8 d; - - s = spu_sub(a, b); - d = spu_sel(s, spu_splats((signed short)0x7FFF), (vec_ushort8)(spu_rlmaska(spu_nor(a, spu_nand(s, b)), -15))); - d = spu_sel(d, spu_splats((signed short)0x8000), (vec_ushort8)(spu_rlmaska(spu_and(a, spu_nor(s, b)), -15))); - - return (d); -} - -static inline vec_short8 vec_subs(vec_bshort8 a, vec_short8 b) -{ - return ((vec_short8)(vec_subs((vec_short8)(a), b))); -} - -static inline vec_short8 vec_subs(vec_short8 a, vec_bshort8 b) -{ - return ((vec_short8)(vec_subs(a, (vec_short8)(b)))); -} - -static inline vec_uint4 vec_subs(vec_uint4 a, vec_uint4 b) -{ - return (spu_andc(spu_sub(a, b), spu_cmpgt(b, a))); -} - -static inline vec_int4 vec_subs(vec_int4 a, vec_int4 b) -{ - vec_int4 s; - vec_int4 d; - - s = spu_sub(a, b); - d = spu_sel(s, spu_splats((signed int)0x7FFFFFFF), (vec_uint4)(spu_rlmaska(spu_nor(a, spu_nand(s, b)), -31))); - d = spu_sel(d, spu_splats((signed int)0x80000000), (vec_uint4)(spu_rlmaska(spu_and(a, spu_nor(s, b)), -31))); - - return (d); -} - -static inline vec_int4 vec_subs(vec_bint4 a, vec_int4 b) -{ - return ((vec_int4)(vec_subs((vec_int4)(a), b))); -} - -static inline vec_int4 vec_subs(vec_int4 a, vec_bint4 b) -{ - return ((vec_int4)(vec_subs(a, (vec_int4)(b)))); -} - - -/* vec_sum4s (vector sum across partial (1/4) saturated) - * ========= - */ -static inline vec_uint4 vec_sum4s(vec_uchar16 a, vec_uint4 b) -{ - vec_uint4 a01_23, a0123; - - a01_23 = (vec_uint4)(spu_add(spu_rlmask((vec_ushort8)(a), -8), - spu_and((vec_ushort8)(a), 0xFF))); - a0123 = spu_add(spu_rlmask(a01_23, -16), spu_and(a01_23, 0x1FF)); - return (vec_adds(a0123, b)); -} - -static inline vec_int4 vec_sum4s(vec_char16 a, vec_int4 b) -{ - vec_int4 a01_23, a0123; - - a01_23 = (vec_int4)(spu_add(spu_rlmaska((vec_short8)(a), -8), - spu_extend(a))); - a0123 = spu_add(spu_rlmaska(a01_23, -16), spu_extend((vec_short8)(a01_23))); - return (vec_adds(a0123, b)); -} - -static inline vec_int4 vec_sum4s(vec_short8 a, vec_int4 b) -{ - vec_int4 a0123; - - a0123 = spu_add(spu_rlmaska((vec_int4)(a), -16), spu_extend(a)); - return (vec_adds(a0123, b)); -} - - -/* vec_sum2s (vector sum across partial (1/2) saturated) - * ========= - */ -static inline vec_int4 vec_sum2s(vec_int4 a, vec_int4 b) -{ - vec_int4 c, d; - vec_int4 sign1, sign2, sign3; - vec_int4 carry, sum_l, sum_h, sat, sat_val; - - sign1 = spu_rlmaska(a, -31); - sign2 = spu_rlmaska(b, -31); - - c = spu_rlqwbyte(a, -4); - sign3 = spu_rlqwbyte(sign1, -4); - - carry = spu_genc(a, b); - sum_l = spu_add(a, b); - sum_h = spu_addx(sign1, sign2, carry); - - carry = spu_genc(sum_l, c); - sum_l = spu_add(sum_l, c); - sum_h = spu_addx(sum_h, sign3, carry); - - sign1 = spu_rlmaska(sum_l, -31); - sign2 = spu_rlmaska(sum_h, -31); - - sat_val = spu_xor(sign2, spu_splats((signed int)0x7FFFFFFF)); - - sat = spu_orc(spu_xor(sign1, sign2), (vec_int4)spu_cmpeq(sum_h, sign2)); - - d = spu_and(spu_sel(sum_l, sat_val, (vec_uint4)(sat)), (vec_int4){0, -1, 0, -1}); - - return (d); -} - - -/* vec_sums (vector sum saturated) - * ======== - */ -static inline vec_int4 vec_sums(vec_int4 a, vec_int4 b) -{ - vec_int4 a0, a1, a2, c0, c1, c2, d; - vec_int4 sign_a, sign_b, sign_l, sign_h; - vec_int4 sum_l, sum_h, sat, sat_val; - - sign_a = spu_rlmaska(a, -31); - sign_b = spu_rlmaska(b, -31); - - a0 = spu_rlqwbyte(a, -12); - a1 = spu_rlqwbyte(a, -8); - a2 = spu_rlqwbyte(a, -4); - - sum_l = spu_add(a, b); - sum_h = spu_addx(sign_a, sign_b, spu_genc(a, b)); - - c2 = spu_genc(sum_l, a2); - sum_l = spu_add(sum_l, a2); - sum_h = spu_addx(sum_h, spu_rlqwbyte(sign_a, -4), c2); - - c1 = spu_genc(sum_l, a1); - sum_l = spu_add(sum_l, a1); - sum_h = spu_addx(sum_h, spu_rlqwbyte(sign_a, -8), c1); - - c0 = spu_genc(sum_l, a0); - sum_l = spu_add(sum_l, a0); - sum_h = spu_addx(sum_h, spu_rlqwbyte(sign_a, -12), c0); - - sign_l = spu_rlmaska(sum_l, -31); - sign_h = spu_rlmaska(sum_h, -31); - - sat_val = spu_xor(sign_h, spu_splats((signed int)0x7FFFFFFF)); - - sat = spu_orc(spu_xor(sign_l, sign_h), (vec_int4)spu_cmpeq(sum_h, sign_h)); - - d = spu_and(spu_sel(sum_l, sat_val, (vec_uint4)(sat)), ((vec_int4){0, 0, 0, -1})); - - return (d); -} - - -/* vec_trunc (vector truncate) - * ========= - */ -static inline vec_float4 vec_trunc(vec_float4 a) -{ - vec_int4 exp; - vec_uint4 mask; - - exp = spu_sub(127, (vec_int4)(spu_and(spu_rlmask((vec_uint4)(a), -23), 0xFF))); - mask = spu_rlmask(spu_splats((unsigned int)0x7FFFFF), exp); - mask = spu_sel(spu_splats((unsigned int)0), mask, spu_cmpgt(exp, -31)); - mask = spu_or(mask, spu_xor((vec_uint4)(spu_rlmaska(spu_add(exp, -1), -31)), -1)); - return (spu_andc(a, (vec_float4)(mask))); -} - -/* vec_unpackh (vector unpack high element) - * =========== - */ -static inline vec_short8 vec_unpackh(vec_char16 a) -{ - return (spu_extend(spu_shuffle(a, a, ((vec_uchar16){0, 0, 1, 1, 2, 2, 3, 3, - 4, 4, 5, 5, 6, 6, 7, 7})))); -} - -static inline vec_bshort8 vec_unpackh(vec_bchar16 a) -{ - return ((vec_bshort8)(vec_unpackh((vec_char16)(a)))); -} - -static inline vec_int4 vec_unpackh(vec_short8 a) -{ - return (spu_extend(spu_shuffle(a, a, ((vec_uchar16){0, 0, 0, 1, 0, 0, 2, 3, - 0, 0, 4, 5, 0, 0, 6, 7})))); -} - -#ifdef SUPPORT_UNPACK_PIXEL -/* Due to type conflicts, unpacking of pixel types and boolean shorts - * cannot simultaneously be supported. By default, the boolean short is - * supported. - */ -static inline vec_uint4 vec_unpackh(vec_pixel8 a) -{ - vec_ushort8 p1, p2; - - p1 = spu_shuffle((vec_ushort8)(spu_rlmaska((vec_short8)(a.p), -7)), - spu_and((vec_ushort8)(a.p), 0x1F), - ((vec_uchar16){ 0, 128, 128, 17, 2, 128, 128, 19, - 4, 128, 128, 21, 6, 128, 128, 23})); - p2 = spu_shuffle(spu_and(spu_rlmask((vec_ushort8)(a.p), -5), 0x1F), - spu_and(spu_rlmask((vec_ushort8)(a.p), -10), 0x1F), - ((vec_uchar16){ 128, 17, 1, 128, 128, 19, 3, 128, - 128, 21, 5, 128, 128, 23, 7, 128})); - return ((vec_uint4)(spu_or(p1, p2))); -} - -#else - -static inline vec_bint4 vec_unpackh(vec_bshort8 a) -{ - return ((vec_bint4)(vec_unpackh((vec_short8)(a)))); -} -#endif - - - - - -/* vec_unpackl (vector unpack low element) - * =========== - */ -static inline vec_short8 vec_unpackl(vec_char16 a) -{ - return (spu_extend(spu_shuffle(a, a, ((vec_uchar16){8, 8, 9, 9, 10, 10, 11, 11, - 12, 12, 13, 13, 14, 14, 15, 15})))); -} - -static inline vec_bshort8 vec_unpackl(vec_bchar16 a) -{ - return ((vec_bshort8)(vec_unpackl((vec_char16)(a)))); -} - - -static inline vec_int4 vec_unpackl(vec_short8 a) -{ - return (spu_extend(spu_shuffle(a, a, ((vec_uchar16){0, 0, 8, 9, 0, 0, 10, 11, - 0, 0,12,13, 0, 0, 14, 15})))); -} - - -#ifdef SUPPORT_UNPACK_PIXEL -/* Due to type conflicts, unpacking of pixel types and boolean shorts - * cannot simultaneously be supported. By default, the boolean short is - * supported. - */ -static inline vec_uint4 vec_unpackl(vec_pixel8 a) -{ - vec_ushort8 p1, p2; - - p1 = spu_shuffle((vec_ushort8)(spu_rlmaska((vec_short8)(a), -7)), - spu_and((vec_ushort8)(a), 0x1F), - ((vec_uchar16){ 8, 128, 128, 25, 10, 128, 128, 27, - 12, 128, 128, 29, 14, 128, 128, 31})); - p2 = spu_shuffle(spu_and(spu_rlmask((vec_ushort8)(a), -5), 0x1F), - spu_and(spu_rlmask((vec_ushort8)(a), -10), 0x1F), - ((vec_uchar16){ 128, 25, 9, 128, 128, 27, 11, 128, - 128, 29, 13, 128, 128, 31, 15, 128})); - return ((vec_uint4)(spu_or(p1, p2))); -} - -#else - -static inline vec_bint4 vec_unpackl(vec_bshort8 a) -{ - return ((vec_bint4)(vec_unpackl((vec_short8)(a)))); - -} -#endif - - - -/* vec_xor (vector logical xor) - * ====== - */ -static inline vec_uchar16 vec_xor(vec_uchar16 a, vec_uchar16 b) -{ - return (spu_xor(a, b)); -} - -static inline vec_char16 vec_xor(vec_char16 a, vec_char16 b) -{ - return (spu_xor(a, b)); -} - -static inline vec_char16 vec_xor(vec_bchar16 a, vec_char16 b) -{ - return (spu_xor((vec_char16)(a), b)); -} - -static inline vec_char16 vec_xor(vec_char16 a, vec_bchar16 b) -{ - return (spu_xor(a, (vec_char16)(b))); -} - -static inline vec_ushort8 vec_xor(vec_ushort8 a, vec_ushort8 b) -{ - return (spu_xor(a, b)); -} - -static inline vec_short8 vec_xor(vec_short8 a, vec_short8 b) -{ - return (spu_xor(a, b)); -} - -static inline vec_short8 vec_xor(vec_bshort8 a, vec_short8 b) -{ - return (spu_xor((vec_short8)(a), b)); -} - -static inline vec_short8 vec_xor(vec_short8 a, vec_bshort8 b) -{ - return (spu_xor(a, (vec_short8)(b))); -} - -static inline vec_uint4 vec_xor(vec_uint4 a, vec_uint4 b) -{ - return (spu_xor(a, b)); -} - -static inline vec_int4 vec_xor(vec_int4 a, vec_int4 b) -{ - return (spu_xor(a, b)); -} - -static inline vec_int4 vec_xor(vec_bint4 a, vec_int4 b) -{ - return (spu_xor((vec_int4)(a), b)); -} - -static inline vec_int4 vec_xor(vec_int4 a, vec_bint4 b) -{ - return (spu_xor(a, (vec_int4)(b))); -} - -static inline vec_float4 vec_xor(vec_float4 a, vec_float4 b) -{ - return (spu_xor(a, b)); -} - -static inline vec_float4 vec_xor(vec_bint4 a, vec_float4 b) -{ - return (spu_xor((vec_float4)(a),b)); -} - -static inline vec_float4 vec_xor(vec_float4 a, vec_bint4 b) -{ - return (spu_xor(a, (vec_float4)(b))); -} - -/************************************************************************ - * PREDICATES - ************************************************************************/ - -/* vec_all_eq (all elements equal) - * ========== - */ -static inline int vec_all_eq(vec_uchar16 a, vec_uchar16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0xFFFF)); -} - -static inline int vec_all_eq(vec_char16 a, vec_char16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0xFFFF)); -} - -static inline int vec_all_eq(vec_bchar16 a, vec_char16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_char16)(a), b)), 0) == 0xFFFF)); -} - -static inline int vec_all_eq(vec_char16 a, vec_bchar16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_char16)(b))), 0) == 0xFFFF)); -} - -static inline int vec_all_eq(vec_ushort8 a, vec_ushort8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0xFF)); -} - -static inline int vec_all_eq(vec_short8 a, vec_short8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0xFF)); -} - -static inline int vec_all_eq(vec_bshort8 a, vec_short8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_short8)(a), b)), 0) == 0xFF)); -} - -static inline int vec_all_eq(vec_short8 a, vec_bshort8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_short8)(b))), 0) == 0xFF)); -} - -static inline int vec_all_eq(vec_uint4 a, vec_uint4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0xF)); -} - -static inline int vec_all_eq(vec_int4 a, vec_int4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0xF)); -} - -static inline int vec_all_eq(vec_bint4 a, vec_int4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_int4)(a), b)), 0) == 0xF)); -} - -static inline int vec_all_eq(vec_int4 a, vec_bint4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_int4)(b))), 0) == 0xF)); -} - -static inline int vec_all_eq(vec_float4 a, vec_float4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0xF)); -} - - -/* vec_all_ge (all elements greater than or equal) - * ========== - */ -static inline int vec_all_ge(vec_uchar16 a, vec_uchar16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0)); -} - -static inline int vec_all_ge(vec_char16 a, vec_char16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0)); -} - -static inline int vec_all_ge(vec_bchar16 a, vec_char16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_char16)(a))), 0) == 0)); -} - -static inline int vec_all_ge(vec_char16 a, vec_bchar16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_char16)(b), a)), 0) == 0)); -} - -static inline int vec_all_ge(vec_ushort8 a, vec_ushort8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0)); -} - -static inline int vec_all_ge(vec_short8 a, vec_short8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0)); -} - -static inline int vec_all_ge(vec_bshort8 a, vec_short8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_short8)(a))), 0) == 0)); -} - -static inline int vec_all_ge(vec_short8 a, vec_bshort8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_short8)(b), a)), 0) == 0)); -} - -static inline int vec_all_ge(vec_uint4 a, vec_uint4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0)); -} - -static inline int vec_all_ge(vec_int4 a, vec_int4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0)); -} - -static inline int vec_all_ge(vec_bint4 a, vec_int4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_int4)(a))), 0) == 0)); -} - -static inline int vec_all_ge(vec_int4 a, vec_bint4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_int4)(b), a)), 0) == 0)); -} - -static inline int vec_all_ge(vec_float4 a, vec_float4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0)); -} - - -/* vec_all_gt (all elements greater than) - * ========== - */ -static inline int vec_all_gt(vec_uchar16 a, vec_uchar16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0xFFFF)); -} - -static inline int vec_all_gt(vec_char16 a, vec_char16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0xFFFF)); -} - -static inline int vec_all_gt(vec_bchar16 a, vec_char16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_char16)(a), b)), 0) == 0xFFFF)); -} - -static inline int vec_all_gt(vec_char16 a, vec_bchar16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_char16)(b))), 0) == 0xFFFF)); -} - -static inline int vec_all_gt(vec_ushort8 a, vec_ushort8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0xFF)); -} - -static inline int vec_all_gt(vec_short8 a, vec_short8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0xFF)); -} - -static inline int vec_all_gt(vec_bshort8 a, vec_short8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_short8)(a), b)), 0) == 0xFF)); -} - -static inline int vec_all_gt(vec_short8 a, vec_bshort8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_short8)(b))), 0) == 0xFF)); -} - -static inline int vec_all_gt(vec_uint4 a, vec_uint4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0xF)); -} - -static inline int vec_all_gt(vec_int4 a, vec_int4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0xF)); -} - -static inline int vec_all_gt(vec_bint4 a, vec_int4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_int4)(a), b)), 0) == 0xF)); -} - -static inline int vec_all_gt(vec_int4 a, vec_bint4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_int4)(b))), 0) == 0xF)); -} - -static inline int vec_all_gt(vec_float4 a, vec_float4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0xF)); -} - - -/* vec_all_in (all elements in bounds) - * ========== - */ -static inline int vec_all_in(vec_float4 a, vec_float4 b) -{ - return (spu_extract(spu_gather(spu_nor(spu_cmpabsgt(a, b), (vec_uint4)(spu_rlmaska((vec_int4)(b), -31)))), 0) == 0xF); -} - - -/* vec_all_le (all elements less than or equal) - * ========== - */ -static inline int vec_all_le(vec_uchar16 a, vec_uchar16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0)); -} - -static inline int vec_all_le(vec_char16 a, vec_char16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0)); -} - -static inline int vec_all_le(vec_bchar16 a, vec_char16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_char16)(a), b)), 0) == 0)); -} - -static inline int vec_all_le(vec_char16 a, vec_bchar16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_char16)(b))), 0) == 0)); -} - -static inline int vec_all_le(vec_ushort8 a, vec_ushort8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0)); -} - -static inline int vec_all_le(vec_short8 a, vec_short8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0)); -} - -static inline int vec_all_le(vec_bshort8 a, vec_short8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_short8)(a), b)), 0) == 0)); -} - -static inline int vec_all_le(vec_short8 a, vec_bshort8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_short8)(b))), 0) == 0)); -} - -static inline int vec_all_le(vec_uint4 a, vec_uint4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0)); -} - -static inline int vec_all_le(vec_int4 a, vec_int4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0)); -} - -static inline int vec_all_le(vec_bint4 a, vec_int4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_int4)(a), b)), 0) == 0)); -} - -static inline int vec_all_le(vec_int4 a, vec_bint4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_int4)(b))), 0) == 0)); -} - -static inline int vec_all_le(vec_float4 a, vec_float4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0)); -} - - -/* vec_all_lt (all elements less than) - * ========== - */ -static inline int vec_all_lt(vec_uchar16 a, vec_uchar16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0xFFFF)); -} - -static inline int vec_all_lt(vec_char16 a, vec_char16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0xFFFF)); -} - -static inline int vec_all_lt(vec_bchar16 a, vec_char16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_char16)(a))), 0) == 0xFFFF)); -} - -static inline int vec_all_lt(vec_char16 a, vec_bchar16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_char16)(b), a)), 0) == 0xFFFF)); -} - -static inline int vec_all_lt(vec_ushort8 a, vec_ushort8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0xFF)); -} - -static inline int vec_all_lt(vec_short8 a, vec_short8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0xFF)); -} - -static inline int vec_all_lt(vec_bshort8 a, vec_short8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_short8)(a))), 0) == 0xFF)); -} - -static inline int vec_all_lt(vec_short8 a, vec_bshort8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_short8)(b), a)), 0) == 0xFF)); -} - -static inline int vec_all_lt(vec_uint4 a, vec_uint4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0xF)); -} - -static inline int vec_all_lt(vec_int4 a, vec_int4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0xF)); -} - -static inline int vec_all_lt(vec_bint4 a, vec_int4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_int4)(a))), 0) == 0xF)); -} - -static inline int vec_all_lt(vec_int4 a, vec_bint4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_int4)(b), a)), 0) == 0xF)); -} - -static inline int vec_all_lt(vec_float4 a, vec_float4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0xF)); -} - - -/* vec_all_nan (all elements not a number) - * =========== - */ -static inline int vec_all_nan(vec_float4 a) -{ - vec_uint4 exp, man; - vec_uint4 exp_mask = spu_splats((unsigned int)0x7F800000); - - exp = spu_and((vec_uint4)(a), exp_mask); - man = spu_and((vec_uint4)(a), spu_splats((unsigned int)0x007FFFFF)); - return ((int)(spu_extract(spu_gather(spu_andc(spu_cmpeq(exp, exp_mask), - spu_cmpeq(man, 0))), 0) == 0xF)); -} - -#define vec_all_nan(_a) (0) - - -/* vec_all_ne (all elements not equal) - * ========== - */ -static inline int vec_all_ne(vec_uchar16 a, vec_uchar16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0)); -} - -static inline int vec_all_ne(vec_char16 a, vec_char16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0)); -} - -static inline int vec_all_ne(vec_bchar16 a, vec_char16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_char16)(a), b)), 0) == 0)); -} - -static inline int vec_all_ne(vec_char16 a, vec_bchar16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_char16)(b))), 0) == 0)); -} - -static inline int vec_all_ne(vec_ushort8 a, vec_ushort8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0)); -} - -static inline int vec_all_ne(vec_short8 a, vec_short8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0)); -} - -static inline int vec_all_ne(vec_bshort8 a, vec_short8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_short8)(a), b)), 0) == 0)); -} - -static inline int vec_all_ne(vec_short8 a, vec_bshort8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_short8)(b))), 0) == 0)); -} - -static inline int vec_all_ne(vec_uint4 a, vec_uint4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0)); -} - -static inline int vec_all_ne(vec_int4 a, vec_int4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0)); -} - -static inline int vec_all_ne(vec_bint4 a, vec_int4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_int4)(a), b)), 0) == 0)); -} - -static inline int vec_all_ne(vec_int4 a, vec_bint4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_int4)(b))), 0) == 0)); -} - -static inline int vec_all_ne(vec_float4 a, vec_float4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0)); -} - - -/* vec_all_nge (all elements not greater than or equal) - * =========== - */ -static inline int vec_all_nge(vec_float4 a, vec_float4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0xF)); -} - - -/* vec_all_ngt (all elements not greater than) - * =========== - */ -static inline int vec_all_ngt(vec_float4 a, vec_float4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0)); -} - - -/* vec_all_nle (all elements not less than or equal) - * =========== - */ -static inline int vec_all_nle(vec_float4 a, vec_float4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0xF)); -} - - -/* vec_all_nlt (all elements not less than) - * =========== - */ -static inline int vec_all_nlt(vec_float4 a, vec_float4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0)); -} - - -/* vec_all_numeric (all elements numeric) - * =========== - */ -static inline int vec_all_numeric(vec_float4 a) -{ - vec_uint4 exp; - - exp = spu_and(spu_rlmask((vec_uint4)(a), -23), 0xFF); - return ((int)(spu_extract(spu_gather(spu_cmpeq(exp, 255)), 0) == 0)); -} - - - -/* vec_any_eq (any elements equal) - * ========== - */ -static inline int vec_any_eq(vec_uchar16 a, vec_uchar16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0)); -} - -static inline int vec_any_eq(vec_char16 a, vec_char16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0)); -} - -static inline int vec_any_eq(vec_bchar16 a, vec_char16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_char16)(a), b)), 0) != 0)); -} - -static inline int vec_any_eq(vec_char16 a, vec_bchar16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_char16)(b))), 0) != 0)); -} - -static inline int vec_any_eq(vec_ushort8 a, vec_ushort8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0)); -} - -static inline int vec_any_eq(vec_short8 a, vec_short8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0)); -} - -static inline int vec_any_eq(vec_bshort8 a, vec_short8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_short8)(a), b)), 0) != 0)); -} - -static inline int vec_any_eq(vec_short8 a, vec_bshort8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_short8)(b))), 0) != 0)); -} - -static inline int vec_any_eq(vec_uint4 a, vec_uint4 b) -{ - return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpeq(a, b), -31)), 0))); -} - -static inline int vec_any_eq(vec_int4 a, vec_int4 b) -{ - return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpeq(a, b), -31)), 0))); -} - -static inline int vec_any_eq(vec_bint4 a, vec_int4 b) -{ - return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpeq((vec_int4)(a), b), -31)), 0))); -} - -static inline int vec_any_eq(vec_int4 a, vec_bint4 b) -{ - return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpeq(a, (vec_int4)(b)), -31)), 0))); -} - -static inline int vec_any_eq(vec_float4 a, vec_float4 b) -{ - return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpeq(a, b), -31)), 0))); -} - -/* vec_any_ge (any elements greater than or equal) - * ========== - */ -static inline int vec_any_ge(vec_uchar16 a, vec_uchar16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0xFFFF)); -} - -static inline int vec_any_ge(vec_char16 a, vec_char16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0xFFFF)); -} - -static inline int vec_any_ge(vec_bchar16 a, vec_char16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_char16)(a))), 0) != 0xFFFF)); -} - -static inline int vec_any_ge(vec_char16 a, vec_bchar16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_char16)(b), a)), 0) != 0xFFFF)); -} - -static inline int vec_any_ge(vec_ushort8 a, vec_ushort8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0xFF)); -} - -static inline int vec_any_ge(vec_short8 a, vec_short8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0xFF)); -} - -static inline int vec_any_ge(vec_bshort8 a, vec_short8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_short8)(a))), 0) != 0xFF)); -} - -static inline int vec_any_ge(vec_short8 a, vec_bshort8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_short8)(b), a)), 0) != 0xFF)); -} - -static inline int vec_any_ge(vec_uint4 a, vec_uint4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0xF)); -} - -static inline int vec_any_ge(vec_int4 a, vec_int4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0xF)); -} - -static inline int vec_any_ge(vec_bint4 a, vec_int4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_int4)(a))), 0) != 0xF)); -} - -static inline int vec_any_ge(vec_int4 a, vec_bint4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_int4)(b), a)), 0) != 0xF)); -} - -static inline int vec_any_ge(vec_float4 a, vec_float4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0xF)); -} - - -/* vec_any_gt (any elements greater than) - * ========== - */ -static inline int vec_any_gt(vec_uchar16 a, vec_uchar16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0)); -} - -static inline int vec_any_gt(vec_char16 a, vec_char16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0)); -} - -static inline int vec_any_gt(vec_bchar16 a, vec_char16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_char16)(a), b)), 0) != 0)); -} - -static inline int vec_any_gt(vec_char16 a, vec_bchar16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_char16)(b))), 0) != 0)); -} - -static inline int vec_any_gt(vec_ushort8 a, vec_ushort8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0)); -} - -static inline int vec_any_gt(vec_short8 a, vec_short8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0)); -} - -static inline int vec_any_gt(vec_bshort8 a, vec_short8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_short8)(a), b)), 0) != 0)); -} - -static inline int vec_any_gt(vec_short8 a, vec_bshort8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_short8)(b))), 0) != 0)); -} - - -static inline int vec_any_gt(vec_uint4 a, vec_uint4 b) -{ - return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt(a, b), -31)), 0))); -} - -static inline int vec_any_gt(vec_int4 a, vec_int4 b) -{ - return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt(a, b), -31)), 0))); -} - -static inline int vec_any_gt(vec_bint4 a, vec_int4 b) -{ - return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt((vec_int4)(a), b), -31)), 0))); -} - -static inline int vec_any_gt(vec_int4 a, vec_bint4 b) -{ - return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt(a, (vec_int4)(b)), -31)), 0))); -} - -static inline int vec_any_gt(vec_float4 a, vec_float4 b) -{ - return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt(a, b), -31)), 0))); -} - -/* vec_any_le (any elements less than or equal) - * ========== - */ -static inline int vec_any_le(vec_uchar16 a, vec_uchar16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0xFFFF)); -} - -static inline int vec_any_le(vec_char16 a, vec_char16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0xFFFF)); -} - -static inline int vec_any_le(vec_bchar16 a, vec_char16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_char16)(a), b)), 0) != 0xFFFF)); -} - -static inline int vec_any_le(vec_char16 a, vec_bchar16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_char16)(b))), 0) != 0xFFFF)); -} - -static inline int vec_any_le(vec_ushort8 a, vec_ushort8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0xFF)); -} - -static inline int vec_any_le(vec_short8 a, vec_short8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0xFF)); -} - -static inline int vec_any_le(vec_bshort8 a, vec_short8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_short8)(a), b)), 0) != 0xFF)); -} - -static inline int vec_any_le(vec_short8 a, vec_bshort8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_short8)(b))), 0) != 0xFF)); -} - -static inline int vec_any_le(vec_uint4 a, vec_uint4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0xF)); -} - -static inline int vec_any_le(vec_int4 a, vec_int4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0xF)); -} - -static inline int vec_any_le(vec_bint4 a, vec_int4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_int4)(a), b)), 0) != 0xF)); -} - -static inline int vec_any_le(vec_int4 a, vec_bint4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_int4)(b))), 0) != 0xF)); -} - -static inline int vec_any_le(vec_float4 a, vec_float4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0xF)); -} - - -/* vec_any_lt (any elements less than) - * ========== - */ -static inline int vec_any_lt(vec_uchar16 a, vec_uchar16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0)); -} - -static inline int vec_any_lt(vec_char16 a, vec_char16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0)); -} - -static inline int vec_any_lt(vec_bchar16 a, vec_char16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_char16)(a))), 0) != 0)); -} - -static inline int vec_any_lt(vec_char16 a, vec_bchar16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_char16)(b), a)), 0) != 0)); -} - -static inline int vec_any_lt(vec_ushort8 a, vec_ushort8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0)); -} - -static inline int vec_any_lt(vec_short8 a, vec_short8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0)); -} - -static inline int vec_any_lt(vec_bshort8 a, vec_short8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_short8)(a))), 0) != 0)); -} - -static inline int vec_any_lt(vec_short8 a, vec_bshort8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_short8)(b), a)), 0) != 0)); -} - -static inline int vec_any_lt(vec_uint4 a, vec_uint4 b) -{ - return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt(b, a), -31)), 0))); -} - -static inline int vec_any_lt(vec_int4 a, vec_int4 b) -{ - return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt(b, a), -31)), 0))); -} - -static inline int vec_any_lt(vec_bint4 a, vec_int4 b) -{ - return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt(b, (vec_int4)(a)), -31)), 0))); -} - -static inline int vec_any_lt(vec_int4 a, vec_bint4 b) -{ - return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt((vec_int4)(b), a), -31)), 0))); -} - -static inline int vec_any_lt(vec_float4 a, vec_float4 b) -{ - return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt(b, a), -31)), 0))); -} - -/* vec_any_nan (any elements not a number) - * =========== - */ -static inline int vec_any_nan(vec_float4 a) -{ - vec_uint4 exp, man; - vec_uint4 exp_mask = spu_splats((unsigned int)0x7F800000); - - exp = spu_and((vec_uint4)(a), exp_mask); - man = spu_and((vec_uint4)(a), spu_splats((unsigned int)0x007FFFFF)); - return ((int)(spu_extract(spu_gather(spu_andc(spu_cmpeq(exp, exp_mask), - spu_cmpeq(man, 0))), 0) != 0)); -} - - -/* vec_any_ne (any elements not equal) - * ========== - */ -static inline int vec_any_ne(vec_uchar16 a, vec_uchar16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0xFFFF)); -} - -static inline int vec_any_ne(vec_char16 a, vec_char16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0xFFFF)); -} - -static inline int vec_any_ne(vec_bchar16 a, vec_char16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_char16)(a), b)), 0) != 0xFFFF)); -} - -static inline int vec_any_ne(vec_char16 a, vec_bchar16 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_char16)(b))), 0) != 0xFFFF)); -} - -static inline int vec_any_ne(vec_ushort8 a, vec_ushort8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0xFF)); -} - -static inline int vec_any_ne(vec_short8 a, vec_short8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0xFF)); -} - -static inline int vec_any_ne(vec_bshort8 a, vec_short8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_short8)(a), b)), 0) != 0xFF)); -} - -static inline int vec_any_ne(vec_short8 a, vec_bshort8 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_short8)(b))), 0) != 0xFF)); -} - -static inline int vec_any_ne(vec_uint4 a, vec_uint4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0xF)); -} - -static inline int vec_any_ne(vec_int4 a, vec_int4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0xF)); -} - -static inline int vec_any_ne(vec_bint4 a, vec_int4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_int4)(a), b)), 0) != 0xF)); -} - -static inline int vec_any_ne(vec_int4 a, vec_bint4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_int4)(b))), 0) != 0xF)); -} - -static inline int vec_any_ne(vec_float4 a, vec_float4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0xF)); -} - - -/* vec_any_nge (any elements not greater than or equal) - * =========== - */ -static inline int vec_any_nge(vec_float4 a, vec_float4 b) -{ - return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt(b, a), -31)), 0))); -} - -/* vec_any_ngt (any elements not greater than) - * =========== - */ -static inline int vec_any_ngt(vec_float4 a, vec_float4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0xF)); -} - - -/* vec_any_nle (any elements not less than or equal) - * =========== - */ -static inline int vec_any_nle(vec_float4 a, vec_float4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0)); -} - - -/* vec_any_nlt (any elements not less than) - * =========== - */ -static inline int vec_any_nlt(vec_float4 a, vec_float4 b) -{ - return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0xF)); -} - - -/* vec_any_numeric (any elements numeric) - * =============== - */ -static inline int vec_any_numeric(vec_float4 a) -{ - vec_uint4 exp; - - exp = spu_and(spu_rlmask((vec_uint4)(a), -23), 0xFF); - return ((int)(spu_extract(spu_gather(spu_cmpeq(exp, 255)), 0) != 0xF)); -} - - -/* vec_any_out (any elements out of bounds) - * =========== - */ -static inline int vec_any_out(vec_float4 a, vec_float4 b) -{ - return (spu_extract(spu_gather(spu_nor(spu_cmpabsgt(a, b), (vec_uint4)(spu_rlmaska((vec_int4)(b), -31)))), 0) != 0xF); -} - - -/* CBE Language Extension Intrinsics - */ - -/* vec_extract (extract element from vector) - * =========== - */ -#define vec_extract(_a, _element) spu_extract(_a, _element) - - -/* vec_insert (insert scalar into specified vector element) - * ========== - */ -#define vec_insert(_a, _b, _element) spu_insert(_a, _b, _element) - -/* vec_lvlx (load vector left indexed) - * ======== - */ -static inline vec_uchar16 vec_lvlx(int a, unsigned char *b) -{ - vec_uchar16 *p = (vec_uchar16 *)((unsigned char *)(b) + a); - return(spu_slqwbyte(*p, (unsigned int)p & 0xF)); -} - -static inline vec_uchar16 vec_lvlx(int a, vec_uchar16 *b) -{ - vec_uchar16 *p = (vec_uchar16 *)((unsigned char *)(b) + a); - return(spu_slqwbyte(*p, (unsigned int)p & 0xF)); -} - -static inline vec_char16 vec_lvlx(int a, signed char *b) -{ - vec_char16 *p = (vec_char16 *)((unsigned char *)(b) + a); - return(spu_slqwbyte(*p, (unsigned int)p & 0xF)); -} - -static inline vec_char16 vec_lvlx(int a, vec_char16 *b) -{ - vec_char16 *p = (vec_char16 *)((unsigned char *)(b) + a); - return(spu_slqwbyte(*p, (unsigned int)p & 0xF)); -} - -static inline vec_ushort8 vec_lvlx(int a, unsigned short *b) -{ - vec_ushort8 *p = (vec_ushort8 *)((unsigned char *)(b) + a); - return(spu_slqwbyte(*p, (unsigned int)p & 0xF)); -} - -static inline vec_ushort8 vec_lvlx(int a, vec_ushort8 *b) -{ - vec_ushort8 *p = (vec_ushort8 *)((unsigned char *)(b) + a); - return(spu_slqwbyte(*p, (unsigned int)p & 0xF)); -} - -static inline vec_short8 vec_lvlx(int a, signed short *b) -{ - vec_short8 *p = (vec_short8 *)((unsigned char *)(b) + a); - return(spu_slqwbyte(*p, (unsigned int)p & 0xF)); -} - -static inline vec_short8 vec_lvlx(int a, vec_short8 *b) -{ - vec_short8 *p = (vec_short8 *)((unsigned char *)(b) + a); - return(spu_slqwbyte(*p, (unsigned int)p & 0xF)); -} - -static inline vec_uint4 vec_lvlx(int a, unsigned int *b) -{ - vec_uint4 *p = (vec_uint4 *)((unsigned char *)(b) + a); - return(spu_slqwbyte(*p, (unsigned int)p & 0xF)); -} - -static inline vec_uint4 vec_lvlx(int a, vec_uint4 *b) -{ - vec_uint4 *p = (vec_uint4 *)((unsigned char *)(b) + a); - return(spu_slqwbyte(*p, (unsigned int)p & 0xF)); -} - -static inline vec_int4 vec_lvlx(int a, signed int *b) -{ - vec_int4 *p = (vec_int4 *)((unsigned char *)(b) + a); - return(spu_slqwbyte(*p, (unsigned int)p & 0xF)); -} - -static inline vec_int4 vec_lvlx(int a, vec_int4 *b) -{ - vec_int4 *p = (vec_int4 *)((unsigned char *)(b) + a); - return(spu_slqwbyte(*p, (unsigned int)p & 0xF)); -} - -static inline vec_float4 vec_lvlx(int a, float *b) -{ - vec_float4 *p = (vec_float4 *)((unsigned char *)(b) + a); - return(spu_slqwbyte(*p, (unsigned int)p & 0xF)); -} - -static inline vec_float4 vec_lvlx(int a, vec_float4 *b) -{ - vec_float4 *p = (vec_float4 *)((unsigned char *)(b) + a); - return(spu_slqwbyte(*p, (unsigned int)p & 0xF)); -} - - -/* vec_lvlxl (load vector left indexed last) - * ========= - */ -#define vec_lvlxl(_a, _b) vec_lvlx(_a, _b) - - -/* vec_lvrx (load vector right indexed) - * ======== - */ -static inline vec_uchar16 vec_lvrx(int a, unsigned char *b) -{ - vec_uchar16 *p = (vec_uchar16 *)((unsigned char *)(b) + a); - return(spu_rlmaskqwbyte(*p, ((int)p & 0xF)-16)); -} - -static inline vec_uchar16 vec_lvrx(int a, vec_uchar16 *b) -{ - vec_uchar16 *p = (vec_uchar16 *)((unsigned char *)(b) + a); - return(spu_rlmaskqwbyte(*p, ((int)p & 0xF)-16)); -} - -static inline vec_char16 vec_lvrx(int a, signed char *b) -{ - vec_char16 *p = (vec_char16 *)((unsigned char *)(b) + a); - return(spu_rlmaskqwbyte(*p, ((int)p & 0xF)-16)); -} - -static inline vec_char16 vec_lvrx(int a, vec_char16 *b) -{ - vec_char16 *p = (vec_char16 *)((unsigned char *)(b) + a); - return(spu_rlmaskqwbyte(*p, ((int)p & 0xF)-16)); -} - -static inline vec_ushort8 vec_lvrx(int a, unsigned short *b) -{ - vec_ushort8 *p = (vec_ushort8 *)((unsigned char *)(b) + a); - return(spu_rlmaskqwbyte(*p, ((int)p & 0xF)-16)); -} - -static inline vec_ushort8 vec_lvrx(int a, vec_ushort8 *b) -{ - vec_ushort8 *p = (vec_ushort8 *)((unsigned char *)(b) + a); - return(spu_rlmaskqwbyte(*p, ((int)p & 0xF)-16)); -} - -static inline vec_short8 vec_lvrx(int a, signed short *b) -{ - vec_short8 *p = (vec_short8 *)((unsigned char *)(b) + a); - return(spu_rlmaskqwbyte(*p, ((int)p & 0xF)-16)); -} - -static inline vec_short8 vec_lvrx(int a, vec_short8 *b) -{ - vec_short8 *p = (vec_short8 *)((unsigned char *)(b) + a); - return(spu_rlmaskqwbyte(*p, ((int)p & 0xF)-16)); -} - -static inline vec_uint4 vec_lvrx(int a, unsigned int *b) -{ - vec_uint4 *p = (vec_uint4 *)((unsigned char *)(b) + a); - return(spu_rlmaskqwbyte(*p, ((int)p & 0xF)-16)); -} - -static inline vec_uint4 vec_lvrx(int a, vec_uint4 *b) -{ - vec_uint4 *p = (vec_uint4 *)((unsigned char *)(b) + a); - return(spu_rlmaskqwbyte(*p, ((int)p & 0xF)-16)); -} - -static inline vec_int4 vec_lvrx(int a, signed int *b) -{ - vec_int4 *p = (vec_int4 *)((unsigned char *)(b) + a); - return(spu_rlmaskqwbyte(*p, ((int)p & 0xF)-16)); -} - -static inline vec_int4 vec_lvrx(int a, vec_int4 *b) -{ - vec_int4 *p = (vec_int4 *)((unsigned char *)(b) + a); - return(spu_rlmaskqwbyte(*p, ((int)p & 0xF)-16)); -} - -static inline vec_float4 vec_lvrx(int a, float *b) -{ - vec_float4 *p = (vec_float4 *)((unsigned char *)(b) + a); - return(spu_rlmaskqwbyte(*p, ((int)p & 0xF)-16)); -} - -static inline vec_float4 vec_lvrx(int a, vec_float4 *b) -{ - vec_float4 *p = (vec_float4 *)((unsigned char *)(b) + a); - return(spu_rlmaskqwbyte(*p, ((int)p & 0xF)-16)); -} - - - -/* vec_lvrxl (load vector right indexed last) - * ========= - */ -#define vec_lvrxl(_a, _b) vec_lvrx(_a, _b) - - -/* vec_promote (promote scalar to a vector) - * =========== - */ -#define vec_promote(_a, _element) spu_promote(_a, _element) - - -/* vec_splats (splat scalar to a vector) - * ========== - */ -#define vec_splats(_a) spu_splats(_a) - - -/* vec_stvlx (store vector left indexed) - * ========= - */ -static inline void vec_stvlx(vec_uchar16 a, int b, unsigned char *c) -{ - int shift; - vec_uchar16 *p = (vec_uchar16 *)((unsigned char *)(c) + b); - - shift = -((int)p & 0xF); - *p = spu_sel(*p, - spu_rlmaskqwbyte(a, shift), - spu_rlmaskqwbyte(spu_splats((unsigned char)0xFF), shift)); -} - -static inline void vec_stvlx(vec_uchar16 a, int b, vec_uchar16 *c) -{ - int shift; - vec_uchar16 *p = (vec_uchar16 *)((unsigned char *)(c) + b); - - shift = -((int)p & 0xF); - *p = spu_sel(*p, - spu_rlmaskqwbyte(a, shift), - spu_rlmaskqwbyte(spu_splats((unsigned char)0xFF), shift)); -} - -static inline void vec_stvlx(vec_char16 a, int b, signed char *c) -{ - int shift; - vec_char16 *p = (vec_char16 *)((unsigned char *)(c) + b); - - shift = -((int)p & 0xF); - *p = spu_sel(*p, - spu_rlmaskqwbyte(a, shift), - spu_rlmaskqwbyte(spu_splats((unsigned char)0xFF), shift)); -} - -static inline void vec_stvlx(vec_char16 a, int b, vec_char16 *c) -{ - int shift; - vec_char16 *p = (vec_char16 *)((unsigned char *)(c) + b); - - shift = -((int)p & 0xF); - *p = spu_sel(*p, - spu_rlmaskqwbyte(a, shift), - spu_rlmaskqwbyte(spu_splats((unsigned char)0xFF), shift)); -} - -static inline void vec_stvlx(vec_ushort8 a, int b, unsigned short *c) -{ - int shift; - vec_ushort8 *p = (vec_ushort8 *)((unsigned char *)(c) + b); - - shift = -((int)p & 0xF); - *p = spu_sel(*p, - spu_rlmaskqwbyte(a, shift), - spu_rlmaskqwbyte(spu_splats((unsigned short)0xFFFF), shift)); -} - -static inline void vec_stvlx(vec_ushort8 a, int b, vec_ushort8 *c) -{ - int shift; - vec_ushort8 *p = (vec_ushort8 *)((unsigned char *)(c) + b); - - shift = -((int)p & 0xF); - *p = spu_sel(*p, - spu_rlmaskqwbyte(a, shift), - spu_rlmaskqwbyte(spu_splats((unsigned short)0xFFFF), shift)); -} - -static inline void vec_stvlx(vec_short8 a, int b, signed short *c) -{ - int shift; - vec_short8 *p = (vec_short8 *)((unsigned char *)(c) + b); - - shift = -((int)p & 0xF); - *p = spu_sel(*p, - spu_rlmaskqwbyte(a, shift), - spu_rlmaskqwbyte(spu_splats((unsigned short)0xFFFF), shift)); -} - -static inline void vec_stvlx(vec_short8 a, int b, vec_short8 *c) -{ - int shift; - vec_short8 *p = (vec_short8 *)((unsigned char *)(c) + b); - - shift = -((int)p & 0xF); - *p = spu_sel(*p, - spu_rlmaskqwbyte(a, shift), - spu_rlmaskqwbyte(spu_splats((unsigned short)0xFFFF), shift)); -} - -static inline void vec_stvlx(vec_uint4 a, int b, unsigned int *c) -{ - int shift; - vec_uint4 *p = (vec_uint4 *)((unsigned char *)(c) + b); - - shift = -((int)p & 0xF); - *p = spu_sel(*p, - spu_rlmaskqwbyte(a, shift), - spu_rlmaskqwbyte(spu_splats((unsigned int)0xFFFFFFFF), shift)); -} - -static inline void vec_stvlx(vec_uint4 a, int b, vec_uint4 *c) -{ - int shift; - vec_uint4 *p = (vec_uint4 *)((unsigned char *)(c) + b); - - shift = -((int)p & 0xF); - *p = spu_sel(*p, - spu_rlmaskqwbyte(a, shift), - spu_rlmaskqwbyte(spu_splats((unsigned int)0xFFFFFFFF), shift)); -} - -static inline void vec_stvlx(vec_int4 a, int b, signed int *c) -{ - int shift; - vec_int4 *p = (vec_int4 *)((unsigned char *)(c) + b); - - shift = -((int)p & 0xF); - *p = spu_sel(*p, - spu_rlmaskqwbyte(a, shift), - spu_rlmaskqwbyte(spu_splats((unsigned int)0xFFFFFFFF), shift)); -} - -static inline void vec_stvlx(vec_int4 a, int b, vec_int4 *c) -{ - int shift; - vec_int4 *p = (vec_int4 *)((unsigned char *)(c) + b); - - shift = -((int)p & 0xF); - *p = spu_sel(*p, - spu_rlmaskqwbyte(a, shift), - spu_rlmaskqwbyte(spu_splats((unsigned int)0xFFFFFFFF), shift)); -} - -static inline void vec_stvlx(vec_float4 a, int b, float *c) -{ - int shift; - vec_float4 *p = (vec_float4 *)((unsigned char *)(c) + b); - - shift = -((int)p & 0xF); - *p = spu_sel(*p, - spu_rlmaskqwbyte(a, shift), - spu_rlmaskqwbyte(spu_splats((unsigned int)0xFFFFFFFF), shift)); -} - -static inline void vec_stvlx(vec_float4 a, int b, vec_float4 *c) -{ - int shift; - vec_float4 *p = (vec_float4 *)((unsigned char *)(c) + b); - - shift = -((int)p & 0xF); - *p = spu_sel(*p, - spu_rlmaskqwbyte(a, shift), - spu_rlmaskqwbyte(spu_splats((unsigned int)0xFFFFFFFF), shift)); -} - -/* vec_stvlxl (store vector left indexed last) - * ========== - */ -#define vec_stvlxl(_a, _b, _c) vec_stvlx(_a, _b, _c) - - -/* vec_stvrx (store vector right indexed) - * ========= - */ -static inline void vec_stvrx(vec_uchar16 a, int b, unsigned char *c) -{ - int shift; - vec_uchar16 *p = (vec_uchar16 *)((unsigned char *)(c) + b); - - shift = 16-((int)p & 0xF); - *p = spu_sel(*p, - spu_slqwbyte(a, shift), - spu_slqwbyte(spu_splats((unsigned char)0xFF), shift)); -} - -static inline void vec_stvrx(vec_uchar16 a, int b, vec_uchar16 *c) -{ - int shift; - vec_uchar16 *p = (vec_uchar16 *)((unsigned char *)(c) + b); - - shift = 16-((int)p & 0xF); - *p = spu_sel(*p, - spu_slqwbyte(a, shift), - spu_slqwbyte(spu_splats((unsigned char)0xFF), shift)); -} - -static inline void vec_stvrx(vec_char16 a, int b, signed char *c) -{ - int shift; - vec_char16 *p = (vec_char16 *)((unsigned char *)(c) + b); - - shift = 16-((int)p & 0xF); - *p = spu_sel(*p, - spu_slqwbyte(a, shift), - spu_slqwbyte(spu_splats((unsigned char)0xFF), shift)); -} - -static inline void vec_stvrx(vec_char16 a, int b, vec_char16 *c) -{ - int shift; - vec_char16 *p = (vec_char16 *)((unsigned char *)(c) + b); - - shift = 16-((int)p & 0xF); - *p = spu_sel(*p, - spu_slqwbyte(a, shift), - spu_slqwbyte(spu_splats((unsigned char)0xFF), shift)); -} - -static inline void vec_stvrx(vec_ushort8 a, int b, unsigned short *c) -{ - int shift; - vec_ushort8 *p = (vec_ushort8 *)((unsigned char *)(c) + b); - - shift = 16-((int)p & 0xF); - *p = spu_sel(*p, - spu_slqwbyte(a, shift), - spu_slqwbyte(spu_splats((unsigned short)0xFFFF), shift)); -} - -static inline void vec_stvrx(vec_ushort8 a, int b, vec_ushort8 *c) -{ - int shift; - vec_ushort8 *p = (vec_ushort8 *)((unsigned char *)(c) + b); - - shift = 16-((int)p & 0xF); - *p = spu_sel(*p, - spu_slqwbyte(a, shift), - spu_slqwbyte(spu_splats((unsigned short)0xFFFF), shift)); -} - -static inline void vec_stvrx(vec_short8 a, int b, signed short *c) -{ - int shift; - vec_short8 *p = (vec_short8 *)((unsigned char *)(c) + b); - - shift = 16-((int)p & 0xF); - *p = spu_sel(*p, - spu_slqwbyte(a, shift), - spu_slqwbyte(spu_splats((unsigned short)0xFFFF), shift)); -} - -static inline void vec_stvrx(vec_short8 a, int b, vec_short8 *c) -{ - int shift; - vec_short8 *p = (vec_short8 *)((unsigned char *)(c) + b); - - shift = 16-((int)p & 0xF); - *p = spu_sel(*p, - spu_slqwbyte(a, shift), - spu_slqwbyte(spu_splats((unsigned short)0xFFFF), shift)); -} - -static inline void vec_stvrx(vec_uint4 a, int b, unsigned int *c) -{ - int shift; - vec_uint4 *p = (vec_uint4 *)((unsigned char *)(c) + b); - - shift = 16-((int)p & 0xF); - *p = spu_sel(*p, - spu_slqwbyte(a, shift), - spu_slqwbyte(spu_splats((unsigned int)0xFFFFFFFF), shift)); -} - -static inline void vec_stvrx(vec_uint4 a, int b, vec_uint4 *c) -{ - int shift; - vec_uint4 *p = (vec_uint4 *)((unsigned char *)(c) + b); - - shift = 16-((int)p & 0xF); - *p = spu_sel(*p, - spu_slqwbyte(a, shift), - spu_slqwbyte(spu_splats((unsigned int)0xFFFFFFFF), shift)); -} - -static inline void vec_stvrx(vec_int4 a, int b, signed int *c) -{ - int shift; - vec_int4 *p = (vec_int4 *)((unsigned char *)(c) + b); - - shift = 16-((int)p & 0xF); - *p = spu_sel(*p, - spu_slqwbyte(a, shift), - spu_slqwbyte(spu_splats((unsigned int)0xFFFFFFFF), shift)); -} - -static inline void vec_stvrx(vec_int4 a, int b, vec_int4 *c) -{ - int shift; - vec_int4 *p = (vec_int4 *)((unsigned char *)(c) + b); - - shift = 16-((int)p & 0xF); - *p = spu_sel(*p, - spu_slqwbyte(a, shift), - spu_slqwbyte(spu_splats((unsigned int)0xFFFFFFFF), shift)); -} - -static inline void vec_stvrx(vec_float4 a, int b, float *c) -{ - int shift; - vec_float4 *p = (vec_float4 *)((unsigned char *)(c) + b); - - shift = 16-((int)p & 0xF); - *p = spu_sel(*p, - spu_slqwbyte(a, shift), - spu_slqwbyte(spu_splats((unsigned int)0xFFFFFFFF), shift)); -} - -static inline void vec_stvrx(vec_float4 a, int b, vec_float4 *c) -{ - int shift; - vec_float4 *p = (vec_float4 *)((unsigned char *)(c) + b); - - shift = 16-((int)p & 0xF); - *p = spu_sel(*p, - spu_slqwbyte(a, shift), - spu_slqwbyte(spu_splats((unsigned int)0xFFFFFFFF), shift)); -} - -/* vec_stvrxl (store vector right indexed last) - * ========== - */ -#define vec_stvrxl(_a, _b, _c) vec_stvrx(_a, _b, _c) - - -#endif /* __SPU__ */ -#endif /* __cplusplus */ -#endif /* !_VMX2SPU_H_ */ diff --git a/gcc/configure b/gcc/configure index 8c9f774..22cf194 100755 --- a/gcc/configure +++ b/gcc/configure @@ -27962,7 +27962,7 @@ esac # version to the per-target configury. case "$cpu_type" in aarch64 | alpha | arc | arm | avr | bfin | cris | csky | i386 | m32c | m68k \ - | microblaze | mips | nds32 | nios2 | pa | riscv | rs6000 | score | sparc | spu \ + | microblaze | mips | nds32 | nios2 | pa | riscv | rs6000 | score | sparc \ | tilegx | tilepro | visium | xstormy16 | xtensa) insn="nop" ;; diff --git a/gcc/configure.ac b/gcc/configure.ac index 137d5b4..5c60d0f 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -4999,7 +4999,7 @@ esac # version to the per-target configury. case "$cpu_type" in aarch64 | alpha | arc | arm | avr | bfin | cris | csky | i386 | m32c | m68k \ - | microblaze | mips | nds32 | nios2 | pa | riscv | rs6000 | score | sparc | spu \ + | microblaze | mips | nds32 | nios2 | pa | riscv | rs6000 | score | sparc \ | tilegx | tilepro | visium | xstormy16 | xtensa) insn="nop" ;; diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 4aea4d3..cec15e5 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -1385,7 +1385,7 @@ As an extension, GNU C supports named address spaces as defined in the N1275 draft of ISO/IEC DTR 18037. Support for named address spaces in GCC will evolve as the draft technical report changes. Calling conventions for any target might also change. At -present, only the AVR, SPU, M32C, RL78, and x86 targets support +present, only the AVR, M32C, RL78, and x86 targets support address spaces other than the generic address space. Address space identifiers may be used exactly like any other C type @@ -1573,23 +1573,6 @@ with 32-bit pointers (20-bit addresses) rather than the default 16-bit addresses. Non-far variables are assumed to appear in the topmost 64@tie{}KiB of the address space. -@subsection SPU Named Address Spaces -@cindex @code{__ea} SPU Named Address Spaces - -On the SPU target variables may be declared as -belonging to another address space by qualifying the type with the -@code{__ea} address space identifier: - -@smallexample -extern int __ea i; -@end smallexample - -@noindent -The compiler generates special code to access the variable @code{i}. -It may use runtime library -support, or generate special machine instructions to access that address -space. - @subsection x86 Named Address Spaces @cindex x86 named address spaces @@ -2486,7 +2469,6 @@ GCC plugins may provide their own attributes. * RX Function Attributes:: * S/390 Function Attributes:: * SH Function Attributes:: -* SPU Function Attributes:: * Symbian OS Function Attributes:: * V850 Function Attributes:: * Visium Function Attributes:: @@ -5839,24 +5821,6 @@ On SH targets this function attribute is similar to @code{interrupt_handler} but it does not save and restore all registers. @end table -@node SPU Function Attributes -@subsection SPU Function Attributes - -These function attributes are supported by the SPU back end: - -@table @code -@item naked -@cindex @code{naked} function attribute, SPU -This attribute allows the compiler to construct the -requisite function declaration, while allowing the body of the -function to be assembly code. The specified function will not have -prologue/epilogue sequences generated by the compiler. Only basic -@code{asm} statements can safely be included in naked functions -(@pxref{Basic Asm}). While using extended @code{asm} or a mixture of -basic @code{asm} and C code may appear to work, they cannot be -depended upon to work reliably and are not supported. -@end table - @node Symbian OS Function Attributes @subsection Symbian OS Function Attributes @@ -6707,7 +6671,6 @@ attributes. * Nvidia PTX Variable Attributes:: * PowerPC Variable Attributes:: * RL78 Variable Attributes:: -* SPU Variable Attributes:: * V850 Variable Attributes:: * x86 Variable Attributes:: * Xstormy16 Variable Attributes:: @@ -7622,14 +7585,6 @@ The RL78 back end supports the @code{saddr} variable attribute. This specifies placement of the corresponding variable in the SADDR area, which can be accessed more efficiently than the default memory region. -@node SPU Variable Attributes -@subsection SPU Variable Attributes - -@cindex @code{spu_vector} variable attribute, SPU -The SPU supports the @code{spu_vector} attribute for variables. For -documentation of this attribute please see the documentation in -@ref{SPU Type Attributes}. - @node V850 Variable Attributes @subsection V850 Variable Attributes @@ -7737,7 +7692,6 @@ attributes. * ARM Type Attributes:: * MeP Type Attributes:: * PowerPC Type Attributes:: -* SPU Type Attributes:: * x86 Type Attributes:: @end menu @@ -8328,15 +8282,6 @@ __attribute__((altivec(bool__))) unsigned These attributes mainly are intended to support the @code{__vector}, @code{__pixel}, and @code{__bool} AltiVec keywords. -@node SPU Type Attributes -@subsection SPU Type Attributes - -@cindex @code{spu_vector} type attribute, SPU -The SPU supports the @code{spu_vector} attribute for types. This attribute -allows one to declare vector data types supported by the Sony/Toshiba/IBM SPU -Language Extensions Specification. It is intended to support the -@code{__vector} keyword. - @node x86 Type Attributes @subsection x86 Type Attributes @@ -13621,7 +13566,6 @@ instructions, but allow the compiler to schedule those calls. * S/390 System z Built-in Functions:: * SH Built-in Functions:: * SPARC VIS Built-in Functions:: -* SPU Built-in Functions:: * TI C6X Built-in Functions:: * TILE-Gx Built-in Functions:: * TILEPro Built-in Functions:: @@ -21160,61 +21104,6 @@ long __builtin_vis_fpcmpur16shl (v4hi, v4hi, int); long __builtin_vis_fpcmpur32shl (v2si, v2si, int); @end smallexample -@node SPU Built-in Functions -@subsection SPU Built-in Functions - -GCC provides extensions for the SPU processor as described in the -Sony/Toshiba/IBM SPU Language Extensions Specification. GCC's -implementation differs in several ways. - -@itemize @bullet - -@item -The optional extension of specifying vector constants in parentheses is -not supported. - -@item -A vector initializer requires no cast if the vector constant is of the -same type as the variable it is initializing. - -@item -If @code{signed} or @code{unsigned} is omitted, the signedness of the -vector type is the default signedness of the base type. The default -varies depending on the operating system, so a portable program should -always specify the signedness. - -@item -By default, the keyword @code{__vector} is added. The macro -@code{vector} is defined in @code{} and can be -undefined. - -@item -GCC allows using a @code{typedef} name as the type specifier for a -vector type. - -@item -For C, overloaded functions are implemented with macros so the following -does not work: - -@smallexample - spu_add ((vector signed int)@{1, 2, 3, 4@}, foo); -@end smallexample - -@noindent -Since @code{spu_add} is a macro, the vector constant in the example -is treated as four separate arguments. Wrap the entire argument in -parentheses for this to work. - -@item -The extended version of @code{__builtin_expect} is not supported. - -@end itemize - -@emph{Note:} Only the interface described in the aforementioned -specification is supported. Internally, GCC uses built-in functions to -implement the required functionality, but these are not supported and -are subject to change without notice. - @node TI C6X Built-in Functions @subsection TI C6X Built-in Functions diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index cfa3f86..2e353be 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -1214,17 +1214,6 @@ See RS/6000 and PowerPC Options. -mfix-at697f -mfix-ut699 -mfix-ut700 -mfix-gr712rc @gol -mlra -mno-lra} -@emph{SPU Options} -@gccoptlist{-mwarn-reloc -merror-reloc @gol --msafe-dma -munsafe-dma @gol --mbranch-hints @gol --msmall-mem -mlarge-mem -mstdmain @gol --mfixed-range=@var{register-range} @gol --mea32 -mea64 @gol --maddress-space-conversion -mno-address-space-conversion @gol --mcache-size=@var{cache-size} @gol --matomic-updates -mno-atomic-updates} - @emph{System V Options} @gccoptlist{-Qy -Qn -YP,@var{paths} -Ym,@var{dir}} @@ -15717,7 +15706,6 @@ platform. * SH Options:: * Solaris 2 Options:: * SPARC Options:: -* SPU Options:: * System V Options:: * TILE-Gx Options:: * TILEPro Options:: @@ -26772,141 +26760,6 @@ when making stack frame references. This is the default in 64-bit mode. Otherwise, assume no such offset is present. @end table -@node SPU Options -@subsection SPU Options -@cindex SPU options - -These @samp{-m} options are supported on the SPU: - -@table @gcctabopt -@item -mwarn-reloc -@itemx -merror-reloc -@opindex mwarn-reloc -@opindex merror-reloc - -The loader for SPU does not handle dynamic relocations. By default, GCC -gives an error when it generates code that requires a dynamic -relocation. @option{-mno-error-reloc} disables the error, -@option{-mwarn-reloc} generates a warning instead. - -@item -msafe-dma -@itemx -munsafe-dma -@opindex msafe-dma -@opindex munsafe-dma - -Instructions that initiate or test completion of DMA must not be -reordered with respect to loads and stores of the memory that is being -accessed. -With @option{-munsafe-dma} you must use the @code{volatile} keyword to protect -memory accesses, but that can lead to inefficient code in places where the -memory is known to not change. Rather than mark the memory as volatile, -you can use @option{-msafe-dma} to tell the compiler to treat -the DMA instructions as potentially affecting all memory. - -@item -mbranch-hints -@opindex mbranch-hints - -By default, GCC generates a branch hint instruction to avoid -pipeline stalls for always-taken or probably-taken branches. A hint -is not generated closer than 8 instructions away from its branch. -There is little reason to disable them, except for debugging purposes, -or to make an object a little bit smaller. - -@item -msmall-mem -@itemx -mlarge-mem -@opindex msmall-mem -@opindex mlarge-mem - -By default, GCC generates code assuming that addresses are never larger -than 18 bits. With @option{-mlarge-mem} code is generated that assumes -a full 32-bit address. - -@item -mstdmain -@opindex mstdmain - -By default, GCC links against startup code that assumes the SPU-style -main function interface (which has an unconventional parameter list). -With @option{-mstdmain}, GCC links your program against startup -code that assumes a C99-style interface to @code{main}, including a -local copy of @code{argv} strings. - -@item -mfixed-range=@var{register-range} -@opindex mfixed-range -Generate code treating the given register range as fixed registers. -A fixed register is one that the register allocator cannot use. This is -useful when compiling kernel code. A register range is specified as -two registers separated by a dash. Multiple register ranges can be -specified separated by a comma. - -@item -mea32 -@itemx -mea64 -@opindex mea32 -@opindex mea64 -Compile code assuming that pointers to the PPU address space accessed -via the @code{__ea} named address space qualifier are either 32 or 64 -bits wide. The default is 32 bits. As this is an ABI-changing option, -all object code in an executable must be compiled with the same setting. - -@item -maddress-space-conversion -@itemx -mno-address-space-conversion -@opindex maddress-space-conversion -@opindex mno-address-space-conversion -Allow/disallow treating the @code{__ea} address space as superset -of the generic address space. This enables explicit type casts -between @code{__ea} and generic pointer as well as implicit -conversions of generic pointers to @code{__ea} pointers. The -default is to allow address space pointer conversions. - -@item -mcache-size=@var{cache-size} -@opindex mcache-size -This option controls the version of libgcc that the compiler links to an -executable and selects a software-managed cache for accessing variables -in the @code{__ea} address space with a particular cache size. Possible -options for @var{cache-size} are @samp{8}, @samp{16}, @samp{32}, @samp{64} -and @samp{128}. The default cache size is 64KB. - -@item -matomic-updates -@itemx -mno-atomic-updates -@opindex matomic-updates -@opindex mno-atomic-updates -This option controls the version of libgcc that the compiler links to an -executable and selects whether atomic updates to the software-managed -cache of PPU-side variables are used. If you use atomic updates, changes -to a PPU variable from SPU code using the @code{__ea} named address space -qualifier do not interfere with changes to other PPU variables residing -in the same cache line from PPU code. If you do not use atomic updates, -such interference may occur; however, writing back cache lines is -more efficient. The default behavior is to use atomic updates. - -@item -mdual-nops -@itemx -mdual-nops=@var{n} -@opindex mdual-nops -By default, GCC inserts NOPs to increase dual issue when it expects -it to increase performance. @var{n} can be a value from 0 to 10. A -smaller @var{n} inserts fewer NOPs. 10 is the default, 0 is the -same as @option{-mno-dual-nops}. Disabled with @option{-Os}. - -@item -mhint-max-nops=@var{n} -@opindex mhint-max-nops -Maximum number of NOPs to insert for a branch hint. A branch hint must -be at least 8 instructions away from the branch it is affecting. GCC -inserts up to @var{n} NOPs to enforce this, otherwise it does not -generate the branch hint. - -@item -mhint-max-distance=@var{n} -@opindex mhint-max-distance -The encoding of the branch hint instruction limits the hint to be within -256 instructions of the branch it is affecting. By default, GCC makes -sure it is within 125. - -@item -msafe-hints -@opindex msafe-hints -Work around a hardware bug that causes the SPU to stall indefinitely. -By default, GCC inserts the @code{hbrp} instruction to make sure -this stall won't happen. - -@end table - @node System V Options @subsection Options for System V diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index 7751984..fa4ae14 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -3736,76 +3736,6 @@ Vector zero @end table -@item SPU---@file{config/spu/spu.h} -@table @code -@item a -An immediate which can be loaded with the il/ila/ilh/ilhu instructions. const_int is treated as a 64 bit value. - -@item c -An immediate for and/xor/or instructions. const_int is treated as a 64 bit value. - -@item d -An immediate for the @code{iohl} instruction. const_int is treated as a 64 bit value. - -@item f -An immediate which can be loaded with @code{fsmbi}. - -@item A -An immediate which can be loaded with the il/ila/ilh/ilhu instructions. const_int is treated as a 32 bit value. - -@item B -An immediate for most arithmetic instructions. const_int is treated as a 32 bit value. - -@item C -An immediate for and/xor/or instructions. const_int is treated as a 32 bit value. - -@item D -An immediate for the @code{iohl} instruction. const_int is treated as a 32 bit value. - -@item I -A constant in the range [@minus{}64, 63] for shift/rotate instructions. - -@item J -An unsigned 7-bit constant for conversion/nop/channel instructions. - -@item K -A signed 10-bit constant for most arithmetic instructions. - -@item M -A signed 16 bit immediate for @code{stop}. - -@item N -An unsigned 16-bit constant for @code{iohl} and @code{fsmbi}. - -@item O -An unsigned 7-bit constant whose 3 least significant bits are 0. - -@item P -An unsigned 3-bit constant for 16-byte rotates and shifts - -@item R -Call operand, reg, for indirect calls - -@item S -Call operand, symbol, for relative calls. - -@item T -Call operand, const_int, for absolute calls. - -@item U -An immediate which can be loaded with the il/ila/ilh/ilhu instructions. const_int is sign extended to 128 bit. - -@item W -An immediate for shift and rotate instructions. const_int is treated as a 32 bit value. - -@item Y -An immediate for and/xor/or instructions. const_int is sign extended as a 128 bit. - -@item Z -An immediate for the @code{iohl} instruction. const_int is sign extended to 128 bit. - -@end table - @item TI C6X family---@file{config/c6x/constraints.md} @table @code @item a diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi index f9fcd09..7867ac8 100644 --- a/gcc/doc/sourcebuild.texi +++ b/gcc/doc/sourcebuild.texi @@ -2011,9 +2011,6 @@ PowerPC target supports PowerPC 405. @item ppc_recip_hw PowerPC target supports executing reciprocal estimate instructions. -@item spu_auto_overlay -SPU target has toolchain that supports automatic overlay generation. - @item vmx_hw PowerPC target supports executing AltiVec instructions. @@ -2423,13 +2420,6 @@ Target supports compiling @code{vpclmul} instructions. Target supports compiling @code{xop} instructions. @end table -@subsubsection Local to tests in @code{gcc.target/spu/ea} - -@table @code -@item ealib -Target @code{__ea} library functions are available. -@end table - @subsubsection Local to tests in @code{gcc.test-framework} @table @code diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 24e0d2b..1a17b06 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,168 @@ +2019-09-03 Ulrich Weigand + + * lib/compat.exp: Remove references to spu. + * lib/fortran-torture.exp: Likewise. + * lib/gcc-dg.exp: Likewise. + * lib/gfortran.exp: Likewise. + * lib/target-supports.exp: Likewise. + * lib/target-utils.exp: Likewise. + + * c-c++-common/torture/complex-sign-add.c: Remove references to spu. + * c-c++-common/torture/complex-sign-mixed-add.c: Likewise. + * c-c++-common/torture/complex-sign-mixed-div.c: Likewise. + * c-c++-common/torture/complex-sign-mixed-mul.c: Likewise. + * c-c++-common/torture/complex-sign-mixed-sub.c: Likewise. + * c-c++-common/torture/complex-sign-mul-minus-one.c: Likewise. + * c-c++-common/torture/complex-sign-mul-one.c: Likewise. + * c-c++-common/torture/complex-sign-mul.c: Likewise. + * c-c++-common/torture/complex-sign-sub.c: Likewise. + + * g++.dg/opt/temp1.C: Remove references to spu. + * g++.dg/opt/vt1.C: Likewise. + * g++.dg/torture/type-generic-1.C: Likewise. + * g++.dg/warn/pr30551-2.C: Likewise. + * g++.dg/warn/pr30551.C: Likewise. + * g++.old-deja/g++.jason/thunk2.C: Likewise. + * g++.old-deja/g++.other/comdat5.C: Likewise. + * g++.old-deja/g++.other/local-alloc1.C: Likewise. + + * gcc.c-torture/compile/20001226-1.c: Remove references to spu. + * gcc.c-torture/execute/20030222-1.c: Likewise. + * gcc.c-torture/execute/20031003-1.c: Likewise. + * gcc.c-torture/execute/20101011-1.c: Likewise. + * gcc.c-torture/execute/conversion.c: Likewise. + * gcc.c-torture/execute/ieee/compare-fp-4.x: Likewise. + * gcc.c-torture/execute/ieee/fp-cmp-2.x: Likewise. + * gcc.c-torture/execute/ieee/inf-1.c: Likewise. + * gcc.c-torture/execute/ieee/inf-2.c: Likewise. + * gcc.c-torture/execute/ieee/mul-subnormal-single-1.x: Likewise. + * gcc.c-torture/execute/ieee/rbug.c: Likewise. + * gcc.c-torture/execute/pr39228.c: Likewise. + * gcc.c-torture/execute/ieee/20010114-2.x: Remove file. + * gcc.c-torture/execute/ieee/20030331-1.x: Remove file. + * gcc.c-torture/execute/ieee/920518-1.x: Remove file. + * gcc.c-torture/execute/ieee/compare-fp-1.x: Remove file. + * gcc.c-torture/execute/ieee/fp-cmp-4f.x: Remove file. + * gcc.c-torture/execute/ieee/fp-cmp-8f.x: Remove file. + + * gcc.dg/20020312-2.c: Remove references to spu. + * gcc.dg/20030702-1.c: Likewise. + * gcc.dg/and-1.c: Likewise. + * gcc.dg/builtin-inf-1.c: Likewise. + * gcc.dg/builtins-1.c: Likewise. + * gcc.dg/builtins-43.c: Likewise. + * gcc.dg/builtins-44.c: Likewise. + * gcc.dg/builtins-45.c: Likewise. + * gcc.dg/float-range-1.c: Likewise. + * gcc.dg/float-range-3.c: Likewise. + * gcc.dg/float-range-4.c: Likewise. + * gcc.dg/float-range-5.c: Likewise. + * gcc.dg/fold-overflow-1.c: Likewise. + * gcc.dg/format/ms_unnamed-1.c: Likewise. + * gcc.dg/format/unnamed-1.c: Likewise. + * gcc.dg/hex-round-1.c: Likewise. + * gcc.dg/hex-round-2.c: Likewise. + * gcc.dg/lower-subreg-1.c: Likewise. + * gcc.dg/nrv3.c: Likewise. + * gcc.dg/pr15784-3.c: Likewise. + * gcc.dg/pr27095.c: Likewise. + * gcc.dg/pr28243.c: Likewise. + * gcc.dg/pr28796-2.c: Likewise. + * gcc.dg/pr30551-3.c: Likewise. + * gcc.dg/pr30551-6.c: Likewise. + * gcc.dg/pr30551.c: Likewise. + * gcc.dg/pr70317.c: Likewise. + * gcc.dg/sms-1.c: Likewise. + * gcc.dg/sms-2.c: Likewise. + * gcc.dg/sms-3.c: Likewise. + * gcc.dg/sms-4.c: Likewise. + * gcc.dg/sms-5.c: Likewise. + * gcc.dg/sms-6.c: Likewise. + * gcc.dg/sms-7.c: Likewise. + * gcc.dg/stack-usage-1.c: Likewise. + * gcc.dg/strlenopt-73.c: Likewise. + * gcc.dg/titype-1.c: Likewise. + * gcc.dg/tls/thr-cse-1.c: Likewise. + * gcc.dg/torture/builtin-attr-1.c: Likewise. + * gcc.dg/torture/builtin-complex-1.c: Likewise. + * gcc.dg/torture/builtin-cproj-1.c: Likewise. + * gcc.dg/torture/builtin-frexp-1.c: Likewise. + * gcc.dg/torture/builtin-ldexp-1.c: Likewise. + * gcc.dg/torture/builtin-logb-1.c: Likewise. + * gcc.dg/torture/builtin-math-2.c: Likewise. + * gcc.dg/torture/builtin-math-5.c: Likewise. + * gcc.dg/torture/builtin-modf-1.c: Likewise. + * gcc.dg/torture/fp-int-convert.h: Likewise. + * gcc.dg/torture/pr25947-1.c: Likewise. + * gcc.dg/torture/type-generic-1.c: Likewise. + * gcc.dg/tree-ssa/20040204-1.c: Likewise. + * gcc.dg/tree-ssa/ivopts-1.c: Likewise. + * gcc.dg/tree-ssa/ssa-fre-3.c: Likewise. + * gcc.dg/tree-ssa/vector-6.c: Likewise. + * gcc.dg/uninit-C-O0.c: Likewise. + * gcc.dg/uninit-C.c: Likewise. + * gcc.dg/vect/no-math-errno-slp-32.c: Likewise. + * gcc.dg/vect/no-math-errno-vect-pow-1.c: Likewise. + * gcc.dg/vect/vect-float-extend-1.c: Likewise. + * gcc.dg/vect/vect-float-truncate-1.c: Likewise. + * gcc.dg/vect/vect.exp: Likewise. + * gcc.gd/vect/costmodel/spu/: Remove directory. + + * gcc.target/spu/: Remove directory. + + * gfortran.dg/bessel_6.f90: Remove references to spu. + * gfortran.dg/bessel_7.f90: Likewise. + * gfortran.dg/char4_iunit_1.f03: Likewise. + * gfortran.dg/chmod_1.f90: Likewise. + * gfortran.dg/chmod_2.f90: Likewise. + * gfortran.dg/chmod_3.f90: Likewise. + * gfortran.dg/default_format_1.f90: Likewise. + * gfortran.dg/default_format_denormal_1.f90: Likewise. + * gfortran.dg/erf_2.F90: Likewise. + * gfortran.dg/erf_3.F90: Likewise. + * gfortran.dg/init_flag_10.f90: Likewise. + * gfortran.dg/init_flag_3.f90: Likewise. + * gfortran.dg/int_conv_2.f90: Likewise. + * gfortran.dg/integer_exponentiation_3.F90: Likewise. + * gfortran.dg/integer_exponentiation_5.F90: Likewise. + * gfortran.dg/isnan_1.f90: Likewise. + * gfortran.dg/isnan_2.f90: Likewise. + * gfortran.dg/maxloc_2.f90: Likewise. + * gfortran.dg/maxlocval_2.f90: Likewise. + * gfortran.dg/maxlocval_4.f90: Likewise. + * gfortran.dg/minloc_1.f90: Likewise. + * gfortran.dg/minlocval_1.f90: Likewise. + * gfortran.dg/minlocval_4.f90: Likewise. + * gfortran.dg/module_nan.f90: Likewise. + * gfortran.dg/namelist_42.f90: Likewise. + * gfortran.dg/namelist_43.f90: Likewise. + * gfortran.dg/nan_1.f90: Likewise. + * gfortran.dg/nan_2.f90: Likewise. + * gfortran.dg/nan_3.f90: Likewise. + * gfortran.dg/nan_4.f90: Likewise. + * gfortran.dg/nan_5.f90: Likewise. + * gfortran.dg/nan_6.f90: Likewise. + * gfortran.dg/nearest_1.f90: Likewise. + * gfortran.dg/nearest_3.f90: Likewise. + * gfortran.dg/open_errors.f90: Likewise. + * gfortran.dg/pr20257.f90: Likewise. + * gfortran.dg/read_infnan_1.f90: Likewise. + * gfortran.dg/real_const_3.f90: Likewise. + * gfortran.dg/realloc_on_assign_2.f03: Likewise. + * gfortran.dg/reassoc_4.f: Likewise. + * gfortran.dg/scalar_mask_2.f90: Likewise. + * gfortran.dg/scratch_1.f90: Likewise. + * gfortran.dg/stat_1.f90: Likewise. + * gfortran.dg/stat_2.f90: Likewise. + * gfortran.dg/transfer_simplify_1.f90: Likewise. + * gfortran.dg/typebound_operator_9.f03: Likewise. + + * gfortran.fortran-torture/execute/intrinsic_nearest.x: Remove + references to spu. + * gfortran.fortran-torture/execute/intrinsic_set_exponent.x: Likewise. + * gfortran.fortran-torture/execute/nan_inf_fmt.x: Likewise. + * gfortran.fortran-torture/execute/getarg_1.x: Remove file. + 2019-09-03 Bernd Edlinger PR middle-end/91603 diff --git a/gcc/testsuite/c-c++-common/torture/complex-sign-add.c b/gcc/testsuite/c-c++-common/torture/complex-sign-add.c index bcaf8bb..e812232 100644 --- a/gcc/testsuite/c-c++-common/torture/complex-sign-add.c +++ b/gcc/testsuite/c-c++-common/torture/complex-sign-add.c @@ -28,9 +28,7 @@ void check_add_float (void) { -#ifndef __SPU__ CHECK_ADD (float, __builtin_copysignf, 0.0f, 0.0if); -#endif } void diff --git a/gcc/testsuite/c-c++-common/torture/complex-sign-mixed-add.c b/gcc/testsuite/c-c++-common/torture/complex-sign-mixed-add.c index 75e34a1..a209161 100644 --- a/gcc/testsuite/c-c++-common/torture/complex-sign-mixed-add.c +++ b/gcc/testsuite/c-c++-common/torture/complex-sign-mixed-add.c @@ -29,9 +29,7 @@ void check_add_float (void) { -#ifndef __SPU__ CHECK_ADD (float, __builtin_copysignf, 0.0f, 0.0if); -#endif } void diff --git a/gcc/testsuite/c-c++-common/torture/complex-sign-mixed-div.c b/gcc/testsuite/c-c++-common/torture/complex-sign-mixed-div.c index 269d5ec..f7ee483 100644 --- a/gcc/testsuite/c-c++-common/torture/complex-sign-mixed-div.c +++ b/gcc/testsuite/c-c++-common/torture/complex-sign-mixed-div.c @@ -20,9 +20,7 @@ void check_div_float (void) { -#ifndef __SPU__ CHECK_DIV (float, __builtin_copysignf, 0.0f, 0.0if, 1.0f); -#endif } void diff --git a/gcc/testsuite/c-c++-common/torture/complex-sign-mixed-mul.c b/gcc/testsuite/c-c++-common/torture/complex-sign-mixed-mul.c index e79db6d..02f936b 100644 --- a/gcc/testsuite/c-c++-common/torture/complex-sign-mixed-mul.c +++ b/gcc/testsuite/c-c++-common/torture/complex-sign-mixed-mul.c @@ -28,9 +28,7 @@ void check_mul_float (void) { -#ifndef __SPU__ CHECK_MUL (float, __builtin_copysignf, 0.0f, 0.0if); -#endif } void diff --git a/gcc/testsuite/c-c++-common/torture/complex-sign-mixed-sub.c b/gcc/testsuite/c-c++-common/torture/complex-sign-mixed-sub.c index 0c88961..02ab4db 100644 --- a/gcc/testsuite/c-c++-common/torture/complex-sign-mixed-sub.c +++ b/gcc/testsuite/c-c++-common/torture/complex-sign-mixed-sub.c @@ -29,9 +29,7 @@ void check_sub_float (void) { -#ifndef __SPU__ CHECK_SUB (float, __builtin_copysignf, 0.0f, 0.0if); -#endif } void diff --git a/gcc/testsuite/c-c++-common/torture/complex-sign-mul-minus-one.c b/gcc/testsuite/c-c++-common/torture/complex-sign-mul-minus-one.c index d20b5e6..05cc4fa 100644 --- a/gcc/testsuite/c-c++-common/torture/complex-sign-mul-minus-one.c +++ b/gcc/testsuite/c-c++-common/torture/complex-sign-mul-minus-one.c @@ -36,9 +36,7 @@ void check_mul_float (void) { -#ifndef __SPU__ CHECK_MUL (float, __builtin_copysignf, 0.0f, 0.0if, 1.0f); -#endif } void diff --git a/gcc/testsuite/c-c++-common/torture/complex-sign-mul-one.c b/gcc/testsuite/c-c++-common/torture/complex-sign-mul-one.c index ad02a2c..014d813 100644 --- a/gcc/testsuite/c-c++-common/torture/complex-sign-mul-one.c +++ b/gcc/testsuite/c-c++-common/torture/complex-sign-mul-one.c @@ -36,9 +36,7 @@ void check_mul_float (void) { -#ifndef __SPU__ CHECK_MUL (float, __builtin_copysignf, 0.0f, 0.0if, 1.0f); -#endif } void diff --git a/gcc/testsuite/c-c++-common/torture/complex-sign-mul.c b/gcc/testsuite/c-c++-common/torture/complex-sign-mul.c index a3274d2..08d247a 100644 --- a/gcc/testsuite/c-c++-common/torture/complex-sign-mul.c +++ b/gcc/testsuite/c-c++-common/torture/complex-sign-mul.c @@ -28,9 +28,7 @@ void check_mul_float (void) { -#ifndef __SPU__ CHECK_MUL (float, __builtin_copysignf, 0.0f, 0.0if); -#endif } void diff --git a/gcc/testsuite/c-c++-common/torture/complex-sign-sub.c b/gcc/testsuite/c-c++-common/torture/complex-sign-sub.c index 0a4e302..d4da14d 100644 --- a/gcc/testsuite/c-c++-common/torture/complex-sign-sub.c +++ b/gcc/testsuite/c-c++-common/torture/complex-sign-sub.c @@ -28,9 +28,7 @@ void check_sub_float (void) { -#ifndef __SPU__ CHECK_SUB (float, __builtin_copysignf, 0.0f, 0.0if); -#endif } void diff --git a/gcc/testsuite/g++.dg/opt/temp1.C b/gcc/testsuite/g++.dg/opt/temp1.C index dc13f51..b822dc4 100644 --- a/gcc/testsuite/g++.dg/opt/temp1.C +++ b/gcc/testsuite/g++.dg/opt/temp1.C @@ -24,12 +24,7 @@ void *memcpy (void *dest, const void *src, __SIZE_TYPE__ n) } struct T { -#ifdef __SPU__ - /* SPU returns aggregates up to 1172 bytes in registers. */ - int a[300]; -#else int a[128]; -#endif T &operator+=(T const &v) __attribute__((noinline)); T operator+(T const &v) const { T t = *this; t += v; return t; } }; diff --git a/gcc/testsuite/g++.dg/opt/vt1.C b/gcc/testsuite/g++.dg/opt/vt1.C index 1b08718..a15f776 100644 --- a/gcc/testsuite/g++.dg/opt/vt1.C +++ b/gcc/testsuite/g++.dg/opt/vt1.C @@ -1,7 +1,6 @@ // Test whether vtable for S is not put into read-only section. // { dg-do compile { target fpic } } // { dg-options "-O2 -fpic -fno-rtti" } -// { dg-skip-if "requires unsupported run-time relocation" { spu-*-* } } // { dg-skip-if "No Windows PIC" { *-*-mingw* *-*-cygwin } } // Origin: Jakub Jelinek diff --git a/gcc/testsuite/g++.dg/torture/type-generic-1.C b/gcc/testsuite/g++.dg/torture/type-generic-1.C index 7708724..e41b8e0 100644 --- a/gcc/testsuite/g++.dg/torture/type-generic-1.C +++ b/gcc/testsuite/g++.dg/torture/type-generic-1.C @@ -3,7 +3,6 @@ /* { dg-do run } */ /* { dg-add-options ieee } */ -/* { dg-skip-if "No Inf/NaN support" { spu-*-* } } */ /* { dg-skip-if "No subnormal support" { csky-*-* } { "-mhard-float" } } */ #include "../../gcc.dg/tg-tests.h" diff --git a/gcc/testsuite/g++.dg/warn/pr30551-2.C b/gcc/testsuite/g++.dg/warn/pr30551-2.C index b224470..95085c6 100644 --- a/gcc/testsuite/g++.dg/warn/pr30551-2.C +++ b/gcc/testsuite/g++.dg/warn/pr30551-2.C @@ -1,6 +1,5 @@ // PR 30551 -Wmain is enabled by -pedantic/-pedantic-errors. // { dg-do compile } // { dg-options "-pedantic-errors" } -// { dg-skip-if "-Wmain not enabled with -pedantic on SPU" { spu-*-* } } int main(char a) {} /* { dg-error "first argument of .*main.* should be .int." "int" } */ /* { dg-error "main.* takes only zero or two arguments" "zero or two" { target *-*-* } .-1 } */ diff --git a/gcc/testsuite/g++.dg/warn/pr30551.C b/gcc/testsuite/g++.dg/warn/pr30551.C index 4b3868e..359b362 100644 --- a/gcc/testsuite/g++.dg/warn/pr30551.C +++ b/gcc/testsuite/g++.dg/warn/pr30551.C @@ -1,6 +1,5 @@ // PR 30551 -Wmain is enabled by default. // { dg-do compile } // { dg-options "" } -// { dg-skip-if "-Wmain not enabled on SPU" { spu-*-* } } int main(char a) {} /* { dg-warning "first argument of .*main.* should be .int." "int" } */ /* { dg-warning "main.* takes only zero or two arguments" "zero or two" { target *-*-* } .-1 } */ diff --git a/gcc/testsuite/g++.old-deja/g++.jason/thunk2.C b/gcc/testsuite/g++.old-deja/g++.jason/thunk2.C index 8c02fc8..fdcff09 100644 --- a/gcc/testsuite/g++.old-deja/g++.jason/thunk2.C +++ b/gcc/testsuite/g++.old-deja/g++.jason/thunk2.C @@ -1,6 +1,5 @@ // { dg-do run { target fpic } } // { dg-options "-fPIC" } -// { dg-skip-if "requires unsupported run-time relocation" { spu-*-* } } // Test that non-variadic function calls using thunks and PIC work right. struct A { diff --git a/gcc/testsuite/g++.old-deja/g++.other/comdat5.C b/gcc/testsuite/g++.old-deja/g++.other/comdat5.C index 3336496..5c2baa3 100644 --- a/gcc/testsuite/g++.old-deja/g++.other/comdat5.C +++ b/gcc/testsuite/g++.old-deja/g++.other/comdat5.C @@ -2,6 +2,5 @@ // { dg-do link { target fpic } } // { dg-additional-sources " comdat5-aux.cc" } // { dg-options "-O2 -fPIC" } -// { dg-skip-if "requires unsupported run-time relocation" { spu-*-* } } #include "comdat4.C" diff --git a/gcc/testsuite/g++.old-deja/g++.other/local-alloc1.C b/gcc/testsuite/g++.old-deja/g++.other/local-alloc1.C index d595d98..fe9d24f 100644 --- a/gcc/testsuite/g++.old-deja/g++.other/local-alloc1.C +++ b/gcc/testsuite/g++.old-deja/g++.other/local-alloc1.C @@ -1,6 +1,5 @@ // { dg-do assemble { target fpic } } // { dg-options "-O0 -fpic" } -// { dg-skip-if "requires unsupported run-time relocation" { spu-*-* } } // Origin: Jakub Jelinek struct bar { diff --git a/gcc/testsuite/gcc.c-torture/compile/20001226-1.c b/gcc/testsuite/gcc.c-torture/compile/20001226-1.c index be0bdcf..073ac6a 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20001226-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20001226-1.c @@ -1,7 +1,6 @@ /* { dg-do assemble } */ /* { dg-skip-if "too much code for avr" { "avr-*-*" } } */ /* { dg-skip-if "too much code for pdp11" { "pdp11-*-*" } } */ -/* { dg-xfail-if "PR36698" { spu-*-* } { "-O0" } { "" } } */ /* { dg-skip-if "" { m32c-*-* } } */ /* { dg-timeout-factor 4.0 } */ diff --git a/gcc/testsuite/gcc.c-torture/execute/20030222-1.c b/gcc/testsuite/gcc.c-torture/execute/20030222-1.c index dbac74a..d395b8d 100644 --- a/gcc/testsuite/gcc.c-torture/execute/20030222-1.c +++ b/gcc/testsuite/gcc.c-torture/execute/20030222-1.c @@ -3,7 +3,6 @@ succeeded at all. We use volatile to make sure the long long is actually truncated to int, in case a single register is wide enough for a long long. */ -/* { dg-skip-if "asm would require extra shift-left-4-byte" { spu-*-* } } */ /* { dg-skip-if "asm requires register allocation" { nvptx-*-* } } */ #include diff --git a/gcc/testsuite/gcc.c-torture/execute/20031003-1.c b/gcc/testsuite/gcc.c-torture/execute/20031003-1.c index 5d172e7..5d39d79 100644 --- a/gcc/testsuite/gcc.c-torture/execute/20031003-1.c +++ b/gcc/testsuite/gcc.c-torture/execute/20031003-1.c @@ -19,15 +19,9 @@ int main() #if INT_MAX == 2147483647 if (f1() != 2147483647) abort (); -#ifdef __SPU__ - /* SPU float rounds towards zero. */ - if (f2() != 0x7fffff80) - abort (); -#else if (f2() != 2147483647) abort (); #endif -#endif return 0; } diff --git a/gcc/testsuite/gcc.c-torture/execute/20101011-1.c b/gcc/testsuite/gcc.c-torture/execute/20101011-1.c index 772648d..649e168 100644 --- a/gcc/testsuite/gcc.c-torture/execute/20101011-1.c +++ b/gcc/testsuite/gcc.c-torture/execute/20101011-1.c @@ -10,9 +10,6 @@ #elif defined (__riscv) /* On RISC-V division by zero does not trap. */ # define DO_TEST 0 -#elif defined (__SPU__) - /* On SPU division by zero does not trap. */ -# define DO_TEST 0 #elif defined (__sh__) /* On SH division by zero does not trap. */ # define DO_TEST 0 diff --git a/gcc/testsuite/gcc.c-torture/execute/conversion.c b/gcc/testsuite/gcc.c-torture/execute/conversion.c index 82d681a..9e62acf 100644 --- a/gcc/testsuite/gcc.c-torture/execute/conversion.c +++ b/gcc/testsuite/gcc.c-torture/execute/conversion.c @@ -284,15 +284,9 @@ test_float_to_integer() abort(); if (f2u(1.99) != 1) abort(); -#ifdef __SPU__ - /* SPU float rounds towards zero. */ - if (f2u((float) ((~0U) >> 1)) != 0x7fffff80) - abort(); -#else if (f2u((float) ((~0U) >> 1)) != (~0U) >> 1 && /* 0x7fffffff */ f2u((float) ((~0U) >> 1)) != ((~0U) >> 1) + 1) abort(); -#endif if (f2u((float) ~((~0U) >> 1)) != ~((~0U) >> 1)) /* 0x80000000 */ abort(); @@ -445,15 +439,9 @@ test_float_to_longlong_integer() abort(); if (f2ull(1.99) != 1LL) abort(); -#ifdef __SPU__ - /* SPU float rounds towards zero. */ - if (f2ull((float) ((~0ULL) >> 1)) != 0x7fffff8000000000ULL) - abort(); -#else if (f2ull((float) ((~0ULL) >> 1)) != (~0ULL) >> 1 && /* 0x7fffffff */ f2ull((float) ((~0ULL) >> 1)) != ((~0ULL) >> 1) + 1) abort(); -#endif if (f2ull((float) ~((~0ULL) >> 1)) != ~((~0ULL) >> 1)) /* 0x80000000 */ abort(); diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/20010114-2.x b/gcc/testsuite/gcc.c-torture/execute/ieee/20010114-2.x deleted file mode 100644 index 73b18d1..0000000 --- a/gcc/testsuite/gcc.c-torture/execute/ieee/20010114-2.x +++ /dev/null @@ -1,6 +0,0 @@ -if [istarget "spu-*-*"] { - # This doesn't work on the SPU because single precision floats are - # always rounded toward 0. - return 1 -} -return 0 diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/20030331-1.x b/gcc/testsuite/gcc.c-torture/execute/ieee/20030331-1.x deleted file mode 100644 index 73b18d1..0000000 --- a/gcc/testsuite/gcc.c-torture/execute/ieee/20030331-1.x +++ /dev/null @@ -1,6 +0,0 @@ -if [istarget "spu-*-*"] { - # This doesn't work on the SPU because single precision floats are - # always rounded toward 0. - return 1 -} -return 0 diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/920518-1.x b/gcc/testsuite/gcc.c-torture/execute/ieee/920518-1.x deleted file mode 100644 index 73b18d1..0000000 --- a/gcc/testsuite/gcc.c-torture/execute/ieee/920518-1.x +++ /dev/null @@ -1,6 +0,0 @@ -if [istarget "spu-*-*"] { - # This doesn't work on the SPU because single precision floats are - # always rounded toward 0. - return 1 -} -return 0 diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-1.x b/gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-1.x deleted file mode 100644 index 2f7a4ec..0000000 --- a/gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-1.x +++ /dev/null @@ -1,6 +0,0 @@ -if [istarget "spu-*-*"] { - # The SPU single-precision floating point format does not - # support Nan & Inf. - return 1 -} -return 0 diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-4.x b/gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-4.x index d7ecd11..510a309 100644 --- a/gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-4.x +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-4.x @@ -13,11 +13,5 @@ if [istarget "arm*-*-vxworks*"] { } } -if [istarget "spu-*-*"] { - # The SPU single-precision floating point format does not - # support Nan & Inf. - return 1 -} - lappend additional_flags "-fno-trapping-math" return 0 diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-2.x b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-2.x index 0fe5a98..84c193f 100644 --- a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-2.x +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-2.x @@ -13,10 +13,4 @@ if [istarget "arm*-*-vxworks*"] { } } -if [istarget "spu-*-*"] { - # The SPU single-precision floating point format does not - # support Nan & Inf. - return 1 -} - return 0 diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-4f.x b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-4f.x deleted file mode 100644 index 2f7a4ec..0000000 --- a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-4f.x +++ /dev/null @@ -1,6 +0,0 @@ -if [istarget "spu-*-*"] { - # The SPU single-precision floating point format does not - # support Nan & Inf. - return 1 -} -return 0 diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-8f.x b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-8f.x deleted file mode 100644 index 2f7a4ec..0000000 --- a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-8f.x +++ /dev/null @@ -1,6 +0,0 @@ -if [istarget "spu-*-*"] { - # The SPU single-precision floating point format does not - # support Nan & Inf. - return 1 -} -return 0 diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/inf-1.c b/gcc/testsuite/gcc.c-torture/execute/ieee/inf-1.c index eee8c01..34f60f3 100644 --- a/gcc/testsuite/gcc.c-torture/execute/ieee/inf-1.c +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/inf-1.c @@ -2,10 +2,7 @@ extern void abort (void); int main() { -#ifndef __SPU__ - /* The SPU single-precision floating point format does not support Inf. */ float fi = __builtin_inff(); -#endif double di = __builtin_inf(); long double li = __builtin_infl(); @@ -13,28 +10,22 @@ int main() double dh = __builtin_huge_val(); long double lh = __builtin_huge_vall(); -#ifndef __SPU__ if (fi + fi != fi) abort (); -#endif if (di + di != di) abort (); if (li + li != li) abort (); -#ifndef __SPU__ if (fi != fh) abort (); -#endif if (di != dh) abort (); if (li != lh) abort (); -#ifndef __SPU__ if (fi <= 0) abort (); -#endif if (di <= 0) abort (); if (li <= 0) diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/inf-2.c b/gcc/testsuite/gcc.c-torture/execute/ieee/inf-2.c index dafd958..50124b2 100644 --- a/gcc/testsuite/gcc.c-torture/execute/ieee/inf-2.c +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/inf-2.c @@ -25,9 +25,6 @@ void test(double f, double i) void testf(float f, float i) { -#ifndef __SPU__ - /* The SPU single-precision floating point format does not support Inf. */ - if (f == __builtin_inff()) abort (); if (f == -__builtin_inff()) @@ -47,7 +44,6 @@ void testf(float f, float i) abort (); if (f < -__builtin_inff()) abort (); -#endif } void testl(long double f, long double i) diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/mul-subnormal-single-1.x b/gcc/testsuite/gcc.c-torture/execute/ieee/mul-subnormal-single-1.x index ee40863..bf17081 100644 --- a/gcc/testsuite/gcc.c-torture/execute/ieee/mul-subnormal-single-1.x +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/mul-subnormal-single-1.x @@ -13,11 +13,6 @@ if {[istarget "m68k-*-*"] && [check_effective_target_coldfire_fpu]} { # not aware of any system that has this. set torture_execute_xfail "m68k-*-*" } -if [istarget "spu-*-*"] { - # The SPU single-precision floating point format does not - # support subnormals. - return 1 -} if { [istarget "tic6x-*-*"] && [check_effective_target_ti_c67x] } { # C6X floating point hardware turns denormals to zero in multiplications. set torture_execute_xfail "tic6x-*-*" diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/rbug.c b/gcc/testsuite/gcc.c-torture/execute/ieee/rbug.c index 1586bd7..ce13d7e 100644 --- a/gcc/testsuite/gcc.c-torture/execute/ieee/rbug.c +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/rbug.c @@ -41,14 +41,8 @@ main () k = 0x8234508000000001ULL; x = s (k); k = (unsigned long long) x; -#ifdef __SPU__ - /* SPU float rounds towards zero. */ - if (k != 0x8234500000000000ULL) - abort (); -#else if (k != 0x8234510000000000ULL) abort (); -#endif exit (0); } diff --git a/gcc/testsuite/gcc.c-torture/execute/pr39228.c b/gcc/testsuite/gcc.c-torture/execute/pr39228.c index ad0d376..f31ec90 100644 --- a/gcc/testsuite/gcc.c-torture/execute/pr39228.c +++ b/gcc/testsuite/gcc.c-torture/execute/pr39228.c @@ -1,5 +1,4 @@ /* { dg-add-options ieee } */ -/* { dg-skip-if "No Inf/NaN support" { spu-*-* } } */ extern void abort (void); diff --git a/gcc/testsuite/gcc.dg/20020312-2.c b/gcc/testsuite/gcc.dg/20020312-2.c index dae3599..98af0d4 100644 --- a/gcc/testsuite/gcc.dg/20020312-2.c +++ b/gcc/testsuite/gcc.dg/20020312-2.c @@ -96,8 +96,6 @@ extern void abort (void); /* No pic register. */ #elif defined(__m32c__) /* No pic register. */ -#elif defined(__SPU__) -# define PIC_REG "126" #elif defined (__frv__) # ifdef __FRV_FDPIC__ # define PIC_REG "gr15" diff --git a/gcc/testsuite/gcc.dg/20030702-1.c b/gcc/testsuite/gcc.dg/20030702-1.c index e4e981b..ee03f71 100644 --- a/gcc/testsuite/gcc.dg/20030702-1.c +++ b/gcc/testsuite/gcc.dg/20030702-1.c @@ -2,7 +2,6 @@ correctly in combine. */ /* { dg-do compile { target fpic } } */ /* { dg-options "-O2 -fpic -fprofile-arcs" } */ -/* { dg-skip-if "requires unsupported run-time relocation" { spu-*-* } } */ /* { dg-require-profiling "-fprofile-generate" } */ int fork (void); diff --git a/gcc/testsuite/gcc.dg/and-1.c b/gcc/testsuite/gcc.dg/and-1.c index c66e4e1..bec56fd 100644 --- a/gcc/testsuite/gcc.dg/and-1.c +++ b/gcc/testsuite/gcc.dg/and-1.c @@ -1,8 +1,8 @@ /* { dg-do compile } */ /* { dg-options "-O2" } */ -/* { dg-final { scan-assembler "and" { target powerpc*-*-* spu-*-* } } } */ -/* There should be no nand for this testcase (for either PPC or SPU). */ -/* { dg-final { scan-assembler-not "nand" { target powerpc*-*-* spu-*-* } } } */ +/* { dg-final { scan-assembler "and" { target powerpc*-*-* } } } */ +/* There should be no nand for this testcase (for PPC). */ +/* { dg-final { scan-assembler-not "nand" { target powerpc*-*-* } } } */ int f(int y) { diff --git a/gcc/testsuite/gcc.dg/builtin-inf-1.c b/gcc/testsuite/gcc.dg/builtin-inf-1.c index 4b7dcd8..b075fcd 100644 --- a/gcc/testsuite/gcc.dg/builtin-inf-1.c +++ b/gcc/testsuite/gcc.dg/builtin-inf-1.c @@ -1,7 +1,7 @@ /* { dg-do compile } */ float fi = __builtin_inff(); -/* { dg-error "does not support infinity" "INF unsupported" { target pdp11*-*-* vax-*-* spu-*-* } .-1 } */ +/* { dg-error "does not support infinity" "INF unsupported" { target pdp11*-*-* vax-*-* } .-1 } */ double di = __builtin_inf(); /* { dg-error "does not support infinity" "INF unsupported" { target pdp11*-*-* vax-*-* } .-1 } */ long double li = __builtin_infl(); diff --git a/gcc/testsuite/gcc.dg/builtins-1.c b/gcc/testsuite/gcc.dg/builtins-1.c index 26e8a05..6128642 100644 --- a/gcc/testsuite/gcc.dg/builtins-1.c +++ b/gcc/testsuite/gcc.dg/builtins-1.c @@ -144,7 +144,7 @@ FPTEST2ARG2_REENT (gamma, int *) /* gamma_r */ FPTEST0 (huge_val) FPTEST2 (hypot) FPTEST1 (ilogb) -FPTEST0 (inf) /* { dg-warning "target format does not support infinity" "inf" {target pdp11*-*-* spu-*-*} } */ +FPTEST0 (inf) /* { dg-warning "target format does not support infinity" "inf" {target pdp11*-*-* } } */ FPTEST1 (j0) FPTEST1 (j1) FPTEST2ARG1 (jn, int) diff --git a/gcc/testsuite/gcc.dg/builtins-43.c b/gcc/testsuite/gcc.dg/builtins-43.c index f7c318e..24a34ed 100644 --- a/gcc/testsuite/gcc.dg/builtins-43.c +++ b/gcc/testsuite/gcc.dg/builtins-43.c @@ -12,20 +12,15 @@ int main () { double nan = __builtin_nan (""); -#ifndef __SPU__ - /* The SPU single-precision floating point format does not support NANs. */ float nanf = __builtin_nanf (""); -#endif long double nanl = __builtin_nanl (""); if (!__builtin_isnan (nan)) link_error (); -#ifndef __SPU__ if (!__builtin_isnan (nanf)) link_error (); if (!__builtin_isnanf (nanf)) link_error (); -#endif if (!__builtin_isnan (nanl)) link_error (); if (!__builtin_isnanl (nanl)) diff --git a/gcc/testsuite/gcc.dg/builtins-44.c b/gcc/testsuite/gcc.dg/builtins-44.c index 8a06b59..4a12350 100644 --- a/gcc/testsuite/gcc.dg/builtins-44.c +++ b/gcc/testsuite/gcc.dg/builtins-44.c @@ -13,20 +13,15 @@ int main () { double pinf = __builtin_inf (); -#ifndef __SPU__ - /* The SPU single-precision floating point format does not support Inf. */ float pinff = __builtin_inff (); -#endif long double pinfl = __builtin_infl (); if (__builtin_isinf (pinf) != 1) link_error (); -#ifndef __SPU__ if (__builtin_isinf (pinff) != 1) link_error (); if (__builtin_isinff (pinff) != 1) link_error (); -#endif if (__builtin_isinf (pinfl) != 1) link_error (); if (__builtin_isinfl (pinfl) != 1) @@ -34,10 +29,8 @@ main () if (__builtin_isinf_sign (-pinf) != -1) link_error (); -#ifndef __SPU__ if (__builtin_isinf_sign (-pinff) != -1) link_error (); -#endif if (__builtin_isinf_sign (-pinfl) != -1) link_error (); diff --git a/gcc/testsuite/gcc.dg/builtins-45.c b/gcc/testsuite/gcc.dg/builtins-45.c index 0fa801b..871e802 100644 --- a/gcc/testsuite/gcc.dg/builtins-45.c +++ b/gcc/testsuite/gcc.dg/builtins-45.c @@ -13,34 +13,24 @@ int main () { double nan = __builtin_nan (""); -#ifndef __SPU__ - /* The SPU single-precision floating point format does not support NANs. */ float nanf = __builtin_nanf (""); -#endif long double nanl = __builtin_nanl (""); double pinf = __builtin_inf (); -#ifndef __SPU__ - /* The SPU single-precision floating point format does not support Inf. */ float pinff = __builtin_inff (); -#endif long double pinfl = __builtin_infl (); if (__builtin_finite (pinf)) link_error (); -#ifndef __SPU__ if (__builtin_finitef (pinff)) link_error (); -#endif if (__builtin_finitel (pinfl)) link_error (); if (__builtin_finite (nan)) link_error (); -#ifndef __SPU__ if (__builtin_finitef (nanf)) link_error (); -#endif if (__builtin_finitel (nanl)) link_error (); diff --git a/gcc/testsuite/gcc.dg/float-range-1.c b/gcc/testsuite/gcc.dg/float-range-1.c index 9185b22..0142c3d 100644 --- a/gcc/testsuite/gcc.dg/float-range-1.c +++ b/gcc/testsuite/gcc.dg/float-range-1.c @@ -4,7 +4,6 @@ /* Origin: Joseph Myers */ /* { dg-do compile } */ /* { dg-options "-ansi -pedantic-errors -Woverflow" } */ -/* { dg-skip-if "No Inf support" { spu-*-* } } */ void f (void) diff --git a/gcc/testsuite/gcc.dg/float-range-3.c b/gcc/testsuite/gcc.dg/float-range-3.c index 32bef98..e386bba 100644 --- a/gcc/testsuite/gcc.dg/float-range-3.c +++ b/gcc/testsuite/gcc.dg/float-range-3.c @@ -1,7 +1,6 @@ /* PR 23572 : warnings for out of range floating-point constants. */ /* { dg-do compile } */ /* { dg-options "-std=c99" } */ -/* { dg-skip-if "No Inf support" { spu-*-* } } */ #include #ifndef INFINITY diff --git a/gcc/testsuite/gcc.dg/float-range-4.c b/gcc/testsuite/gcc.dg/float-range-4.c index a50a47d..c4faaa06 100644 --- a/gcc/testsuite/gcc.dg/float-range-4.c +++ b/gcc/testsuite/gcc.dg/float-range-4.c @@ -1,7 +1,6 @@ /* PR 23572 : warnings for out of range floating-point constants. */ /* { dg-do compile } */ /* { dg-options "-Wno-overflow -std=c99" } */ -/* { dg-skip-if "No Inf support" { spu-*-* } } */ #include #ifndef INFINITY diff --git a/gcc/testsuite/gcc.dg/float-range-5.c b/gcc/testsuite/gcc.dg/float-range-5.c index 034f360..f3e06ba 100644 --- a/gcc/testsuite/gcc.dg/float-range-5.c +++ b/gcc/testsuite/gcc.dg/float-range-5.c @@ -2,7 +2,6 @@ Test that they are NOT pedantic warnings. */ /* { dg-do compile } */ /* { dg-options "-pedantic-errors -std=c99" } */ -/* { dg-skip-if "No Inf support" { spu-*-* } } */ #include #ifndef INFINITY diff --git a/gcc/testsuite/gcc.dg/fold-overflow-1.c b/gcc/testsuite/gcc.dg/fold-overflow-1.c index 4f45b35..108df4e 100644 --- a/gcc/testsuite/gcc.dg/fold-overflow-1.c +++ b/gcc/testsuite/gcc.dg/fold-overflow-1.c @@ -1,6 +1,5 @@ /* { dg-do compile } */ /* { dg-require-effective-target int32plus } */ -/* { dg-skip-if "No Inf support" { spu-*-* } } */ /* { dg-options "-O -ftrapping-math" } */ /* There should be exactly 2 +Inf in the assembly file. */ diff --git a/gcc/testsuite/gcc.dg/format/ms_unnamed-1.c b/gcc/testsuite/gcc.dg/format/ms_unnamed-1.c index a3a0e6a..e5a2562 100644 --- a/gcc/testsuite/gcc.dg/format/ms_unnamed-1.c +++ b/gcc/testsuite/gcc.dg/format/ms_unnamed-1.c @@ -10,7 +10,7 @@ /* Definition of TItype follows same logic as in gcc.dg/titype-1.c, but must be a #define to avoid giving the type a name. */ -#if (defined(__LP64__) && !defined(__hppa__)) || defined(__SPU__) +#if defined(__LP64__) && !defined(__hppa__) #define TItype int __attribute__ ((mode (TI))) #else #define TItype long diff --git a/gcc/testsuite/gcc.dg/format/unnamed-1.c b/gcc/testsuite/gcc.dg/format/unnamed-1.c index cb19c14..4b24bec 100644 --- a/gcc/testsuite/gcc.dg/format/unnamed-1.c +++ b/gcc/testsuite/gcc.dg/format/unnamed-1.c @@ -10,7 +10,7 @@ /* Definition of TItype follows same logic as in gcc.dg/titype-1.c, but must be a #define to avoid giving the type a name. */ -#if (defined(__LP64__) && !defined(__hppa__)) || defined(__SPU__) +#if defined(__LP64__) && !defined(__hppa__) #define TItype int __attribute__ ((mode (TI))) #else #define TItype long diff --git a/gcc/testsuite/gcc.dg/hex-round-1.c b/gcc/testsuite/gcc.dg/hex-round-1.c index e1283ca..3276ad4 100644 --- a/gcc/testsuite/gcc.dg/hex-round-1.c +++ b/gcc/testsuite/gcc.dg/hex-round-1.c @@ -1,7 +1,6 @@ /* Test for hexadecimal float rounding: bug 21720. */ /* { dg-do link } */ /* { dg-options "-O -std=gnu99" } */ -/* { dg-skip-if "SPU float rounds towards zero" { spu-*-* } } */ #include diff --git a/gcc/testsuite/gcc.dg/hex-round-2.c b/gcc/testsuite/gcc.dg/hex-round-2.c index af49536..ba9b8bf 100644 --- a/gcc/testsuite/gcc.dg/hex-round-2.c +++ b/gcc/testsuite/gcc.dg/hex-round-2.c @@ -2,7 +2,6 @@ in number. */ /* { dg-do link } */ /* { dg-options "-O -std=gnu99" } */ -/* { dg-skip-if "SPU float rounds towards zero" { spu-*-* } } */ #include diff --git a/gcc/testsuite/gcc.dg/lower-subreg-1.c b/gcc/testsuite/gcc.dg/lower-subreg-1.c index 6bae730..63a4710 100644 --- a/gcc/testsuite/gcc.dg/lower-subreg-1.c +++ b/gcc/testsuite/gcc.dg/lower-subreg-1.c @@ -1,4 +1,4 @@ -/* { dg-do compile { target { ! { mips64 || { aarch64*-*-* arm*-*-* ia64-*-* sparc*-*-* spu-*-* tilegx-*-* } } } } } */ +/* { dg-do compile { target { ! { mips64 || { aarch64*-*-* arm*-*-* ia64-*-* sparc*-*-* tilegx-*-* } } } } } */ /* { dg-options "-O -fdump-rtl-subreg1" } */ /* { dg-additional-options "-mno-stv" { target ia32 } } */ /* { dg-skip-if "" { { i?86-*-* x86_64-*-* } && x32 } } */ diff --git a/gcc/testsuite/gcc.dg/nrv3.c b/gcc/testsuite/gcc.dg/nrv3.c index 9723712..6c66ecf 100644 --- a/gcc/testsuite/gcc.dg/nrv3.c +++ b/gcc/testsuite/gcc.dg/nrv3.c @@ -3,12 +3,7 @@ /* { dg-do compile } */ /* { dg-options "-O -fdump-tree-optimized" } */ -#ifdef __SPU__ -/* SPU returns aggregates up to 1172 bytes in registers. */ -typedef struct { int x[300]; void *y; } S; -#else typedef struct { int x[20]; void *y; } S; -#endif typedef struct { int a; S b; } T; S nrv_candidate (void); void use_result (S, int); diff --git a/gcc/testsuite/gcc.dg/pr15784-3.c b/gcc/testsuite/gcc.dg/pr15784-3.c index c17d9e0..17bf722 100644 --- a/gcc/testsuite/gcc.dg/pr15784-3.c +++ b/gcc/testsuite/gcc.dg/pr15784-3.c @@ -1,5 +1,4 @@ /* { dg-do compile } */ -/* { dg-skip-if "No NaN support" { spu-*-* } } */ /* SH4 without -mieee defaults to -ffinite-math-only. */ /* { dg-options "-fdump-tree-gimple -fno-finite-math-only" } */ /* Test for folding abs(x) where appropriate. */ diff --git a/gcc/testsuite/gcc.dg/pr27095.c b/gcc/testsuite/gcc.dg/pr27095.c index 8d2b47b..1c3566c 100644 --- a/gcc/testsuite/gcc.dg/pr27095.c +++ b/gcc/testsuite/gcc.dg/pr27095.c @@ -19,7 +19,7 @@ main (int argc, char **argv) memset (x, argc, strlen (x)); return 0; } -/* { dg-final { scan-assembler-not "(?n)strlen\(.*\n\)+.*strlen" { target { ! { powerpc*-*-darwin* hppa*-*-hpux* ia64-*-hpux* alpha*-*-* spu-*-* tic6x-*-* } } } } } */ +/* { dg-final { scan-assembler-not "(?n)strlen\(.*\n\)+.*strlen" { target { ! { powerpc*-*-darwin* hppa*-*-hpux* ia64-*-hpux* alpha*-*-* tic6x-*-* } } } } } */ /* hppa*-*-hpux* has an IMPORT statement for strlen (plus the branch). */ /* *-*-darwin* has something similar. */ /* tic6x emits a comment at the point where the delayed branch happens. */ @@ -29,5 +29,3 @@ main (int argc, char **argv) /* { dg-final { scan-assembler-not "(?n)strlen\(.*\n\)+.*strlen\(.*\n\)+.*strlen\(.*\n\)+.*strlen" { target ia64-*-hpux* } } } */ /* alpha-*-* has a GOT load and the call. */ /* { dg-final { scan-assembler-not "(?n)jsr .*,strlen\(.*\n\)+.*jsr .*,strlen" { target alpha*-*-* } } } */ -/* spu-*-* has a branch hint and the call. */ -/* { dg-final { scan-assembler-not "(?n)brsl.*,strlen\(.*\n\)+.*brsl.*,strlen" { target spu-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/pr28243.c b/gcc/testsuite/gcc.dg/pr28243.c index 3fc8b7e..a6d693e 100644 --- a/gcc/testsuite/gcc.dg/pr28243.c +++ b/gcc/testsuite/gcc.dg/pr28243.c @@ -4,7 +4,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target fpic } */ /* { dg-options "-O2 -ftracer -fPIC" } */ -/* { dg-skip-if "requires unsupported run-time relocation" { spu-*-* } } */ struct displayfuncs { void (*init) (); diff --git a/gcc/testsuite/gcc.dg/pr28796-2.c b/gcc/testsuite/gcc.dg/pr28796-2.c index f56a5d4..a56b4ab 100644 --- a/gcc/testsuite/gcc.dg/pr28796-2.c +++ b/gcc/testsuite/gcc.dg/pr28796-2.c @@ -1,7 +1,6 @@ /* { dg-do run } */ /* { dg-options "-O2 -funsafe-math-optimizations -fno-finite-math-only -DUNSAFE" } */ /* { dg-add-options ieee } */ -/* { dg-skip-if "No Inf/NaN support" { spu-*-* } } */ #include "tg-tests.h" diff --git a/gcc/testsuite/gcc.dg/pr30551-3.c b/gcc/testsuite/gcc.dg/pr30551-3.c index 02955e5..9151b1e 100644 --- a/gcc/testsuite/gcc.dg/pr30551-3.c +++ b/gcc/testsuite/gcc.dg/pr30551-3.c @@ -1,7 +1,6 @@ /* PR 30551 -Wmain is enabled by -pedantic-errors. */ /* { dg-do compile } */ /* { dg-options "-pedantic-errors" } */ -/* { dg-skip-if "-Wmain not enabled with -pedantic on SPU" { spu-*-* } } */ void main(char a) {} /* { dg-error "first argument of .main. should be .int." "int" } */ /* { dg-error ".main. takes only zero or two arguments" "zero or two" { target *-*-* } .-1 } */ /* { dg-error "return type of .main. is not .int." "return type" { target *-*-* } .-2 } */ diff --git a/gcc/testsuite/gcc.dg/pr30551-6.c b/gcc/testsuite/gcc.dg/pr30551-6.c index ed7ddab..fa6bf0c 100644 --- a/gcc/testsuite/gcc.dg/pr30551-6.c +++ b/gcc/testsuite/gcc.dg/pr30551-6.c @@ -1,7 +1,6 @@ /* PR 30551 -Wmain is enabled by -pedantic. */ /* { dg-do compile } */ /* { dg-options "-pedantic" } */ -/* { dg-skip-if "-Wmain not enabled with -pedantic on SPU" { spu-*-* } } */ void main(char a) {} /* { dg-warning "first argument of .main. should be .int." "int" } */ /* { dg-warning ".main. takes only zero or two arguments" "zero or two" { target *-*-* } .-1 } */ /* { dg-warning "return type of .main. is not .int." "return type" { target *-*-* } .-2 } */ diff --git a/gcc/testsuite/gcc.dg/pr30551.c b/gcc/testsuite/gcc.dg/pr30551.c index 979bcee..c7b108e 100644 --- a/gcc/testsuite/gcc.dg/pr30551.c +++ b/gcc/testsuite/gcc.dg/pr30551.c @@ -1,7 +1,6 @@ /* PR 30551 -Wmain is enabled by -Wall. */ /* { dg-do compile } */ /* { dg-options "-Wall" } */ -/* { dg-skip-if "-Wmain not enabled with -Wall on SPU" { spu-*-* } } */ void main(char a) {} /* { dg-warning "first argument of .main. should be .int." "int" } */ /* { dg-warning ".main. takes only zero or two arguments" "zero or two" { target *-*-* } .-1 } */ /* { dg-warning "return type of .main. is not .int." "return type" { target *-*-* } .-2 } */ diff --git a/gcc/testsuite/gcc.dg/pr70317.c b/gcc/testsuite/gcc.dg/pr70317.c index 3a9c52e..585212d 100644 --- a/gcc/testsuite/gcc.dg/pr70317.c +++ b/gcc/testsuite/gcc.dg/pr70317.c @@ -1,6 +1,6 @@ /* PR tree-optimization/70317 */ /* { dg-do compile } */ -/* { dg-skip-if "No NaN support" { spu*-*-* vax*-*-* pdp11*-*-* } } */ +/* { dg-skip-if "No NaN support" { vax*-*-* pdp11*-*-* } } */ /* { dg-options "-O2 -fdump-tree-optimized" } */ /* { dg-additional-options "-fno-common" { target hppa*-*-hpux* } } */ diff --git a/gcc/testsuite/gcc.dg/sms-1.c b/gcc/testsuite/gcc.dg/sms-1.c index 497fe0f..26868c3 100644 --- a/gcc/testsuite/gcc.dg/sms-1.c +++ b/gcc/testsuite/gcc.dg/sms-1.c @@ -40,5 +40,5 @@ main () return 0; } -/* { dg-final { scan-rtl-dump-times "SMS succeeded" 1 "sms" { target powerpc*-*-* spu-*-* } } } */ +/* { dg-final { scan-rtl-dump-times "SMS succeeded" 1 "sms" { target powerpc*-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/sms-2.c b/gcc/testsuite/gcc.dg/sms-2.c index c449398..7b96f55 100644 --- a/gcc/testsuite/gcc.dg/sms-2.c +++ b/gcc/testsuite/gcc.dg/sms-2.c @@ -32,4 +32,4 @@ fun (nb) } } -/* { dg-final { scan-rtl-dump-times "SMS loop many exits" 1 "sms" { target spu-*-* powerpc*-*-* } } } */ +/* { dg-final { scan-rtl-dump-times "SMS loop many exits" 1 "sms" { target powerpc*-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/sms-3.c b/gcc/testsuite/gcc.dg/sms-3.c index 78a6d84..822b516 100644 --- a/gcc/testsuite/gcc.dg/sms-3.c +++ b/gcc/testsuite/gcc.dg/sms-3.c @@ -39,5 +39,5 @@ main () return 0; } -/* { dg-final { scan-rtl-dump-times "SMS succeeded" 1 "sms" { target spu-*-* powerpc*-*-* } } } */ +/* { dg-final { scan-rtl-dump-times "SMS succeeded" 1 "sms" { target powerpc*-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/sms-4.c b/gcc/testsuite/gcc.dg/sms-4.c index 0dc1de2..f5ebb55 100644 --- a/gcc/testsuite/gcc.dg/sms-4.c +++ b/gcc/testsuite/gcc.dg/sms-4.c @@ -35,5 +35,5 @@ main () return 0; } -/* { dg-final { scan-rtl-dump-times "SMS succeeded" 1 "sms" { target spu-*-* powerpc*-*-* } } } */ +/* { dg-final { scan-rtl-dump-times "SMS succeeded" 1 "sms" { target powerpc*-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/sms-5.c b/gcc/testsuite/gcc.dg/sms-5.c index 09213cc..9ce36a0 100644 --- a/gcc/testsuite/gcc.dg/sms-5.c +++ b/gcc/testsuite/gcc.dg/sms-5.c @@ -46,6 +46,5 @@ int main () return 0; } -/* { dg-final { scan-rtl-dump-times "SMS succeeded" 1 "sms" { target spu-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/sms-6.c b/gcc/testsuite/gcc.dg/sms-6.c index cbc23ea..e57e015 100644 --- a/gcc/testsuite/gcc.dg/sms-6.c +++ b/gcc/testsuite/gcc.dg/sms-6.c @@ -42,5 +42,4 @@ int main() return 0; } -/* { dg-final { scan-rtl-dump-times "SMS succeeded" 1 "sms" { target spu-*-* } } } */ /* { dg-final { scan-rtl-dump-times "SMS succeeded" 3 "sms" { target powerpc*-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/sms-7.c b/gcc/testsuite/gcc.dg/sms-7.c index cd49461..4fd9bf1 100644 --- a/gcc/testsuite/gcc.dg/sms-7.c +++ b/gcc/testsuite/gcc.dg/sms-7.c @@ -44,5 +44,4 @@ int main() return 0; } -/* { dg-final { scan-rtl-dump-times "SMS succeeded" 1 "sms" { target spu-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/stack-usage-1.c b/gcc/testsuite/gcc.dg/stack-usage-1.c index b264222..be1254a 100644 --- a/gcc/testsuite/gcc.dg/stack-usage-1.c +++ b/gcc/testsuite/gcc.dg/stack-usage-1.c @@ -79,8 +79,6 @@ # define SIZE 96 /* 256 - 160 bytes for register save area */ #elif defined (__s390__) # define SIZE 160 /* 256 - 96 bytes for register save area */ -#elif defined (__SPU__) -# define SIZE 224 #elif defined (__epiphany__) # define SIZE (256 - __EPIPHANY_STACK_OFFSET__) #elif defined (__RL78__) diff --git a/gcc/testsuite/gcc.dg/strlenopt-73.c b/gcc/testsuite/gcc.dg/strlenopt-73.c index d3c3f05..6523949 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-73.c +++ b/gcc/testsuite/gcc.dg/strlenopt-73.c @@ -89,7 +89,7 @@ void test_copy_cond_unequal_length_i64 (void) /* The following tests assume GCC transforms the memcpy calls into int128_t assignments which it does only on targets that define - the MOVE_MAX macro to 16. That's only spu, s390, and i386 with + the MOVE_MAX macro to 16. That's only s390 and i386 with int128_t support. */ const char a8[32] = "01234567"; diff --git a/gcc/testsuite/gcc.dg/titype-1.c b/gcc/testsuite/gcc.dg/titype-1.c index ef860b9..31c01a6 100644 --- a/gcc/testsuite/gcc.dg/titype-1.c +++ b/gcc/testsuite/gcc.dg/titype-1.c @@ -1,7 +1,7 @@ /* { dg-do run } */ /* Not all platforms support TImode integers. */ -#if (defined(__LP64__) && !defined(__hppa__)) || defined(_WIN64) || defined(__SPU__) +#if (defined(__LP64__) && !defined(__hppa__)) || defined(_WIN64) typedef int TItype __attribute__ ((mode (TI))); #else typedef long TItype; diff --git a/gcc/testsuite/gcc.dg/tls/thr-cse-1.c b/gcc/testsuite/gcc.dg/tls/thr-cse-1.c index da2fbff..84eedfd 100644 --- a/gcc/testsuite/gcc.dg/tls/thr-cse-1.c +++ b/gcc/testsuite/gcc.dg/tls/thr-cse-1.c @@ -18,10 +18,9 @@ int foo (int b, int c, int d) return a; } -/* { dg-final { scan-assembler-not "emutls_get_address.*emutls_get_address.*" { target { ! { "*-wrs-vxworks" "*-*-darwin8" "hppa*-*-hpux*" "spu-*-*" "i?86-*-mingw*" "x86_64-*-mingw*" visium-*-* } } } } } */ +/* { dg-final { scan-assembler-not "emutls_get_address.*emutls_get_address.*" { target { ! { "*-wrs-vxworks" "*-*-darwin8" "hppa*-*-hpux*" "i?86-*-mingw*" "x86_64-*-mingw*" visium-*-* } } } } } */ /* { dg-final { scan-assembler-not "call\tL___emutls_get_address.stub.*call\tL___emutls_get_address.stub.*" { target "*-*-darwin8" } } } */ /* { dg-final { scan-assembler-not "(b,l|bl) __emutls_get_address.*(b,l|bl) __emutls_get_address.*" { target "hppa*-*-hpux*" } } } */ -/* { dg-final { scan-assembler-not "(brsl|brasl)\t__emutls_get_address.*(brsl|brasl)\t__emutls_get_address.*" { target spu-*-* } } } */ /* { dg-final { scan-assembler-not "tls_lookup.*tls_lookup.*" { target *-wrs-vxworks } } } */ /* { dg-final { scan-assembler-not "call\t___emutls_get_address.*call\t___emutls_get_address" { target "i?86-*-mingw*" } } } */ /* { dg-final { scan-assembler-not "call\t__emutls_get_address.*call\t__emutls_get_address" { target "x86_64-*-mingw*" } } } */ diff --git a/gcc/testsuite/gcc.dg/torture/builtin-attr-1.c b/gcc/testsuite/gcc.dg/torture/builtin-attr-1.c index c138b92..c5e5d2a 100644 --- a/gcc/testsuite/gcc.dg/torture/builtin-attr-1.c +++ b/gcc/testsuite/gcc.dg/torture/builtin-attr-1.c @@ -339,7 +339,7 @@ FPTEST2 (fmod) BUILTIN_FPTEST0 (huge_val) FPTEST2 (hypot) FPTEST1T (ilogb, int) -BUILTIN_FPTEST0 (inf) /* { dg-warning "does not support infinity" "INF unsupported" { target vax-*-* pdp11-*-* spu-*-* } } */ +BUILTIN_FPTEST0 (inf) /* { dg-warning "does not support infinity" "INF unsupported" { target vax-*-* pdp11-*-* } } */ FPTEST1 (j0) FPTEST1 (j1) FPTEST2ARG1 (jn, int) diff --git a/gcc/testsuite/gcc.dg/torture/builtin-complex-1.c b/gcc/testsuite/gcc.dg/torture/builtin-complex-1.c index 5a4ed3c..f0d3dd3 100644 --- a/gcc/testsuite/gcc.dg/torture/builtin-complex-1.c +++ b/gcc/testsuite/gcc.dg/torture/builtin-complex-1.c @@ -19,13 +19,11 @@ extern void abort (void); abort (); \ } while (0) -#ifndef __SPU__ void comparef (float a, float b) { COMPARE_BODY (a, b, float, __builtin_copysignf); } -#endif void compare (double a, double b) @@ -39,14 +37,12 @@ comparel (long double a, long double b) COMPARE_BODY (a, b, long double, __builtin_copysignl); } -#ifndef __SPU__ void comparecf (_Complex float a, float r, float i) { comparef (__real__ a, r); comparef (__imag__ a, i); } -#endif void comparec (_Complex double a, double r, double i) @@ -95,10 +91,8 @@ comparecl (_Complex long double a, long double r, long double i) void check_float (void) { -#ifndef __SPU__ ALL_CHECKS (0.0f, -0.0f, __builtin_nanf(""), __builtin_inff(), float, comparecf); -#endif } void diff --git a/gcc/testsuite/gcc.dg/torture/builtin-cproj-1.c b/gcc/testsuite/gcc.dg/torture/builtin-cproj-1.c index d79f34a..c8a3f51 100644 --- a/gcc/testsuite/gcc.dg/torture/builtin-cproj-1.c +++ b/gcc/testsuite/gcc.dg/torture/builtin-cproj-1.c @@ -18,11 +18,7 @@ extern void link_error(int); #define CPROJ(X) __builtin_cproj(X) #define CPROJF(X) __builtin_cprojf(X) #define CPROJL(X) __builtin_cprojl(X) -#ifndef __SPU__ #define INF __builtin_inff() -#else -#define INF __builtin_inf() -#endif #define I 1i #define CPSGN(X,Y) __builtin_copysignf((X),(Y)) #define CIMAG(X) __builtin_cimagf(X) @@ -36,7 +32,6 @@ extern void link_error(int); /* Test that (cproj(X) == ZERO+Inf) and that the signs of the imaginary parts match. ZERO is +/- 0i. */ -#ifndef __SPU__ #define TEST_CST_INF(X,ZERO) do { \ if (CPROJF(X) != ZERO+INF || CKSGN_I(CPROJF(X),ZERO+INF)) \ link_error(__LINE__); \ @@ -45,14 +40,6 @@ extern void link_error(int); if (CPROJL(X) != ZERO+INF || CKSGN_I(CPROJL(X),ZERO+INF)) \ link_error(__LINE__); \ } while (0) -#else -#define TEST_CST_INF(X,ZERO) do { \ - if (CPROJ(X) != ZERO+INF || CKSGN_I(CPROJ(X),ZERO+INF)) \ - link_error(__LINE__); \ - if (CPROJL(X) != ZERO+INF || CKSGN_I(CPROJL(X),ZERO+INF)) \ - link_error(__LINE__); \ -} while (0) -#endif /* Test that (cproj(X) == X) for all finite (X). */ #define TEST_CST(X) do { \ @@ -62,7 +49,6 @@ extern void link_error(int); /* Test that cproj(X + I*INF) -> (ZERO + INF), where ZERO is +-0i. NEG is either blank or a minus sign when ZERO is negative. */ -#ifndef __SPU__ #define TEST_IMAG_INF(NEG,ZERO) do { \ if (CPROJF(f+I*NEG INF) != ZERO+INF \ || CKSGN_I (CPROJF(f+I*NEG INF), ZERO+INF)) \ @@ -74,19 +60,8 @@ extern void link_error(int); || CKSGN_I (CPROJL(ld+I*NEG INF), ZERO+INF)) \ link_error(__LINE__); \ } while (0) -#else -#define TEST_IMAG_INF(NEG,ZERO) do { \ - if (CPROJ(d+I*NEG INF) != ZERO+INF \ - || CKSGN_I (CPROJ(d+I*NEG INF), ZERO+INF)) \ - link_error(__LINE__); \ - if (CPROJL(ld+I*NEG INF) != ZERO+INF \ - || CKSGN_I (CPROJL(ld+I*NEG INF), ZERO+INF)) \ - link_error(__LINE__); \ -} while (0) -#endif /* Like TEST_IMAG_INF, but check that side effects are honored. */ -#ifndef __SPU__ #define TEST_IMAG_INF_SIDE_EFFECT(NEG,ZERO) do { \ int side = 4; \ if (CPROJF(++side+I*NEG INF) != ZERO+INF \ @@ -101,23 +76,9 @@ extern void link_error(int); if (side != 10) \ link_error(__LINE__); \ } while (0) -#else -#define TEST_IMAG_INF_SIDE_EFFECT(NEG,ZERO) do { \ - int side = 4; \ - if (CPROJ(++side+I*NEG INF) != ZERO+INF \ - || CKSGN_I (CPROJ(++side+I*NEG INF), ZERO+INF)) \ - link_error(__LINE__); \ - if (CPROJL(++side+I*NEG INF) != ZERO+INF \ - || CKSGN_I (CPROJL(++side+I*NEG INF), ZERO+INF)) \ - link_error(__LINE__); \ - if (side != 8) \ - link_error(__LINE__); \ -} while (0) -#endif /* Test that cproj(INF, POSITIVE) -> INF+0i. NEG is either blank or a minus sign to test negative INF. */ -#ifndef __SPU__ #define TEST_REAL_INF(NEG) do { \ __real cf = NEG INF; \ __imag cf = (x ? 4 : 5); \ @@ -135,23 +96,8 @@ extern void link_error(int); || CKSGN_I (CPROJL(cld), INF)) \ link_error(__LINE__); \ } while (0) -#else -#define TEST_REAL_INF(NEG) do { \ - __real cd = NEG INF; \ - __imag cd = (x ? 4 : 5); \ - if (CPROJ(cd) != INF \ - || CKSGN_I (CPROJ(cd), INF)) \ - link_error(__LINE__); \ - __real cld = NEG INF; \ - __imag cld = (x ? 4 : 5); \ - if (CPROJL(cld) != INF \ - || CKSGN_I (CPROJL(cld), INF)) \ - link_error(__LINE__); \ -} while (0) -#endif /* Like TEST_REAL_INF, but check that side effects are honored. */ -#ifndef __SPU__ #define TEST_REAL_INF_SIDE_EFFECT(NEG) do { \ int side = -9; \ __real cf = NEG INF; \ @@ -172,23 +118,6 @@ extern void link_error(int); if (side != -3) \ link_error(__LINE__); \ } while (0) -#else -#define TEST_REAL_INF_SIDE_EFFECT(NEG) do { \ - int side = -9; \ - __real cd = NEG INF; \ - __imag cd = (x ? 4 : 5); \ - if (CPROJ((++side,cd)) != INF \ - || CKSGN_I (CPROJ((++side,cd)), INF)) \ - link_error(__LINE__); \ - __real cld = NEG INF; \ - __imag cld = (x ? 4 : 5); \ - if (CPROJL((++side,cld)) != INF \ - || CKSGN_I (CPROJL((++side,cld)), INF)) \ - link_error(__LINE__); \ - if (side != -5) \ - link_error(__LINE__); \ -} while (0) -#endif void foo (_Complex long double cld, _Complex double cd, _Complex float cf, long double ld, double d, float f, int x) diff --git a/gcc/testsuite/gcc.dg/torture/builtin-frexp-1.c b/gcc/testsuite/gcc.dg/torture/builtin-frexp-1.c index 2f1708b..2d1c184 100644 --- a/gcc/testsuite/gcc.dg/torture/builtin-frexp-1.c +++ b/gcc/testsuite/gcc.dg/torture/builtin-frexp-1.c @@ -54,7 +54,6 @@ extern void link_error(int); /* Test that FUNCRES(frexp(NEG FUNCARG(ARGARG),&i)) is false. Check the sign as well. Ensure side-effects are evaluated in i. */ -#ifndef __SPU__ #define TESTIT_FREXP2(NEG,FUNCARG,ARGARG,FUNCRES) do { \ int i=5; \ if (!__builtin_##FUNCRES##f(__builtin_frexpf(NEG __builtin_##FUNCARG##f(ARGARG),&i)) \ @@ -70,20 +69,6 @@ extern void link_error(int); || CKEXP(i,8)) \ link_error(__LINE__); \ } while (0) -#else -#define TESTIT_FREXP2(NEG,FUNCARG,ARGARG,FUNCRES) do { \ - int i=6; \ - /* SPU single-precision floating point format does not support Inf or Nan. */ \ - if (!__builtin_##FUNCRES(__builtin_frexp(NEG __builtin_##FUNCARG(ARGARG),&i)) \ - || CKSGN(__builtin_frexp(NEG __builtin_##FUNCARG(ARGARG),(i++,&i)), NEG __builtin_##FUNCARG(ARGARG)) \ - || CKEXP(i,7)) \ - link_error(__LINE__); \ - if (!__builtin_##FUNCRES##l(__builtin_frexpl(NEG __builtin_##FUNCARG##l(ARGARG),&i)) \ - || CKSGN_L(__builtin_frexpl(NEG __builtin_##FUNCARG##l(ARGARG),(i++,&i)), NEG __builtin_##FUNCARG##l(ARGARG)) \ - || CKEXP(i,8)) \ - link_error(__LINE__); \ - } while (0) -#endif void __attribute__ ((__noinline__)) foo(void) diff --git a/gcc/testsuite/gcc.dg/torture/builtin-ldexp-1.c b/gcc/testsuite/gcc.dg/torture/builtin-ldexp-1.c index 05fa2b9..eb32546 100644 --- a/gcc/testsuite/gcc.dg/torture/builtin-ldexp-1.c +++ b/gcc/testsuite/gcc.dg/torture/builtin-ldexp-1.c @@ -47,7 +47,6 @@ extern void link_error(int); /* Test that FUNCRES(FUNC(NEG FUNCARG(ARGARG),ARG2)) is false. Check the sign as well. */ -#ifndef __SPU__ #define TESTIT3(FUNC,NEG,FUNCARG,ARGARG,ARG2,FUNCRES) do { \ if (!__builtin_##FUNCRES##f(__builtin_##FUNC##f(NEG __builtin_##FUNCARG##f(ARGARG),ARG2)) \ || CKSGN_F(__builtin_##FUNC##f(NEG __builtin_##FUNCARG##f(ARGARG),ARG2), NEG __builtin_##FUNCARG##f(ARGARG))) \ @@ -59,17 +58,6 @@ extern void link_error(int); || CKSGN_L(__builtin_##FUNC##l(NEG __builtin_##FUNCARG##l(ARGARG),ARG2), NEG __builtin_##FUNCARG##l(ARGARG))) \ link_error(__LINE__); \ } while (0) -#else -#define TESTIT3(FUNC,NEG,FUNCARG,ARGARG,ARG2,FUNCRES) do { \ - /* SPU single-precision floating point format does not support Inf or Nan. */ \ - if (!__builtin_##FUNCRES(__builtin_##FUNC(NEG __builtin_##FUNCARG(ARGARG),ARG2)) \ - || CKSGN(__builtin_##FUNC(NEG __builtin_##FUNCARG(ARGARG),ARG2), NEG __builtin_##FUNCARG(ARGARG))) \ - link_error(__LINE__); \ - if (!__builtin_##FUNCRES##l(__builtin_##FUNC##l(NEG __builtin_##FUNCARG##l(ARGARG),ARG2)) \ - || CKSGN_L(__builtin_##FUNC##l(NEG __builtin_##FUNCARG##l(ARGARG),ARG2), NEG __builtin_##FUNCARG##l(ARGARG))) \ - link_error(__LINE__); \ - } while (0) -#endif /* Using foo==MIN/MAX float values, test that FUNC(foo,EXP) == foo*exp2(EXP), and also that FUNC(foo,-EXP) == foo*exp2(-EXP). */ diff --git a/gcc/testsuite/gcc.dg/torture/builtin-logb-1.c b/gcc/testsuite/gcc.dg/torture/builtin-logb-1.c index 087d87f..edf2f50 100644 --- a/gcc/testsuite/gcc.dg/torture/builtin-logb-1.c +++ b/gcc/testsuite/gcc.dg/torture/builtin-logb-1.c @@ -48,7 +48,6 @@ extern void link_error(int); /* Test if FUNCRES(FUNC(NEG FUNCARG(ARGARG))) is false. Check the sign as well. */ -#ifndef __SPU__ #define TESTIT3(FUNC,NEG,FUNCARG,ARGARG,FUNCRES,NEG2) do { \ if (!__builtin_##FUNCRES##f(__builtin_##FUNC(NEG __builtin_##FUNCARG##f(ARGARG))) \ || CKSGN_F(__builtin_##FUNC##f(NEG __builtin_##FUNCARG##f(ARGARG)), NEG2 __builtin_##FUNCARG##f(ARGARG))) \ @@ -60,17 +59,6 @@ extern void link_error(int); || CKSGN_L(__builtin_##FUNC##l(NEG __builtin_##FUNCARG##l(ARGARG)), NEG2 __builtin_##FUNCARG##l(ARGARG))) \ link_error(__LINE__); \ } while (0) -#else -#define TESTIT3(FUNC,NEG,FUNCARG,ARGARG,FUNCRES,NEG2) do { \ - /* SPU single-precision floating point format does not support Inf or Nan. */ \ - if (!__builtin_##FUNCRES(__builtin_##FUNC(NEG __builtin_##FUNCARG(ARGARG))) \ - || CKSGN(__builtin_##FUNC(NEG __builtin_##FUNCARG(ARGARG)), NEG2 __builtin_##FUNCARG(ARGARG))) \ - link_error(__LINE__); \ - if (!__builtin_##FUNCRES##l(__builtin_##FUNC##l(NEG __builtin_##FUNCARG##l(ARGARG))) \ - || CKSGN_L(__builtin_##FUNC##l(NEG __builtin_##FUNCARG##l(ARGARG)), NEG2 __builtin_##FUNCARG##l(ARGARG))) \ - link_error(__LINE__); \ - } while (0) -#endif void __attribute__ ((__noinline__)) foo(void) diff --git a/gcc/testsuite/gcc.dg/torture/builtin-math-2.c b/gcc/testsuite/gcc.dg/torture/builtin-math-2.c index 73db916..6f3a4be 100644 --- a/gcc/testsuite/gcc.dg/torture/builtin-math-2.c +++ b/gcc/testsuite/gcc.dg/torture/builtin-math-2.c @@ -60,21 +60,15 @@ extern void fool (long double); void bar() { /* An argument of NaN is not evaluated at compile-time. */ -#ifndef __SPU__ foof (__builtin_exp2f (__builtin_nanf(""))); -#endif foo (__builtin_exp2 (__builtin_nan(""))); fool (__builtin_exp2l (__builtin_nanl(""))); /* An argument of Inf/-Inf is not evaluated at compile-time. */ -#ifndef __SPU__ foof (__builtin_exp2f (__builtin_inff())); -#endif foo (__builtin_exp2 (__builtin_inf())); fool (__builtin_exp2l (__builtin_infl())); -#ifndef __SPU__ foof (__builtin_exp2f (-__builtin_inff())); -#endif foo (__builtin_exp2 (-__builtin_inf())); fool (__builtin_exp2l (-__builtin_infl())); @@ -137,36 +131,24 @@ void bar() TESTIT (tgamma, -3.0); /* An argument of NaN is not evaluated at compile-time. */ -#ifndef __SPU__ foof (__builtin_powf (__builtin_nanf(""), 2.5F)); -#endif foo (__builtin_pow (__builtin_nan(""), 2.5)); fool (__builtin_powl (__builtin_nanl(""), 2.5L)); -#ifndef __SPU__ foof (__builtin_powf (2.5F, __builtin_nanf(""))); -#endif foo (__builtin_pow (2.5, __builtin_nan(""))); fool (__builtin_powl (2.5L, __builtin_nanl(""))); /* An argument of Inf/-Inf is not evaluated at compile-time. */ -#ifndef __SPU__ foof (__builtin_powf (__builtin_inff(), 2.5F)); -#endif foo (__builtin_pow (__builtin_inf(), 2.5)); fool (__builtin_powl (__builtin_infl(), 2.5L)); -#ifndef __SPU__ foof (__builtin_powf (-__builtin_inff(), 2.5F)); -#endif foo (__builtin_pow (-__builtin_inf(), 2.5)); fool (__builtin_powl (-__builtin_infl(), 2.5L)); -#ifndef __SPU__ foof (__builtin_powf (2.5F, __builtin_inff())); -#endif foo (__builtin_pow (2.5, __builtin_inf())); fool (__builtin_powl (2.5L, __builtin_infl())); -#ifndef __SPU__ foof (__builtin_powf (2.5F, -__builtin_inff())); -#endif foo (__builtin_pow (2.5, -__builtin_inf())); fool (__builtin_powl (2.5L, -__builtin_infl())); @@ -242,25 +224,17 @@ void bar() TESTIT (ilogb, 0.0); TESTIT (ilogb, -0.0); -#ifndef __SPU__ foof (__builtin_ilogbf (__builtin_inff())); -#endif foo (__builtin_ilogb (__builtin_inf())); fool (__builtin_ilogbl (__builtin_infl())); -#ifndef __SPU__ foof (__builtin_ilogbf (-__builtin_inff())); -#endif foo (__builtin_ilogb (-__builtin_inf())); fool (__builtin_ilogbl (-__builtin_infl())); -#ifndef __SPU__ foof (__builtin_ilogbf (__builtin_nanf(""))); -#endif foo (__builtin_ilogb (__builtin_nan(""))); fool (__builtin_ilogbl (__builtin_nanl(""))); -#ifndef __SPU__ foof (__builtin_ilogbf (-__builtin_nanf(""))); -#endif foo (__builtin_ilogb (-__builtin_nan(""))); fool (__builtin_ilogbl (-__builtin_nanl(""))); @@ -306,8 +280,7 @@ void bar() } /* { dg-final { scan-tree-dump-times "exp2 " 9 "original" } } */ -/* { dg-final { scan-tree-dump-times "exp2f" 9 "original" { target { ! { spu*-*-* } } } } } */ -/* { dg-final { scan-tree-dump-times "exp2f" 6 "original" { target { spu*-*-* } } } } */ +/* { dg-final { scan-tree-dump-times "exp2f" 9 "original" } } */ /* { dg-final { scan-tree-dump-times "exp2l" 9 "original" } } */ /* { dg-final { scan-tree-dump-times "asin " 2 "original" } } */ /* { dg-final { scan-tree-dump-times "asinf" 2 "original" } } */ @@ -337,8 +310,7 @@ void bar() /* { dg-final { scan-tree-dump-times "tgammaf" 5 "original" } } */ /* { dg-final { scan-tree-dump-times "tgammal" 5 "original" } } */ /* { dg-final { scan-tree-dump-times "pow " 13 "original" } } */ -/* { dg-final { scan-tree-dump-times "powf" 13 "original" { target { ! { spu*-*-* } } } } } */ -/* { dg-final { scan-tree-dump-times "powf" 7 "original" { target { spu*-*-* } } } } */ +/* { dg-final { scan-tree-dump-times "powf" 13 "original" } } */ /* { dg-final { scan-tree-dump-times "powl" 13 "original" } } */ /* { dg-final { scan-tree-dump-times "sqrt " 1 "original" } } */ /* { dg-final { scan-tree-dump-times "sqrtf" 1 "original" } } */ @@ -356,8 +328,7 @@ void bar() /* { dg-final { scan-tree-dump-times "_logbf" 2 "original" } } */ /* { dg-final { scan-tree-dump-times "_logbl" 2 "original" } } */ /* { dg-final { scan-tree-dump-times "ilogb " 6 "original" } } */ -/* { dg-final { scan-tree-dump-times "ilogbf" 6 "original" { target { ! { spu*-*-* } } } } } */ -/* { dg-final { scan-tree-dump-times "ilogbf" 2 "original" { target { spu*-*-* } } } } */ +/* { dg-final { scan-tree-dump-times "ilogbf" 6 "original" } } */ /* { dg-final { scan-tree-dump-times "ilogbl" 6 "original" } } */ /* { dg-final { scan-tree-dump-times "y0 " 3 "original" } } */ /* { dg-final { scan-tree-dump-times "y0f" 3 "original" } } */ diff --git a/gcc/testsuite/gcc.dg/torture/builtin-math-5.c b/gcc/testsuite/gcc.dg/torture/builtin-math-5.c index 9ea906c..e1d3d06 100644 --- a/gcc/testsuite/gcc.dg/torture/builtin-math-5.c +++ b/gcc/testsuite/gcc.dg/torture/builtin-math-5.c @@ -28,21 +28,15 @@ extern void fool (_Complex long double); void bar() { /* An argument of NaN is not evaluated at compile-time. */ -#ifndef __SPU__ foof (__builtin_csqrtf (__builtin_nanf(""))); -#endif foo (__builtin_csqrt (__builtin_nan(""))); fool (__builtin_csqrtl (__builtin_nanl(""))); /* An argument of Inf/-Inf is not evaluated at compile-time. */ -#ifndef __SPU__ foof (__builtin_csqrtf (__builtin_inff())); -#endif foo (__builtin_csqrt (__builtin_inf())); fool (__builtin_csqrtl (__builtin_infl())); -#ifndef __SPU__ foof (__builtin_csqrtf (-__builtin_inff())); -#endif foo (__builtin_csqrt (-__builtin_inf())); fool (__builtin_csqrtl (-__builtin_infl())); @@ -51,36 +45,24 @@ void bar() TESTIT (cexp, -1e20); /* An argument of NaN is not evaluated at compile-time. */ -#ifndef __SPU__ foof (__builtin_cpowf (__builtin_nanf(""), 2.5F)); -#endif foo (__builtin_cpow (__builtin_nan(""), 2.5)); fool (__builtin_cpowl (__builtin_nanl(""), 2.5L)); -#ifndef __SPU__ foof (__builtin_cpowf (2.5F, __builtin_nanf(""))); -#endif foo (__builtin_cpow (2.5, __builtin_nan(""))); fool (__builtin_cpowl (2.5L, __builtin_nanl(""))); /* An argument of Inf/-Inf is not evaluated at compile-time. */ -#ifndef __SPU__ foof (__builtin_cpowf (__builtin_inff(), 2.5F)); -#endif foo (__builtin_cpow (__builtin_inf(), 2.5)); fool (__builtin_cpowl (__builtin_infl(), 2.5L)); -#ifndef __SPU__ foof (__builtin_cpowf (-__builtin_inff(), 2.5F)); -#endif foo (__builtin_cpow (-__builtin_inf(), 2.5)); fool (__builtin_cpowl (-__builtin_infl(), 2.5L)); -#ifndef __SPU__ foof (__builtin_cpowf (2.5F, __builtin_inff())); -#endif foo (__builtin_cpow (2.5, __builtin_inf())); fool (__builtin_cpowl (2.5L, __builtin_infl())); -#ifndef __SPU__ foof (__builtin_cpowf (2.5F, -__builtin_inff())); -#endif foo (__builtin_cpow (2.5, -__builtin_inf())); fool (__builtin_cpowl (2.5L, -__builtin_infl())); @@ -110,14 +92,12 @@ void bar() } -/* { dg-final { scan-tree-dump-times "csqrtf" 3 "original" { target { ! { spu*-*-* } } } } } */ -/* { dg-final { scan-tree-dump-times "csqrtf" 0 "original" { target { spu*-*-* } } } } */ +/* { dg-final { scan-tree-dump-times "csqrtf" 3 "original" } } */ /* { dg-final { scan-tree-dump-times "csqrt " 3 "original" } } */ /* { dg-final { scan-tree-dump-times "csqrtl" 3 "original" } } */ /* { dg-final { scan-tree-dump-times "cexpf" 2 "original" } } */ /* { dg-final { scan-tree-dump-times "cexp " 2 "original" } } */ /* { dg-final { scan-tree-dump-times "cexpl" 2 "original" } } */ -/* { dg-final { scan-tree-dump-times "cpowf" 18 "original" { target { ! { spu*-*-* } } } } } */ -/* { dg-final { scan-tree-dump-times "cpowf" 12 "original" { target { spu*-*-* } } } } */ +/* { dg-final { scan-tree-dump-times "cpowf" 18 "original" } } */ /* { dg-final { scan-tree-dump-times "cpow " 18 "original" } } */ /* { dg-final { scan-tree-dump-times "cpowl" 18 "original" } } */ diff --git a/gcc/testsuite/gcc.dg/torture/builtin-modf-1.c b/gcc/testsuite/gcc.dg/torture/builtin-modf-1.c index 78d3032..246d5b1 100644 --- a/gcc/testsuite/gcc.dg/torture/builtin-modf-1.c +++ b/gcc/testsuite/gcc.dg/torture/builtin-modf-1.c @@ -63,7 +63,6 @@ extern void link_error(int); /* Test that modf(NEG FUNCARG(ARGARG, &iptr)) == FRACRES && FUNCRES(iptr) is true. Check the sign of both as well. This is for checking an argument of Inf. */ -#ifndef __SPU__ #define TESTIT_MODF2(NEG,FUNCARG,ARGARG,FUNCRES,FRACRES) do { \ float iptrf = 0.5; double iptr = 0.5; long double iptrl = 0.5; \ if (__builtin_modff(NEG __builtin_##FUNCARG##f(ARGARG),&iptrf) != FRACRES##f \ @@ -82,27 +81,10 @@ extern void link_error(int); || CKSGN_IPTR_L(iptrl,FRACRES##l)) \ link_error(__LINE__); \ } while (0) -#else -#define TESTIT_MODF2(NEG,FUNCARG,ARGARG,FUNCRES,FRACRES) do { \ - /* SPU single-precision floating point format does not support Inf or Nan. */ \ - double iptr = 0.5; long double iptrl = 0.5; \ - if (__builtin_modf(NEG __builtin_##FUNCARG(ARGARG),&iptr) != FRACRES \ - || CKSGN(__builtin_modf(NEG __builtin_##FUNCARG(ARGARG),&iptr), FRACRES) \ - || CKIPTR(!__builtin_##FUNCRES(iptr),0) \ - || CKSGN_IPTR(iptr,FRACRES)) \ - link_error(__LINE__); \ - if (__builtin_modfl(NEG __builtin_##FUNCARG##l(ARGARG),&iptrl) != FRACRES##l \ - || CKSGN_L(__builtin_modfl(NEG __builtin_##FUNCARG##l(ARGARG),&iptrl), FRACRES##l) \ - || CKIPTR(!__builtin_##FUNCRES##l(iptrl),0) \ - || CKSGN_IPTR_L(iptrl,FRACRES##l)) \ - link_error(__LINE__); \ - } while (0) -#endif /* Test that FUNCRES(modf(NEG FUNCARG(ARGARG, &iptr))) is true && FUNCRES(iptr) is true. Check the sign of both as well. This is for checking an argument of NaN. */ -#ifndef __SPU__ #define TESTIT_MODF3(NEG,FUNCARG,ARGARG,FUNCRES) do { \ float iptrf = 0.5; double iptr = 0.5; long double iptrl = 0.5; \ if (CKRES(!__builtin_##FUNCRES##f(__builtin_modff(NEG __builtin_##FUNCARG##f(ARGARG),&iptrf))) \ @@ -121,22 +103,6 @@ extern void link_error(int); || CKSGN_IPTR_L(iptrl,NEG 1)) \ link_error(__LINE__); \ } while (0) -#else -#define TESTIT_MODF3(NEG,FUNCARG,ARGARG,FUNCRES) do { \ - /* SPU single-precision floating point format does not support Inf or Nan. */ \ - double iptr = 0.5; long double iptrl = 0.5; \ - if (CKRES(!__builtin_##FUNCRES(__builtin_modf(NEG __builtin_##FUNCARG(ARGARG),&iptr))) \ - || CKSGN(__builtin_modf(NEG __builtin_##FUNCARG(ARGARG),&iptr), NEG 1) \ - || CKIPTR(!__builtin_##FUNCRES(iptr),0) \ - || CKSGN_IPTR(iptr,NEG 1)) \ - link_error(__LINE__); \ - if (CKRES(!__builtin_##FUNCRES##l(__builtin_modfl(NEG __builtin_##FUNCARG##l(ARGARG),&iptrl))) \ - || CKSGN_L(__builtin_modfl(NEG __builtin_##FUNCARG##l(ARGARG),&iptrl), NEG 1) \ - || CKIPTR(!__builtin_##FUNCRES##l(iptrl),0) \ - || CKSGN_IPTR_L(iptrl,NEG 1)) \ - link_error(__LINE__); \ - } while (0) -#endif void __attribute__ ((__noinline__)) foo(void) diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert.h b/gcc/testsuite/gcc.dg/torture/fp-int-convert.h index f0b3f39..ecc3977b 100644 --- a/gcc/testsuite/gcc.dg/torture/fp-int-convert.h +++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert.h @@ -7,7 +7,7 @@ extern void exit (int); /* Not all platforms support TImode integers; logic as in gcc.dg/titype-1.c. */ -#if (defined(__LP64__) && !defined(__hppa__)) || defined(_WIN64) || defined(__SPU__) +#if (defined(__LP64__) && !defined(__hppa__)) || defined(_WIN64) typedef int TItype __attribute__ ((mode (TI))); typedef unsigned int UTItype __attribute__ ((mode (TI))); #else diff --git a/gcc/testsuite/gcc.dg/torture/pr25947-1.c b/gcc/testsuite/gcc.dg/torture/pr25947-1.c index 89d1ed0..3acad8d 100644 --- a/gcc/testsuite/gcc.dg/torture/pr25947-1.c +++ b/gcc/testsuite/gcc.dg/torture/pr25947-1.c @@ -1,6 +1,5 @@ /* PR target/25947: define_split in cris.md caused unrecognized insn. */ /* { dg-options "-fpic" { target fpic } } */ -/* { dg-skip-if "requires unsupported run-time relocation" { spu-*-* } { "-O0" } { "" } } */ extern char *rl_line_buffer; extern int rl_point; diff --git a/gcc/testsuite/gcc.dg/torture/type-generic-1.c b/gcc/testsuite/gcc.dg/torture/type-generic-1.c index 3df6f9b..b2aacd9 100644 --- a/gcc/testsuite/gcc.dg/torture/type-generic-1.c +++ b/gcc/testsuite/gcc.dg/torture/type-generic-1.c @@ -3,7 +3,6 @@ /* { dg-do run } */ /* { dg-require-effective-target inf } */ -/* { dg-skip-if "No Inf/NaN support" { spu-*-* } } */ /* { dg-skip-if "No subnormal support" { csky-*-* } { "-mhard-float" } } */ /* { dg-options "-DUNSAFE" { target tic6x*-*-* visium-*-* nvptx-*-* } } */ /* { dg-add-options ieee } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040204-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040204-1.c index 2f3dcb5..3e07a35 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/20040204-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/20040204-1.c @@ -33,4 +33,4 @@ void test55 (int x, int y) that the && should be emitted (based on BRANCH_COST). Fix this by teaching dom to look through && and register all components as true. */ -/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" { xfail { ! "alpha*-*-* arm*-*-* aarch64*-*-* powerpc*-*-* cris-*-* crisv32-*-* hppa*-*-* i?86-*-* mmix-*-* mips*-*-* m68k*-*-* moxie-*-* nds32*-*-* s390*-*-* sh*-*-* sparc*-*-* spu-*-* visium-*-* x86_64-*-* riscv*-*-* or1k*-*-* msp430-*-* pru*-*-*" } } } } */ +/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" { xfail { ! "alpha*-*-* arm*-*-* aarch64*-*-* powerpc*-*-* cris-*-* crisv32-*-* hppa*-*-* i?86-*-* mmix-*-* mips*-*-* m68k*-*-* moxie-*-* nds32*-*-* s390*-*-* sh*-*-* sparc*-*-* visium-*-* x86_64-*-* riscv*-*-* or1k*-*-* msp430-*-* pru*-*-*" } } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ivopts-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ivopts-1.c index 44f1b62..5ee87b0 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ivopts-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ivopts-1.c @@ -1,7 +1,7 @@ /* { dg-do compile } */ /* Not all platforms support TImode integers. */ -#if (defined(__LP64__) && !defined(__hppa__)) || defined(__SPU__) +#if defined(__LP64__) && !defined(__hppa__) typedef int TItype __attribute__ ((mode (TI))); #else typedef long TItype; diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c index eda7118..6b6255b 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c @@ -5,7 +5,7 @@ When the condition is true, we distribute "(int) (a + b)" as "(int) a + (int) b", otherwise we keep the original. */ -/* { dg-do compile { target { { ! mips64 } && { ! spu-*-* } } } } */ +/* { dg-do compile { target { ! mips64 } } } */ /* { dg-options "-O -fno-tree-forwprop -fno-tree-ccp -fwrapv -fdump-tree-fre1-details" } */ /* From PR14844. */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vector-6.c b/gcc/testsuite/gcc.dg/tree-ssa/vector-6.c index e0bb196..151962e 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/vector-6.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/vector-6.c @@ -32,5 +32,5 @@ v4si test4 (v4si v, int i) return v; } -/* { dg-final { scan-tree-dump-times "Now a gimple register: v" 2 "ssa" { target { { i?86-*-* x86_64-*-* aarch64*-*-* spu*-*-* } || { powerpc_altivec_ok } } } } } */ -/* { dg-final { scan-tree-dump-times "Now a gimple register: v" 2 "ccp1" { target { { i?86-*-* x86_64-*-* aarch64*-*-* spu*-*-* } || { powerpc_altivec_ok } } } } } */ +/* { dg-final { scan-tree-dump-times "Now a gimple register: v" 2 "ssa" { target { { i?86-*-* x86_64-*-* aarch64*-*-* } || { powerpc_altivec_ok } } } } } */ +/* { dg-final { scan-tree-dump-times "Now a gimple register: v" 2 "ccp1" { target { { i?86-*-* x86_64-*-* aarch64*-*-* } || { powerpc_altivec_ok } } } } } */ diff --git a/gcc/testsuite/gcc.dg/uninit-C-O0.c b/gcc/testsuite/gcc.dg/uninit-C-O0.c index 02339d4..305dd36 100644 --- a/gcc/testsuite/gcc.dg/uninit-C-O0.c +++ b/gcc/testsuite/gcc.dg/uninit-C-O0.c @@ -3,7 +3,7 @@ /* { dg-options "-Wuninitialized" } */ /* Not all platforms support TImode integers. */ -#if (defined(__LP64__) && !defined(__hppa__)) || defined(__SPU__) +#if defined(__LP64__) && !defined(__hppa__) typedef int TItype __attribute__ ((mode (TI))); #else typedef long TItype; diff --git a/gcc/testsuite/gcc.dg/uninit-C.c b/gcc/testsuite/gcc.dg/uninit-C.c index a22f0d7..741106c 100644 --- a/gcc/testsuite/gcc.dg/uninit-C.c +++ b/gcc/testsuite/gcc.dg/uninit-C.c @@ -3,7 +3,7 @@ /* { dg-options "-O -Wuninitialized" } */ /* Not all platforms support TImode integers. */ -#if (defined(__LP64__) && !defined(__hppa__)) || defined(__SPU__) +#if defined(__LP64__) && !defined(__hppa__) typedef int TItype __attribute__ ((mode (TI))); #else typedef long TItype; diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-fast-math-vect-pr29925.c b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-fast-math-vect-pr29925.c deleted file mode 100644 index d8fe35c..0000000 --- a/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-fast-math-vect-pr29925.c +++ /dev/null @@ -1,39 +0,0 @@ -/* { dg-require-effective-target vect_float } */ - -#include -#include "../../tree-vect.h" - -__attribute__ ((noinline)) void -interp_pitch(float *exc, float *interp, int pitch, int len) -{ - int i,k; - int maxj; - - maxj=3; - for (i=0;i -#include "../../tree-vect.h" - -#define N 32 - -struct t{ - int k[N]; - int l; -}; - -struct s{ - char a; /* aligned */ - char b[N-1]; /* unaligned (offset 1B) */ - char c[N]; /* aligned (offset NB) */ - struct t d; /* aligned (offset 2NB) */ - struct t e; /* unaligned (offset 2N+4N+4 B) */ -}; - -int main1 () -{ - int i; - struct s tmp; - - /* unaligned */ - for (i = 0; i < N/2; i++) - { - tmp.b[i] = 5; - } - - /* check results: */ - for (i = 0; i -#include "../../tree-vect.h" - -#define N 32 - -struct t{ - int k[N]; - int l; -}; - -struct s{ - char a; /* aligned */ - char b[N-1]; /* unaligned (offset 1B) */ - char c[N]; /* aligned (offset NB) */ - struct t d; /* aligned (offset 2NB) */ - struct t e; /* unaligned (offset 2N+4N+4 B) */ -}; - -int main1 () -{ - int i; - struct s tmp; - - /* aligned */ - for (i = 0; i < N/2; i++) - { - tmp.c[i] = 6; - } - - /* check results: */ - for (i = 0; i -#include "../../tree-vect.h" - -#define N 32 - -struct t{ - int k[N]; - int l; -}; - -struct s{ - char a; /* aligned */ - char b[N-1]; /* unaligned (offset 1B) */ - char c[N]; /* aligned (offset NB) */ - struct t d; /* aligned (offset 2NB) */ - struct t e; /* unaligned (offset 2N+4N+4 B) */ -}; - -int main1 () -{ - int i; - struct s tmp; - - /* aligned */ - for (i = 0; i < N/2; i++) - { - tmp.d.k[i] = 7; - } - - /* check results: */ - for (i = 0; i -#include "../../tree-vect.h" - -#define N 32 - -struct t{ - int k[N]; - int l; -}; - -struct s{ - char a; /* aligned */ - char b[N-1]; /* unaligned (offset 1B) */ - char c[N]; /* aligned (offset NB) */ - struct t d; /* aligned (offset 2NB) */ - struct t e; /* unaligned (offset 2N+4N+4 B) */ -}; - -int main1 () -{ - int i; - struct s tmp; - - /* unaligned */ - for (i = 0; i < N/2; i++) - { - tmp.e.k[i] = 8; - } - - /* check results: */ - for (i = 0; i -#include "../../tree-vect.h" - -#define N 16 -struct test { - char ca[N]; -}; - -extern struct test s; - -int main1 () -{ - int i; - - for (i = 0; i < N; i++) - { - s.ca[i] = 5; - } - - /* check results: */ - for (i = 0; i < N; i++) - { - if (s.ca[i] != 5) - abort (); - } - - return 0; -} - -int main (void) -{ - return main1 (); -} - -/* Peeling to align the store is used. Overhead of peeling is too high. */ -/* { dg-final { scan-tree-dump-times "vectorization not profitable" 1 "vect" { target vector_alignment_reachable } } } */ - -/* Versioning to align the store is used. Overhead of versioning is not too high. */ -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target {! vector_alignment_reachable} } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-68a.c b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-68a.c deleted file mode 100644 index ce27e4f..0000000 --- a/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-68a.c +++ /dev/null @@ -1,48 +0,0 @@ -/* { dg-require-effective-target vect_int } */ - -#include -#include "../../tree-vect.h" - -#define N 32 - -struct s{ - int m; - int n[N][N][N]; -}; - -struct test1{ - struct s a; /* array a.n is unaligned */ - int b; - int c; - struct s e; /* array e.n is aligned */ -}; - -int main1 () -{ - int i,j; - struct test1 tmp1; - - /* 1. unaligned */ - for (i = 0; i < N; i++) - { - tmp1.a.n[1][2][i] = 5; - } - - /* check results: */ - for (i = 0; i -#include "../../tree-vect.h" - -#define N 32 - -struct s{ - int m; - int n[N][N][N]; -}; - -struct test1{ - struct s a; /* array a.n is unaligned */ - int b; - int c; - struct s e; /* array e.n is aligned */ -}; - -int main1 () -{ - int i,j; - struct test1 tmp1; - - /* 2. aligned */ - for (i = 3; i < N-1; i++) - { - tmp1.a.n[1][2][i] = 6; - } - - /* check results: */ - for (i = 3; i < N-1; i++) - { - if (tmp1.a.n[1][2][i] != 6) - abort (); - } - - return 0; -} - -int main (void) -{ - check_vect (); - - return main1 (); -} - -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-68c.c b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-68c.c deleted file mode 100644 index 8221f9e..0000000 --- a/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-68c.c +++ /dev/null @@ -1,48 +0,0 @@ -/* { dg-require-effective-target vect_int } */ - -#include -#include "../../tree-vect.h" - -#define N 32 - -struct s{ - int m; - int n[N][N][N]; -}; - -struct test1{ - struct s a; /* array a.n is unaligned */ - int b; - int c; - struct s e; /* array e.n is aligned */ -}; - -int main1 () -{ - int i,j; - struct test1 tmp1; - - /* 3. aligned */ - for (i = 0; i < N; i++) - { - tmp1.e.n[1][2][i] = 7; - } - - /* check results: */ - for (i = 0; i < N; i++) - { - if (tmp1.e.n[1][2][i] != 7) - abort (); - } - - return 0; -} - -int main (void) -{ - check_vect (); - - return main1 (); -} - -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-68d.c b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-68d.c deleted file mode 100644 index 0468455..0000000 --- a/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-68d.c +++ /dev/null @@ -1,49 +0,0 @@ -/* { dg-require-effective-target vect_int } */ - -#include -#include "../../tree-vect.h" - -#define N 20 - -struct s{ - int m; - int n[N][N][N]; -}; - -struct test1{ - struct s a; /* array a.n is unaligned */ - int b; - int c; - struct s e; /* array e.n is aligned */ -}; - -int main1 () -{ - int i,j; - struct test1 tmp1; - - /* 4. unaligned */ - for (i = 3; i < N-3; i++) - { - tmp1.e.n[1][2][i] = 8; - } - - /* check results: */ - for (i = 3; i -#include "../../tree-vect.h" - -#define N 16 -#define OFF 4 - -/* Check handling of accesses for which the "initial condition" - - the expression that represents the first location accessed - is - more involved than just an ssa_name. */ - -int ib[N+OFF] __attribute__ ((__aligned__(16))) = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10}; - -int main1 (int *pib) -{ - int i; - int ia[N+OFF]; - int ic[N+OFF] = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10}; - - for (i = OFF; i < N; i++) - { - ia[i] = pib[i - OFF]; - } - - - /* check results: */ - for (i = OFF; i < N; i++) - { - if (ia[i] != pib[i - OFF]) - abort (); - } - - return 0; -} - -int main (void) -{ - check_vect (); - - main1 (&ib[OFF]); - return 0; -} - - -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-76b.c b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-76b.c deleted file mode 100644 index 1d6075e..0000000 --- a/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-76b.c +++ /dev/null @@ -1,46 +0,0 @@ -/* { dg-require-effective-target vect_int } */ - -#include -#include "../../tree-vect.h" - -#define N 16 -#define OFF 4 - -/* Check handling of accesses for which the "initial condition" - - the expression that represents the first location accessed - is - more involved than just an ssa_name. */ - -int ib[N+OFF] __attribute__ ((__aligned__(16))) = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10, 0, 1, 3, 5, 7, 11, 13, 17}; -int ic[N+OFF] = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10, 0, 1, 3, 5, 7, 11, 13, 17}; - -int main1 (int *pib) -{ - int i; - int ia[N+OFF]; - - for (i = OFF; i < N; i++) - { - pib[i - OFF] = ic[i]; - } - - - /* check results: */ - for (i = OFF; i < N; i++) - { - if (pib[i - OFF] != ic[i]) - abort (); - } - - return 0; -} - -int main (void) -{ - check_vect (); - - main1 (&ib[OFF]); - return 0; -} - -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ -/* { dg-final { scan-tree-dump-times "vectorization not profitable" 0 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-76c.c b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-76c.c deleted file mode 100644 index 672e967..0000000 --- a/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-76c.c +++ /dev/null @@ -1,46 +0,0 @@ -/* { dg-require-effective-target vect_int } */ - -#include -#include "../../tree-vect.h" - -#define N 32 -#define OFF 4 - -/* Check handling of accesses for which the "initial condition" - - the expression that represents the first location accessed - is - more involved than just an ssa_name. */ - -int ib[N+OFF] __attribute__ ((__aligned__(16))) = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10}; -int ic[N+OFF] = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10}; - -int main1 (int *pib) -{ - int i; - int ia[N+OFF]; - - for (i = OFF; i < N; i++) - { - ia[i] = ic[i - OFF]; - } - - - /* check results: */ - for (i = OFF; i < N; i++) - { - if (ia[i] != ic[i - OFF]) - abort (); - } - - return 0; -} - -int main (void) -{ - check_vect (); - - main1 (&ib[OFF]); - return 0; -} - - -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-iv-9.c b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-iv-9.c deleted file mode 100644 index 0f09405..0000000 --- a/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-iv-9.c +++ /dev/null @@ -1,37 +0,0 @@ -/* { dg-require-effective-target vect_int } */ - -#include -#include "../../tree-vect.h" - -#define N 26 -int a[N]; - -__attribute__ ((noinline)) int main1 (int X) -{ - int s = X; - int i; - - /* vectorization of reduction with induction. */ - for (i = 0; i < N; i++) - s += (i + a[i]); - - return s; -} - -int main (void) -{ - int s, i; - check_vect (); - - for (i = 0; i < N; i++) - a[i] = 2*i; - - s = main1 (3); - if (s != 978) - abort (); - - return 0; -} - -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { target vect_int_mult } } } */ -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target {! vect_int_mult } } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/spu/spu-costmodel-vect.exp b/gcc/testsuite/gcc.dg/vect/costmodel/spu/spu-costmodel-vect.exp deleted file mode 100644 index fb3da51..0000000 --- a/gcc/testsuite/gcc.dg/vect/costmodel/spu/spu-costmodel-vect.exp +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright (C) 1997-2019 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# . - -# GCC testsuite that uses the `dg.exp' driver. - -# Load support procs. -load_lib gcc-dg.exp - -# Exit immediately if this isn't a powerpc target. -if { ![istarget spu*-*-*] } then { - return -} - - -# Set up flags used for tests that don't specify options. -set DEFAULT_VECTCFLAGS "" - -# These flags are used for all targets. -lappend DEFAULT_VECTCFLAGS "-O2" "-ftree-vectorize" "-fvect-cost-model=dynamic" - -# If the target system supports vector instructions, the default action -# for a test is 'run', otherwise it's 'compile'. Save current default. -# Executing vector instructions on a system without hardware vector support -# is also disabled by a call to check_vect, but disabling execution here is -# more efficient. -global dg-do-what-default -set save-dg-do-what-default ${dg-do-what-default} - -set dg-do-what-default run - -# Initialize `dg'. -dg-init - -lappend DEFAULT_VECTCFLAGS "-fdump-tree-vect-details" - -# Main loop. -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/costmodel-pr*.\[cS\]]] \ - "" $DEFAULT_VECTCFLAGS -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/costmodel-vect-*.\[cS\]]] \ - "" $DEFAULT_VECTCFLAGS - -#### Tests with special options -global SAVED_DEFAULT_VECTCFLAGS -set SAVED_DEFAULT_VECTCFLAGS $DEFAULT_VECTCFLAGS - -# -ffast-math tests -set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS -lappend DEFAULT_VECTCFLAGS "-ffast-math" -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/costmodel-fast-math-vect*.\[cS\]]] \ - "" $DEFAULT_VECTCFLAGS - -# Clean up. -set dg-do-what-default ${save-dg-do-what-default} - -# All done. -dg-finish diff --git a/gcc/testsuite/gcc.dg/vect/no-math-errno-slp-32.c b/gcc/testsuite/gcc.dg/vect/no-math-errno-slp-32.c index 1e88c0d..18064cc3 100644 --- a/gcc/testsuite/gcc.dg/vect/no-math-errno-slp-32.c +++ b/gcc/testsuite/gcc.dg/vect/no-math-errno-slp-32.c @@ -13,4 +13,4 @@ void foo(void) } } -/* { dg-final { scan-tree-dump "pattern recognized" "vect" { xfail spu*-*-* } } } */ +/* { dg-final { scan-tree-dump "pattern recognized" "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-math-errno-vect-pow-1.c b/gcc/testsuite/gcc.dg/vect/no-math-errno-vect-pow-1.c index b943f5a..8e3989a 100644 --- a/gcc/testsuite/gcc.dg/vect/no-math-errno-vect-pow-1.c +++ b/gcc/testsuite/gcc.dg/vect/no-math-errno-vect-pow-1.c @@ -10,4 +10,4 @@ void foo(void) x[i] = __builtin_pow (x[i], 0.5); } -/* { dg-final { scan-tree-dump "pattern recognized" "vect" { xfail spu*-*-* } } } */ +/* { dg-final { scan-tree-dump "pattern recognized" "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-float-extend-1.c b/gcc/testsuite/gcc.dg/vect/vect-float-extend-1.c index 867fe20..76b4369 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-float-extend-1.c +++ b/gcc/testsuite/gcc.dg/vect/vect-float-extend-1.c @@ -38,4 +38,4 @@ main (void) return main1 (); } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail spu*-*-* } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-float-truncate-1.c b/gcc/testsuite/gcc.dg/vect/vect-float-truncate-1.c index 30d3a83..8b82c82 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-float-truncate-1.c +++ b/gcc/testsuite/gcc.dg/vect/vect-float-truncate-1.c @@ -37,4 +37,4 @@ main (void) return main1 (); } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail spu*-*-* } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect.exp b/gcc/testsuite/gcc.dg/vect/vect.exp index 9569ea5..a52a2aa 100644 --- a/gcc/testsuite/gcc.dg/vect/vect.exp +++ b/gcc/testsuite/gcc.dg/vect/vect.exp @@ -266,9 +266,6 @@ et-dg-runtest dg-runtest [lsort \ # Don't allow IPA cloning, because it throws our counts out of whack. set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS lappend DEFAULT_VECTCFLAGS "-O3" "-fno-ipa-cp-clone" -if [istarget "spu-*-*"] { - lappend DEFAULT_VECTCFLAGS "-funroll-loops" -} et-dg-runtest dg-runtest [lsort \ [glob -nocomplain $srcdir/$subdir/O3-*.\[cS\]]] \ diff --git a/gcc/testsuite/gcc.target/spu/Wmain.c b/gcc/testsuite/gcc.target/spu/Wmain.c deleted file mode 100644 index d80e182..0000000 --- a/gcc/testsuite/gcc.target/spu/Wmain.c +++ /dev/null @@ -1,7 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-Wmain -mstdmain" } */ - -int main (void *wrong)/* { dg-warning "first argument of 'main' should be 'int'" } */ - /* { dg-warning "'main' takes only zero or two arguments" "" { target *-*-* } .-1 } */ -{ -} diff --git a/gcc/testsuite/gcc.target/spu/abi.c b/gcc/testsuite/gcc.target/spu/abi.c deleted file mode 100644 index b435f1e..0000000 --- a/gcc/testsuite/gcc.target/spu/abi.c +++ /dev/null @@ -1,474 +0,0 @@ -/* { dg-do run } */ -/* { dg-options "-O2" } */ -/* Test that arguments are passed in the correct location according to the ABI. */ - -#include - -/* Hack to allow calling func_asm which takes 84 arguments that are scalars. - The function func_call takes 84 union quadword arguments, so we can check to - see if each scalar is passed in the correct location. This asm glues the - two functions together, so that the compiler is not aware of the - aliasing. */ -__asm__ ("func_asm = func_call"); - -typedef unsigned int uqword __attribute__((mode(TI))); -typedef int qword __attribute__((mode(TI))); - -union u -{ - uqword uq; - qword sq; - double d[2]; - float f[4]; - unsigned long long ull[2]; - long long sll[2]; - unsigned long ul[4]; - long sl[4]; - unsigned int ui[4]; - int si[4]; - unsigned short us[8]; - short ss[8]; - unsigned char uc[16]; - signed char sc[16]; -}; - - -extern void func_asm(signed char a1, - unsigned char a2, - short a3, - unsigned short a4, - int a5, - unsigned int a6, - long a7, - unsigned long a8, - long long a9, - unsigned long long a10, - float a11, - double a12, - int a13, - int a14, - int a15, - int a16, - int a17, - int a18, - int a19, - int a20, - int a21, - int a22, - int a23, - int a24, - int a25, - int a26, - int a27, - int a28, - int a29, - int a30, - int a31, - int a32, - int a33, - int a34, - int a35, - int a36, - int a37, - int a38, - int a39, - int a40, - int a41, - int a42, - int a43, - int a44, - int a45, - int a46, - int a47, - int a48, - int a49, - int a50, - int a51, - int a52, - int a53, - int a54, - int a55, - int a56, - int a57, - int a58, - int a59, - int a60, - int a61, - int a62, - int a63, - int a64, - int a65, - int a66, - int a67, - int a68, - int a69, - int a70, - int a71, - int a72, - signed char a73, - unsigned char a74, - short a75, - unsigned short a76, - int a77, - unsigned int a78, - long a79, - unsigned long a80, - long long a81, - unsigned long long a82, - float a83, - double a84); - -void func_call(union u a1, - union u a2, - union u a3, - union u a4, - union u a5, - union u a6, - union u a7, - union u a8, - union u a9, - union u a10, - union u a11, - union u a12, - union u a13, - union u a14, - union u a15, - union u a16, - union u a17, - union u a18, - union u a19, - union u a20, - union u a21, - union u a22, - union u a23, - union u a24, - union u a25, - union u a26, - union u a27, - union u a28, - union u a29, - union u a30, - union u a31, - union u a32, - union u a33, - union u a34, - union u a35, - union u a36, - union u a37, - union u a38, - union u a39, - union u a40, - union u a41, - union u a42, - union u a43, - union u a44, - union u a45, - union u a46, - union u a47, - union u a48, - union u a49, - union u a50, - union u a51, - union u a52, - union u a53, - union u a54, - union u a55, - union u a56, - union u a57, - union u a58, - union u a59, - union u a60, - union u a61, - union u a62, - union u a63, - union u a64, - union u a65, - union u a66, - union u a67, - union u a68, - union u a69, - union u a70, - union u a71, - union u a72, - union u a73, - union u a74, - union u a75, - union u a76, - union u a77, - union u a78, - union u a79, - union u a80, - union u a81, - union u a82, - union u a83, - union u a84) -{ - /* arguments passed in registers */ - if (a1.sc[3] != -1) /* signed char */ - abort (); - - if (a2.uc[3] != +2) /* unsigned char */ - abort (); - - if (a3.ss[1] != -3) /* short */ - abort (); - - if (a4.us[1] != +4) /* unsigned short */ - abort (); - - if (a5.si[0] != -5) /* int */ - abort (); - - if (a6.ui[0] != +6) /* unsigned int */ - abort (); - - if (a7.sl[0] != -7) /* long */ - abort (); - - if (a8.ul[0] != +8) /* unsigned long */ - abort (); - - if (a9.sll[0] != -9) /* long long */ - abort (); - - if (a10.ull[0] != +10) /* unsigned long long */ - abort (); - - if (a11.f[0] != -11.0f) /* float */ - abort (); - - if (a12.d[0] != +12.0) /* double */ - abort (); - - if (a13.si[0] != -13) /* int */ - abort (); - - if (a14.si[0] != +14) /* int */ - abort (); - - if (a15.si[0] != -15) /* int */ - abort (); - - if (a16.si[0] != +16) /* int */ - abort (); - - if (a17.si[0] != -17) /* int */ - abort (); - - if (a18.si[0] != +18) /* int */ - abort (); - - if (a19.si[0] != -19) /* int */ - abort (); - - if (a20.si[0] != +20) /* int */ - abort (); - - if (a21.si[0] != -21) /* int */ - abort (); - - if (a22.si[0] != +22) /* int */ - abort (); - - if (a23.si[0] != -23) /* int */ - abort (); - - if (a24.si[0] != +24) /* int */ - abort (); - - if (a25.si[0] != -25) /* int */ - abort (); - - if (a26.si[0] != +26) /* int */ - abort (); - - if (a27.si[0] != -27) /* int */ - abort (); - - if (a28.si[0] != +28) /* int */ - abort (); - - if (a29.si[0] != -29) /* int */ - abort (); - - if (a30.si[0] != +30) /* int */ - abort (); - - if (a31.si[0] != -31) /* int */ - abort (); - - if (a32.si[0] != +32) /* int */ - abort (); - - if (a33.si[0] != -33) /* int */ - abort (); - - if (a34.si[0] != +34) /* int */ - abort (); - - if (a35.si[0] != -35) /* int */ - abort (); - - if (a36.si[0] != +36) /* int */ - abort (); - - if (a37.si[0] != -37) /* int */ - abort (); - - if (a38.si[0] != +38) /* int */ - abort (); - - if (a39.si[0] != -39) /* int */ - abort (); - - if (a40.si[0] != +40) /* int */ - abort (); - - if (a41.si[0] != -41) /* int */ - abort (); - - if (a42.si[0] != +42) /* int */ - abort (); - - if (a43.si[0] != -43) /* int */ - abort (); - - if (a44.si[0] != +44) /* int */ - abort (); - - if (a45.si[0] != -45) /* int */ - abort (); - - if (a46.si[0] != +46) /* int */ - abort (); - - if (a47.si[0] != -47) /* int */ - abort (); - - if (a48.si[0] != +48) /* int */ - abort (); - - if (a49.si[0] != -49) /* int */ - abort (); - - if (a50.si[0] != +50) /* int */ - abort (); - - if (a51.si[0] != -51) /* int */ - abort (); - - if (a52.si[0] != +52) /* int */ - abort (); - - if (a53.si[0] != -53) /* int */ - abort (); - - if (a54.si[0] != +54) /* int */ - abort (); - - if (a55.si[0] != -55) /* int */ - abort (); - - if (a56.si[0] != +56) /* int */ - abort (); - - if (a57.si[0] != -57) /* int */ - abort (); - - if (a58.si[0] != +58) /* int */ - abort (); - - if (a59.si[0] != -59) /* int */ - abort (); - - if (a60.si[0] != +60) /* int */ - abort (); - - if (a61.si[0] != -61) /* int */ - abort (); - - if (a62.si[0] != +62) /* int */ - abort (); - - if (a63.si[0] != -63) /* int */ - abort (); - - if (a64.si[0] != +64) /* int */ - abort (); - - if (a65.si[0] != -65) /* int */ - abort (); - - if (a66.si[0] != +66) /* int */ - abort (); - - if (a67.si[0] != -67) /* int */ - abort (); - - if (a68.si[0] != +68) /* int */ - abort (); - - if (a69.si[0] != -69) /* int */ - abort (); - - if (a70.si[0] != +70) /* int */ - abort (); - - if (a71.si[0] != -71) /* int */ - abort (); - - if (a72.si[0] != +72) /* int */ - abort (); - - /* arguments passed on the stack */ - if (a73.sc[3] != -73) /* signed char */ - abort (); - - if (a74.uc[3] != 74) /* unsigned char */ - abort (); - - if (a75.ss[1] != -75) /* short */ - abort (); - - if (a76.us[1] != +76) /* unsigned short */ - abort (); - - if (a77.si[0] != -77) /* int */ - abort (); - - if (a78.ui[0] != +78) /* unsigned int */ - abort (); - - if (a79.sl[0] != -79) /* long */ - abort (); - - if (a80.ul[0] != +80) /* unsigned long */ - abort (); - - if (a81.sll[0] != -81) /* long long */ - abort (); - - if (a82.ull[0] != +82) /* unsigned long long */ - abort (); - - if (a83.f[0] != -83.0f) /* float */ - abort (); - - if (a84.d[0] != +84.0) /* double */ - abort (); -} - -int main(void) -{ - func_asm(-1, +2, -3, +4, -5, +6, -7, +8, -9, +10, - -11, +12, -13, +14, -15, +16, -17, +18, -19, +20, - -21, +22, -23, +24, -25, +26, -27, +28, -29, +30, - -31, +32, -33, +34, -35, +36, -37, +38, -39, +40, - -41, +42, -43, +44, -45, +46, -47, +48, -49, +50, - -51, +52, -53, +54, -55, +56, -57, +58, -59, +60, - -61, +62, -63, +64, -65, +66, -67, +68, -69, +70, - -71, +72, -73, +74, -75, +76, -77, +78, -79, +80, - -81, +82, -83, +84); - - return 0; -} diff --git a/gcc/testsuite/gcc.target/spu/compare-dp.c b/gcc/testsuite/gcc.target/spu/compare-dp.c deleted file mode 100644 index cbc7663..0000000 --- a/gcc/testsuite/gcc.target/spu/compare-dp.c +++ /dev/null @@ -1,10 +0,0 @@ -/* { dg-do compile } */ -/* { dg-final { scan-assembler-not "__eqdf2" } } */ - -/* Ensure double precision comparisons are always inlined. */ - -int test (double a, double b) __attribute__((noinline)); -int test (double a, double b) -{ - return a == b; -} diff --git a/gcc/testsuite/gcc.target/spu/cpat-1.c b/gcc/testsuite/gcc.target/spu/cpat-1.c deleted file mode 100644 index 6fe2925..0000000 --- a/gcc/testsuite/gcc.target/spu/cpat-1.c +++ /dev/null @@ -1,104 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O2 -w" } */ -/* { dg-final { scan-assembler-times "lqr\t.3,.LC" 4 } } */ -/* { dg-final { scan-assembler-times "cbd\t.3,0\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cbd\t.3,1\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cbd\t.3,2\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cbd\t.3,3\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cbd\t.3,4\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cbd\t.3,5\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cbd\t.3,6\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cbd\t.3,7\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cbd\t.3,8\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cbd\t.3,9\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cbd\t.3,10\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cbd\t.3,11\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cbd\t.3,12\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cbd\t.3,13\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cbd\t.3,14\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cbd\t.3,15\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "chd\t.3,0\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "chd\t.3,2\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "chd\t.3,4\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "chd\t.3,6\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "chd\t.3,8\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "chd\t.3,10\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "chd\t.3,12\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "chd\t.3,14\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cwd\t.3,0\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cwd\t.3,4\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cwd\t.3,8\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cwd\t.3,12\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cdd\t.3,0\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cdd\t.3,8\\(.sp\\)" 1 } } */ - -__vector unsigned char -not_cpat0() -{ - /* Contains no runs */ - return (__vector unsigned char) { - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; -} - -__vector unsigned char -not_cpat1() -{ - /* Includes 1 run but not in the right place. */ - return (__vector unsigned char) { - 0x10, 0x02, 0x03, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; -} - -__vector unsigned char -not_cpat2() -{ - /* Includes 2 runs. */ - return (__vector unsigned char) { - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03}; -} - -__vector unsigned char -not_cpat3() -{ - /* Includes 1 incorrect run. */ - return (__vector unsigned char) { - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x07, 0x1F}; -} - -__vector unsigned char cbd_0() { return (__vector unsigned char) { 0x03, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; } -__vector unsigned char cbd_1() { return (__vector unsigned char) { 0x10, 0x03, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; } -__vector unsigned char cbd_2() { return (__vector unsigned char) { 0x10, 0x11, 0x03, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; } -__vector unsigned char cbd_3() { return (__vector unsigned char) { 0x10, 0x11, 0x12, 0x03, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; } -__vector unsigned char cbd_4() { return (__vector unsigned char) { 0x10, 0x11, 0x12, 0x13, 0x03, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; } -__vector unsigned char cbd_5() { return (__vector unsigned char) { 0x10, 0x11, 0x12, 0x13, 0x14, 0x03, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; } -__vector unsigned char cbd_6() { return (__vector unsigned char) { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x03, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; } -__vector unsigned char cbd_7() { return (__vector unsigned char) { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x03, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; } -__vector unsigned char cbd_8() { return (__vector unsigned char) { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x03, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; } -__vector unsigned char cbd_9() { return (__vector unsigned char) { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; } -__vector unsigned char cbd_a() { return (__vector unsigned char) { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x03, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; } -__vector unsigned char cbd_b() { return (__vector unsigned char) { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x03, 0x1C, 0x1D, 0x1E, 0x1F}; } -__vector unsigned char cbd_c() { return (__vector unsigned char) { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x03, 0x1D, 0x1E, 0x1F}; } -__vector unsigned char cbd_d() { return (__vector unsigned char) { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x03, 0x1E, 0x1F}; } -__vector unsigned char cbd_e() { return (__vector unsigned char) { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x03, 0x1F}; } -__vector unsigned char cbd_f() { return (__vector unsigned char) { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x03}; } - -__vector unsigned char chd_0() { return (__vector unsigned char) { 0x02, 0x03, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; } -__vector unsigned char chd_2() { return (__vector unsigned char) { 0x10, 0x11, 0x02, 0x03, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; } -__vector unsigned char chd_4() { return (__vector unsigned char) { 0x10, 0x11, 0x12, 0x13, 0x02, 0x03, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; } -__vector unsigned char chd_6() { return (__vector unsigned char) { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x02, 0x03, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; } -__vector unsigned char chd_8() { return (__vector unsigned char) { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x02, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; } -__vector unsigned char chd_a() { return (__vector unsigned char) { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x02, 0x03, 0x1C, 0x1D, 0x1E, 0x1F}; } -__vector unsigned char chd_c() { return (__vector unsigned char) { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x02, 0x03, 0x1E, 0x1F}; } -__vector unsigned char chd_e() { return (__vector unsigned char) { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x02, 0x03}; } - -__vector unsigned char cwd_0() { return (__vector unsigned char) { 0x00, 0x01, 0x02, 0x03, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; } -__vector unsigned char cwd_4() { return (__vector unsigned char) { 0x10, 0x11, 0x12, 0x13, 0x00, 0x01, 0x02, 0x03, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; } -__vector unsigned char cwd_8() { return (__vector unsigned char) { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x00, 0x01, 0x02, 0x03, 0x1C, 0x1D, 0x1E, 0x1F}; } -__vector unsigned char cwd_c() { return (__vector unsigned char) { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x00, 0x01, 0x02, 0x03}; } - -__vector unsigned char cdd_0() { return (__vector unsigned char) { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; } -__vector unsigned char cdd_8() { return (__vector unsigned char) { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; } - diff --git a/gcc/testsuite/gcc.target/spu/cpat-2.c b/gcc/testsuite/gcc.target/spu/cpat-2.c deleted file mode 100644 index d5f86ed..0000000 --- a/gcc/testsuite/gcc.target/spu/cpat-2.c +++ /dev/null @@ -1,44 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O2 -w" } */ -/* { dg-final { scan-assembler-times "cbd .3,0\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cbd .3,1\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cbd .3,2\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cbd .3,3\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cbd .3,15\\(.sp\\)" 22 } } */ -/* { dg-final { scan-assembler-times "chd .3,0\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "chd .3,2\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "ila .3,66051" 2 } } */ - -#define MAKE_UINT(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,aA,aB,aC,aD,aE,aF) ((unsigned int)(a0 << 24 | a1 << 16 | a2 << 8 | a3)) - -unsigned int cbd_0() { return MAKE_UINT( 0x03, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned int cbd_1() { return MAKE_UINT( 0x10, 0x03, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned int cbd_2() { return MAKE_UINT( 0x10, 0x11, 0x03, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned int cbd_3() { return MAKE_UINT( 0x10, 0x11, 0x12, 0x03, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned int cbd_4() { return MAKE_UINT( 0x10, 0x11, 0x12, 0x13, 0x03, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned int cbd_5() { return MAKE_UINT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x03, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned int cbd_6() { return MAKE_UINT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x03, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned int cbd_7() { return MAKE_UINT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x03, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned int cbd_8() { return MAKE_UINT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x03, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned int cbd_9() { return MAKE_UINT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned int cbd_a() { return MAKE_UINT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x03, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned int cbd_b() { return MAKE_UINT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x03, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned int cbd_c() { return MAKE_UINT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x03, 0x1D, 0x1E, 0x1F); } -unsigned int cbd_d() { return MAKE_UINT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x03, 0x1E, 0x1F); } -unsigned int cbd_e() { return MAKE_UINT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x03, 0x1F); } -unsigned int cbd_f() { return MAKE_UINT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x03); } -unsigned int chd_0() { return MAKE_UINT( 0x02, 0x03, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned int chd_2() { return MAKE_UINT( 0x10, 0x11, 0x02, 0x03, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned int chd_4() { return MAKE_UINT( 0x10, 0x11, 0x12, 0x13, 0x02, 0x03, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned int chd_6() { return MAKE_UINT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x02, 0x03, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned int chd_8() { return MAKE_UINT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x02, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned int chd_a() { return MAKE_UINT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x02, 0x03, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned int chd_c() { return MAKE_UINT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x02, 0x03, 0x1E, 0x1F); } -unsigned int chd_e() { return MAKE_UINT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x02, 0x03); } -unsigned int cwd_0() { return MAKE_UINT( 0x00, 0x01, 0x02, 0x03, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned int cwd_4() { return MAKE_UINT( 0x10, 0x11, 0x12, 0x13, 0x00, 0x01, 0x02, 0x03, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned int cwd_8() { return MAKE_UINT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x00, 0x01, 0x02, 0x03, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned int cwd_c() { return MAKE_UINT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x00, 0x01, 0x02, 0x03); } -unsigned int cdd_0() { return MAKE_UINT( 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned int cdd_8() { return MAKE_UINT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07); } - diff --git a/gcc/testsuite/gcc.target/spu/cpat-3.c b/gcc/testsuite/gcc.target/spu/cpat-3.c deleted file mode 100644 index ced5011..0000000 --- a/gcc/testsuite/gcc.target/spu/cpat-3.c +++ /dev/null @@ -1,61 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O2 -w" } */ -/* { dg-final { scan-assembler-times "cbd .3,0\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cbd .3,1\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cbd .3,2\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cbd .3,3\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cbd .3,4\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cbd .3,5\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cbd .3,6\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cbd .3,7\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cbd .3,15\\(.sp\\)" 15 } } */ -/* { dg-final { scan-assembler-times "chd .3,0\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "chd .3,2\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "chd .3,4\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "chd .3,6\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cwd .3,0\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cwd .3,4\\(.sp\\)" 1 } } */ -/* { dg-final { scan-assembler-times "cdd .3,0\\(.sp\\)" 1 } } */ - -#define MAKE_ULLONG(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,aA,aB,aC,aD,aE,aF) \ - ((unsigned long long) \ - (a0##ull << 56 \ - | a1##ull << 48 \ - | a2##ull << 40 \ - | a3##ull << 32\ - | a4##ull << 24\ - | a5##ull << 16 \ - | a6##ull << 8 \ - | a7##ull )) - -unsigned long long cbd_0() { return MAKE_ULLONG( 0x03, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned long long cbd_1() { return MAKE_ULLONG( 0x10, 0x03, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned long long cbd_2() { return MAKE_ULLONG( 0x10, 0x11, 0x03, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned long long cbd_3() { return MAKE_ULLONG( 0x10, 0x11, 0x12, 0x03, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned long long cbd_4() { return MAKE_ULLONG( 0x10, 0x11, 0x12, 0x13, 0x03, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned long long cbd_5() { return MAKE_ULLONG( 0x10, 0x11, 0x12, 0x13, 0x14, 0x03, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned long long cbd_6() { return MAKE_ULLONG( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x03, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned long long cbd_7() { return MAKE_ULLONG( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x03, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned long long cbd_8() { return MAKE_ULLONG( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x03, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned long long cbd_9() { return MAKE_ULLONG( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned long long cbd_a() { return MAKE_ULLONG( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x03, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned long long cbd_b() { return MAKE_ULLONG( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x03, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned long long cbd_c() { return MAKE_ULLONG( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x03, 0x1D, 0x1E, 0x1F); } -unsigned long long cbd_d() { return MAKE_ULLONG( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x03, 0x1E, 0x1F); } -unsigned long long cbd_e() { return MAKE_ULLONG( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x03, 0x1F); } -unsigned long long cbd_f() { return MAKE_ULLONG( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x03); } -unsigned long long chd_0() { return MAKE_ULLONG( 0x02, 0x03, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned long long chd_2() { return MAKE_ULLONG( 0x10, 0x11, 0x02, 0x03, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned long long chd_4() { return MAKE_ULLONG( 0x10, 0x11, 0x12, 0x13, 0x02, 0x03, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned long long chd_6() { return MAKE_ULLONG( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x02, 0x03, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned long long chd_8() { return MAKE_ULLONG( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x02, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned long long chd_a() { return MAKE_ULLONG( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x02, 0x03, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned long long chd_c() { return MAKE_ULLONG( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x02, 0x03, 0x1E, 0x1F); } -unsigned long long chd_e() { return MAKE_ULLONG( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x02, 0x03); } -unsigned long long cwd_0() { return MAKE_ULLONG( 0x00, 0x01, 0x02, 0x03, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned long long cwd_4() { return MAKE_ULLONG( 0x10, 0x11, 0x12, 0x13, 0x00, 0x01, 0x02, 0x03, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned long long cwd_8() { return MAKE_ULLONG( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x00, 0x01, 0x02, 0x03, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned long long cwd_c() { return MAKE_ULLONG( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x00, 0x01, 0x02, 0x03); } -unsigned long long cdd_0() { return MAKE_ULLONG( 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned long long cdd_8() { return MAKE_ULLONG( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07); } - diff --git a/gcc/testsuite/gcc.target/spu/cpat-4.c b/gcc/testsuite/gcc.target/spu/cpat-4.c deleted file mode 100644 index 89110a66..0000000 --- a/gcc/testsuite/gcc.target/spu/cpat-4.c +++ /dev/null @@ -1,40 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O2 -w" } */ -/* { dg-final { scan-assembler-times "il\t.3,4611" 1 } } */ -/* { dg-final { scan-assembler-times "il\t.3,4627" 25 } } */ -/* { dg-final { scan-assembler-times "il\t.3,515" 3 } } */ -/* { dg-final { scan-assembler-times "il\t.3,787" 1 } } */ - -#define MAKE_USHORT(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,aA,aB,aC,aD,aE,aF) ((unsigned short)(a2 << 8 | a3)) - -unsigned short cbd_0() { return MAKE_USHORT( 0x03, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned short cbd_1() { return MAKE_USHORT( 0x10, 0x03, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned short cbd_2() { return MAKE_USHORT( 0x10, 0x11, 0x03, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned short cbd_3() { return MAKE_USHORT( 0x10, 0x11, 0x12, 0x03, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned short cbd_4() { return MAKE_USHORT( 0x10, 0x11, 0x12, 0x13, 0x03, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned short cbd_5() { return MAKE_USHORT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x03, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned short cbd_6() { return MAKE_USHORT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x03, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned short cbd_7() { return MAKE_USHORT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x03, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned short cbd_8() { return MAKE_USHORT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x03, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned short cbd_9() { return MAKE_USHORT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned short cbd_a() { return MAKE_USHORT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x03, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned short cbd_b() { return MAKE_USHORT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x03, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned short cbd_c() { return MAKE_USHORT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x03, 0x1D, 0x1E, 0x1F); } -unsigned short cbd_d() { return MAKE_USHORT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x03, 0x1E, 0x1F); } -unsigned short cbd_e() { return MAKE_USHORT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x03, 0x1F); } -unsigned short cbd_f() { return MAKE_USHORT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x03); } -unsigned short chd_0() { return MAKE_USHORT( 0x02, 0x03, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned short chd_2() { return MAKE_USHORT( 0x10, 0x11, 0x02, 0x03, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned short chd_4() { return MAKE_USHORT( 0x10, 0x11, 0x12, 0x13, 0x02, 0x03, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned short chd_6() { return MAKE_USHORT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x02, 0x03, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned short chd_8() { return MAKE_USHORT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x02, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned short chd_a() { return MAKE_USHORT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x02, 0x03, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned short chd_c() { return MAKE_USHORT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x02, 0x03, 0x1E, 0x1F); } -unsigned short chd_e() { return MAKE_USHORT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x02, 0x03); } -unsigned short cwd_0() { return MAKE_USHORT( 0x00, 0x01, 0x02, 0x03, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned short cwd_4() { return MAKE_USHORT( 0x10, 0x11, 0x12, 0x13, 0x00, 0x01, 0x02, 0x03, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned short cwd_8() { return MAKE_USHORT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x00, 0x01, 0x02, 0x03, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned short cwd_c() { return MAKE_USHORT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x00, 0x01, 0x02, 0x03); } -unsigned short cdd_0() { return MAKE_USHORT( 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F); } -unsigned short cdd_8() { return MAKE_USHORT( 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07); } - diff --git a/gcc/testsuite/gcc.target/spu/dfcgt-nan.c b/gcc/testsuite/gcc.target/spu/dfcgt-nan.c deleted file mode 100644 index 18ce013..0000000 --- a/gcc/testsuite/gcc.target/spu/dfcgt-nan.c +++ /dev/null @@ -1,31 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-march=celledp -O1" } */ -/* { dg-final { scan-assembler "dfceq" } } */ - -/* GCC previously transformed an "a <= b" test into "! (a > b)" when - compiling with -march=celledp, so that the dfcgt instruction can be - used to implement the comparison. - - However, this transformation violates the IEEE-754 standard in the - presence of NaN values. If either a or b is a NaN, a <= b should - evaluate to false according to IEEE rules. However, after the - transformation, a > b as implemented by dfcgt itself returns false, - so the transformed test returns true. - - Note that the equivalent transformation is valid for single- - precision floating-point values on the Cell SPU, because the format - does not have NaNs. It is invalid for double-precision, even on - Cell, however. */ - -int test (double a, double b) __attribute__ ((noinline)); -int test (double a, double b) -{ - return a <= b; -} - -int main (void) -{ - double x = 0.0; - double y = 0.0/0.0; - return test (x, y); -} diff --git a/gcc/testsuite/gcc.target/spu/dfcmeq.c b/gcc/testsuite/gcc.target/spu/dfcmeq.c deleted file mode 100644 index 9286361b..0000000 --- a/gcc/testsuite/gcc.target/spu/dfcmeq.c +++ /dev/null @@ -1,9 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-march=celledp -O1" } */ -/* { dg-final { scan-assembler "dfcmeq" } } */ - -int foo(double x, double y) -{ - if (__builtin_fabs(x) == __builtin_fabs(y)) - return 0; -} diff --git a/gcc/testsuite/gcc.target/spu/dfcmgt.c b/gcc/testsuite/gcc.target/spu/dfcmgt.c deleted file mode 100644 index ef7ef58..0000000 --- a/gcc/testsuite/gcc.target/spu/dfcmgt.c +++ /dev/null @@ -1,10 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-march=celledp -O1" } */ -/* { dg-final { scan-assembler "dfcmgt" } } */ - -int foo(double x, double y) -{ - if (__builtin_fabs(x) > __builtin_fabs(y)) - return 0; -} - diff --git a/gcc/testsuite/gcc.target/spu/ea/cache1.c b/gcc/testsuite/gcc.target/spu/ea/cache1.c deleted file mode 100644 index 3487ce9..0000000 --- a/gcc/testsuite/gcc.target/spu/ea/cache1.c +++ /dev/null @@ -1,195 +0,0 @@ -/* Copyright (C) 2009 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with this file; see the file COPYING3. If not see - . */ - -/* { dg-do run } */ -/* { dg-require-effective-target "ealib" } */ - -#include -#include -#include -#include - -#ifdef __EA64__ -#define addr unsigned long long -#else -#define addr unsigned long -#endif - -static __ea void *bigblock; -static __ea void *block; -static int *ls_block; - -extern char __cache_tag_array_size[]; -#define CACHE_SIZE (4 * (int) &__cache_tag_array_size[0]) -#define LINE_SIZE ((addr)128) - -void -init_mem (void) -{ - bigblock = malloc_ea (CACHE_SIZE + 2 * LINE_SIZE); - block = malloc_ea (2 * LINE_SIZE); - ls_block = malloc (LINE_SIZE); - - memset_ea (bigblock, 0, CACHE_SIZE + 2 * LINE_SIZE); - memset_ea (block, -1, 2 * LINE_SIZE); - memset (ls_block, -1, LINE_SIZE); - cache_flush (); -} - -/* Test 1: Simple cache fetching. */ -void -test1 (void) -{ - addr aligned = ((((addr) block) + LINE_SIZE - 1) & -LINE_SIZE); - int *p1 = NULL; - int *p2 = NULL; - int i = 0; - - /* First, check if the same addr give the same cache ptr. */ - p1 = cache_fetch ((__ea void *) aligned); - p2 = cache_fetch ((__ea void *) aligned); - - if (p1 != p2) - abort (); - - /* Check that the data actually is in the cache. */ - for (i = 0; i < LINE_SIZE / sizeof (int); i++) - { - if (p1[i] != -1) - abort (); - } - - /* Check returning within the cache line. */ - p2 = cache_fetch ((__ea void *) (aligned + sizeof (int))); - - if (p2 - p1 != 1) - abort (); - - /* Finally, check that fetching an LS pointer returns that pointer. */ - p1 = cache_fetch ((__ea char *) ls_block); - if (p1 != ls_block) - abort (); -} - -/* Test 2: Eviction testing. */ -void -test2 (void) -{ - addr aligned = ((((addr) block) + LINE_SIZE - 1) & -LINE_SIZE); - int *p = NULL; - int i = 0; - - /* First check that clean evictions don't write back. */ - p = cache_fetch ((__ea void *) aligned); - for (i = 0; i < LINE_SIZE / sizeof (int); i++) - p[i] = 0; - - cache_evict ((__ea void *) aligned); - memcpy_ea ((__ea char *) ls_block, (__ea void *) aligned, LINE_SIZE); - - for (i = 0; i < LINE_SIZE / sizeof (int); i++) - { - if (ls_block[i] == 0) - abort (); - } - - /* Now check that dirty evictions do write back. */ - p = cache_fetch_dirty ((__ea void *) aligned, LINE_SIZE); - for (i = 0; i < LINE_SIZE / sizeof (int); i++) - p[i] = 0; - - cache_evict ((__ea void *) aligned); - memcpy_ea ((__ea char *) ls_block, (__ea void *) aligned, LINE_SIZE); - - for (i = 0; i < LINE_SIZE / sizeof (int); i++) - { - if (ls_block[i] != 0) - abort (); - } - - /* Finally, check that non-atomic writeback only writes dirty bytes. */ - - for (i = 0; i < LINE_SIZE / sizeof (int); i++) - { - p = cache_fetch_dirty ((__ea void *) (aligned + i * sizeof (int)), - (i % 2) * sizeof (int)); - p[0] = -1; - } - - cache_evict ((__ea void *) aligned); - memcpy_ea ((__ea char *) ls_block, (__ea void *) aligned, LINE_SIZE); - - for (i = 0; i < LINE_SIZE / sizeof (int); i++) - { - if ((ls_block[i] == -1) && (i % 2 == 0)) - abort (); - if ((ls_block[i] == 0) && (i % 2 == 1)) - abort (); - } -} - -/* Test LS forced-eviction. */ -void -test3 (void) -{ - addr aligned = ((((addr) bigblock) + LINE_SIZE - 1) & -LINE_SIZE); - char *test = NULL; - char *ls = NULL; - int i = 0; - - /* Init memory, fill the cache to capacity. */ - ls = cache_fetch_dirty ((__ea void *) aligned, LINE_SIZE); - for (i = 1; i < (CACHE_SIZE / LINE_SIZE); i++) - cache_fetch_dirty ((__ea void *) (aligned + i * LINE_SIZE), LINE_SIZE); - - memset (ls, -1, LINE_SIZE); - test = cache_fetch ((__ea void *) (aligned + CACHE_SIZE)); - - /* test == ls indicates cache collision. */ - if (test != ls) - abort (); - - /* Make sure it actually wrote the cache line. */ - for (i = 0; i < LINE_SIZE; i++) - { - if (ls[i] != 0) - abort (); - } - - ls = cache_fetch ((__ea void *) aligned); - - /* test != ls indicates another entry was evicted. */ - if (test == ls) - abort (); - - /* Make sure that the previous eviction actually wrote back. */ - for (i = 0; i < LINE_SIZE; i++) - { - if (ls[i] != 0xFF) - abort (); - } -} - -int -main (int argc, char **argv) -{ - init_mem (); - test1 (); - test2 (); - test3 (); - - return 0; -} diff --git a/gcc/testsuite/gcc.target/spu/ea/cast1.c b/gcc/testsuite/gcc.target/spu/ea/cast1.c deleted file mode 100644 index 9ec4e15..0000000 --- a/gcc/testsuite/gcc.target/spu/ea/cast1.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (C) 2009 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with this file; see the file COPYING3. If not see - . */ - -/* { dg-do run } */ - -extern void abort (void); -extern unsigned long long __ea_local_store; - -__ea int *ppu; -int x, *spu = &x, *spu2; - -int -main (int argc, char **argv) -{ - ppu = (__ea int *) spu; - spu2 = (int *) ppu; - -#ifdef __EA32__ - if ((int) ppu != (int) __ea_local_store + (int) spu) -#else - if ((unsigned long long) ppu != __ea_local_store + (unsigned long long)(int) spu) -#endif - - abort (); - - if (spu != spu2) - abort (); - - return 0; -} diff --git a/gcc/testsuite/gcc.target/spu/ea/cast2.c b/gcc/testsuite/gcc.target/spu/ea/cast2.c deleted file mode 100644 index 6ce57dc..0000000 --- a/gcc/testsuite/gcc.target/spu/ea/cast2.c +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (C) 2009 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with this file; see the file COPYING3. If not see - . */ - -/* { dg-do run } */ - -extern void abort (void); - -int array[128]; - -__ea int *ea; -int *lm; - -void verify_ea (void) __attribute__ ((noinline)); -void -verify_ea (void) -{ - if (ea != (__ea int *)lm) - abort (); -} - -void verify_lm (void) __attribute__ ((noinline)); -void -verify_lm (void) -{ - if ((int *)ea != lm) - abort (); -} - -void verify_diff (int x) __attribute__ ((noinline)); -void -verify_diff (int x) -{ - if (ea - lm != x) - abort (); -} - -int -main (int argc, char **argv) -{ - ea = 0; - lm = 0; - verify_ea (); - verify_lm (); - verify_diff (0); - - ea = &array[64]; - lm = &array[64]; - verify_ea (); - verify_lm (); - verify_diff (0); - - ea = &array[0]; - lm = &array[64]; - verify_diff (-64); - - ea = &array[64]; - lm = &array[0]; - verify_diff (64); - - return 0; -} diff --git a/gcc/testsuite/gcc.target/spu/ea/compile1.c b/gcc/testsuite/gcc.target/spu/ea/compile1.c deleted file mode 100644 index ee7a32a..0000000 --- a/gcc/testsuite/gcc.target/spu/ea/compile1.c +++ /dev/null @@ -1,109 +0,0 @@ -/* Copyright (C) 2009 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with this file; see the file COPYING3. If not see - . */ - -/* Valid __ea declarations. */ - -/* { dg-do compile } */ - -/* Typedefs. */ -typedef __ea int ea_int_t; -typedef __ea int *ea_int_star_t; -typedef int outer_t; - -/* Externs. */ - -__ea extern int i1; -extern __ea int i2; -extern int __ea i3; -extern __ea ea_int_t i4; /* __ea qualifier permitted via typedef. */ -extern int __ea __ea __ea dupe; /* __ea duplicate permitted directly. */ -extern int __ea *ppu; - -/* Pointers. */ -__ea int *i4p; - -/* Structs. */ -struct st { - __ea int *p; -}; - -/* Variable definitions. */ -__ea int ii0; -int *__ea ii1; -static int __ea ii2; - -void -f1 () -{ - int *spu; - ppu = (ea_int_t *) spu; - ppu = (ea_int_star_t) spu; -} - -void -f2 () -{ - int *spu; - spu = (int *) ppu; - ppu = (__ea int *) spu; -} - -void -f3 () -{ - int i = sizeof (__ea int); -} - -__ea int *f4 (void) -{ - return 0; -} - -int f5 (__ea int *parm) -{ - static __ea int local4; - int tmp = local4; - local4 = *parm; - return tmp; -} - -static inline __ea void *f6 (__ea void *start) -{ - return 0; -} - -void f7 (void) -{ - __ea void *s1; - auto __ea void *s2; -} - -__ea int *f8 (__ea int *x) -{ - register __ea int *y = x; - __ea int *z = y; - return z; -} - -long long f9 (__ea long long x[2]) -{ - return x[0] + x[1]; -} - -void f10 () -{ - static __ea outer_t o; -} diff --git a/gcc/testsuite/gcc.target/spu/ea/compile2.c b/gcc/testsuite/gcc.target/spu/ea/compile2.c deleted file mode 100644 index 58e6489..0000000 --- a/gcc/testsuite/gcc.target/spu/ea/compile2.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (C) 2009 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with this file; see the file COPYING3. If not see - . */ - -/* Make sure __ea structure references work. */ - -/* { dg-do compile } */ - -typedef unsigned long int uintptr_t; - -struct tostruct -{ - uintptr_t selfpc; - long count; - unsigned short link; -}; - -/* froms are indexing tos */ -static __ea unsigned short *froms; -static __ea struct tostruct *tos = 0; - -void -foo (uintptr_t frompc, uintptr_t selfpc) -{ - __ea unsigned short *frompcindex; - - frompcindex = &froms[(frompc) / (4 * sizeof (*froms))]; - *frompcindex = tos[0].link; - - return; -} diff --git a/gcc/testsuite/gcc.target/spu/ea/cppdefine.c b/gcc/testsuite/gcc.target/spu/ea/cppdefine.c deleted file mode 100644 index 5836357..0000000 --- a/gcc/testsuite/gcc.target/spu/ea/cppdefine.c +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (C) 2009 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with this file; see the file COPYING3. If not see - . */ - -/* Test default __EA32__/__EA64__ define. */ - -/* { dg-do compile } */ - -#if !defined (__EA32__) && !defined (__EA64__) -#error both __EA32__ and __EA64__ undefined -#endif - -#if defined (__EA32__) && defined (__EA64__) -#error both __EA32__ and __EA64__ defined -#endif - -#ifdef __EA32__ -int x [ sizeof (__ea char *) == 4 ? 1 : -1 ]; -#endif - -#ifdef __EA64__ -int x [ sizeof (__ea char *) == 8 ? 1 : -1 ]; -#endif - diff --git a/gcc/testsuite/gcc.target/spu/ea/ea.exp b/gcc/testsuite/gcc.target/spu/ea/ea.exp deleted file mode 100644 index 5411454..0000000 --- a/gcc/testsuite/gcc.target/spu/ea/ea.exp +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright (C) 2008-2019 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# . - -# GCC testsuite that uses the `dg.exp' driver. - -# Exit immediately if this isn't a SPU target. -if { ![istarget spu-*-*] } then { - return -} - -# Load support procs. -load_lib gcc-dg.exp - -# Return 1 if target __ea library functions are available -proc check_effective_target_ealib { } { - return [check_no_compiler_messages ealib executable { - #include - int main (void) - { - __ea void *ptr = malloc_ea (1024); - return 0; - } - }] -} - -# If a testcase doesn't have special options, use these. -# We do not use the global DEFAULT_CFLAGS as all test cases -# in this directory use the __ea address space qualifier -# extension and thus will not compile with -ansi. -set DEFAULT_EA_CFLAGS "-std=gnu99 -pedantic-errors -O2" - -# Initialize `dg'. -dg-init - -# Run all tests in both -mea32 and -mea64 mode. -set tests [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] -dg-runtest $tests "-mea32" $DEFAULT_EA_CFLAGS -dg-runtest $tests "-mea64" $DEFAULT_EA_CFLAGS - -# All done. -dg-finish diff --git a/gcc/testsuite/gcc.target/spu/ea/errors1.c b/gcc/testsuite/gcc.target/spu/ea/errors1.c deleted file mode 100644 index 7d0b5a1..0000000 --- a/gcc/testsuite/gcc.target/spu/ea/errors1.c +++ /dev/null @@ -1,67 +0,0 @@ -/* Copyright (C) 2009 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with this file; see the file COPYING3. If not see - . */ - -/* Invalid __ea declarations. */ - -/* { dg-do compile } */ - -typedef __ea int eaint; - -void func () -{ - register __ea int local1; /* { dg-error "'__ea' combined with 'register' qualifier for 'local1'" } */ - auto __ea int local2; /* { dg-error "'__ea' combined with 'auto' qualifier for 'local2'" } */ - __ea int local3; /* { dg-error "'__ea' specified for auto variable 'local3'" } */ - register int *__ea p1; /* { dg-error "'__ea' combined with 'register' qualifier for 'p1'" } */ - auto char *__ea p2; /* { dg-error "'__ea' combined with 'auto' qualifier for 'p2'" } */ - void *__ea p3; /* { dg-error "'__ea' specified for auto variable 'p3'" } */ - register __ea int a1[2]; /* { dg-error "'__ea' combined with 'register' qualifier for 'a1'" } */ - auto __ea char a2[1]; /* { dg-error "'__ea' combined with 'auto' qualifier for 'a2'" } */ - __ea char a3[5]; /* { dg-error "'__ea' specified for auto variable 'a3'" } */ - register eaint td1; /* { dg-error "'__ea' combined with 'register' qualifier for 'td1'" } */ - auto eaint td2; /* { dg-error "'__ea' combined with 'auto' qualifier for 'td2'" } */ - eaint td3; /* { dg-error "'__ea' specified for auto variable 'td3'" } */ -} - -void func2 (__ea int x) /* { dg-error "'__ea' specified for parameter 'x'" } */ -{ } - -void func2td (eaint x) /* { dg-error "'__ea' specified for parameter 'x'" } */ -{ } - -struct st { - __ea int x; /* { dg-error "'__ea' specified for structure field 'x'" } */ - eaint td; /* { dg-error "'__ea' specified for structure field 'td'" } */ - int *__ea q; /* { dg-error "'__ea' specified for structure field 'q'" } */ - int __ea b : 7; /* { dg-error "'__ea' specified for structure field 'b'" } */ - int __ea : 1; /* { dg-error "'__ea' specified for structure field" } */ -} s; - -struct A { int a; }; - -int func3 (int *__ea); /* { dg-error "'__ea' specified for unnamed parameter" } */ -int func3 (int *__ea x) /* { dg-error "'__ea' specified for parameter 'x'" } */ -{ - struct A i = (__ea struct A) { 1 }; /* { dg-error "compound literal qualified by address-space qualifier" } */ - return i.a; -} - -extern __ea int ea_var; /* { dg-message "note: previous declaration of 'ea_var' was here" } */ -int ea_var; /* { dg-error "conflicting named address spaces \\(generic vs __ea\\) for 'ea_var'" } */ - -extern eaint ea_var_td; /* { dg-message "note: previous declaration of 'ea_var_td' was here" } */ -int ea_var_td; /* { dg-error "conflicting named address spaces \\(generic vs __ea\\) for 'ea_var_td'" } */ - diff --git a/gcc/testsuite/gcc.target/spu/ea/errors2.c b/gcc/testsuite/gcc.target/spu/ea/errors2.c deleted file mode 100644 index f8269e9..0000000 --- a/gcc/testsuite/gcc.target/spu/ea/errors2.c +++ /dev/null @@ -1,107 +0,0 @@ -/* Copyright (C) 2009 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with this file; see the file COPYING3. If not see - . */ - -/* Invalid __ea declarations. */ - -/* { dg-do compile } */ - -__ea char ea_str[] = "abc"; -char lm_str[] = "abc"; - -__ea char *lm_ea_ptr1 = "abc"; /* { dg-error "initializer element is not computable at load time" } */ -__ea char *lm_ea_ptr2 = (__ea char *)"abc"; /* { dg-error "initializer element is not constant" } */ -__ea char *lm_ea_ptr3 = ea_str; -__ea char *lm_ea_ptr4 = (__ea char *)ea_str; -__ea char *lm_ea_ptr5 = lm_str; /* { dg-error "initializer element is not computable at load time" } */ -__ea char *lm_ea_ptr6 = (__ea char *)lm_str; /* { dg-error "initializer element is not constant" } */ - -__ea char * __ea ea_ea_ptr1 = ea_str; -__ea char * __ea ea_ea_ptr2 = (__ea char *)ea_str; - -char * __ea ea_lm_ptr1 = lm_str; -char * __ea ea_lm_ptr2 = (char *)lm_str; - -struct foo { - int first; - __ea char *ptr; - int last; -}; - -__ea struct foo ea_struct1 = { - 10, - (__ea char *)0, - 11, -}; - -__ea struct foo ea_struct2 = { - 20, - 0, - 21, -}; - -struct foo ea_struct3 = { - 30, - ea_str, - 31, -}; - -struct foo ea_struct4 = { - 40, - (__ea char *)lm_str, /* { dg-error "(initializer element is not constant)|(near initialization)" } */ - 41, -}; - -struct bar { - int first; - char *ptr; - int last; -}; - -__ea struct bar ea_struct5 = { - 50, - 0, - 51, -}; - -__ea struct bar ea_struct6 = { - 60, - (char *)0, - 61, -}; - -__ea struct bar ea_struct7 = { - 70, - lm_str, - 71, -}; - -struct bar lm_struct8 = { - 80, - 0, - 81, -}; - -struct bar lm_struct9 = { - 90, - (char *)0, - 91, -}; - -struct bar lm_struct10 = { - 100, - lm_str, - 101, -}; diff --git a/gcc/testsuite/gcc.target/spu/ea/execute1.c b/gcc/testsuite/gcc.target/spu/ea/execute1.c deleted file mode 100644 index 99d6d69..0000000 --- a/gcc/testsuite/gcc.target/spu/ea/execute1.c +++ /dev/null @@ -1,41 +0,0 @@ -/* Copyright (C) 2009 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with this file; see the file COPYING3. If not see - . */ - -/* { dg-do compile } */ - -#include - -__ea char str[] = "abc"; - -int -main (void) -{ - __ea char *p = str; - - if (*p++ != 'a') - abort (); - - if (*p++ != 'b') - abort (); - - if (*p++ != 'c') - abort (); - - if (*p++ != '\0') - abort (); - - return 0; -} diff --git a/gcc/testsuite/gcc.target/spu/ea/execute2.c b/gcc/testsuite/gcc.target/spu/ea/execute2.c deleted file mode 100644 index 5fce4e6..0000000 --- a/gcc/testsuite/gcc.target/spu/ea/execute2.c +++ /dev/null @@ -1,41 +0,0 @@ -/* Copyright (C) 2009 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with this file; see the file COPYING3. If not see - . */ - -/* { dg-do run } */ - -#include - -char str[] = "abc"; - -int -main (void) -{ - __ea char *p = (__ea char *)str; - - if (*p++ != 'a') - abort (); - - if (*p++ != 'b') - abort (); - - if (*p++ != 'c') - abort (); - - if (*p++ != '\0') - abort (); - - return 0; -} diff --git a/gcc/testsuite/gcc.target/spu/ea/execute3.c b/gcc/testsuite/gcc.target/spu/ea/execute3.c deleted file mode 100644 index 1b8c139..0000000 --- a/gcc/testsuite/gcc.target/spu/ea/execute3.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (C) 2009 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with this file; see the file COPYING3. If not see - . */ - -/* { dg-do run } */ - -#include - -int -main (void) -{ - __ea char *p = (__ea char *)"abc"; - - if (*p++ != 'a') - abort (); - - if (*p++ != 'b') - abort (); - - if (*p++ != 'c') - abort (); - - if (*p++ != '\0') - abort (); - - return 0; -} diff --git a/gcc/testsuite/gcc.target/spu/ea/ops1.c b/gcc/testsuite/gcc.target/spu/ea/ops1.c deleted file mode 100644 index 0d162f2..0000000 --- a/gcc/testsuite/gcc.target/spu/ea/ops1.c +++ /dev/null @@ -1,94 +0,0 @@ -/* Copyright (C) 2009 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with this file; see the file COPYING3. If not see - . */ - -/* This is the same as ops2.c except for the compile option. - If you modify this code, please modify ops2.c as well. */ - -/* { dg-do compile } */ -/* { dg-options "-O2 -std=gnu99 -pedantic-errors -maddress-space-conversion" } */ - -#define __lm - -__ea int ea_var = 1; -__lm int lm_var = 2; - -typedef __ea int *ea_ptr_t; -typedef __lm int *lm_ptr_t; - -typedef __ea void *ea_vptr_t; -typedef __lm void *lm_vptr_t; - -ea_ptr_t ea, ea2; -lm_ptr_t lm, lm2; - -ea_vptr_t eav; -lm_vptr_t lmv; - -extern void call_ea (ea_ptr_t); -extern void call_lm (lm_ptr_t); - -/* Assignment, initialization, argument passing, and return. */ -void to_ea (void) { ea = lm; } -void to_lm (void) { lm = ea; } /* { dg-error "assignment from pointer to non-enclosed address space" } */ -void init_ea (void) { ea_ptr_t l_ea = lm; } -void init_lm (void) { lm_ptr_t l_lm = ea; } /* { dg-error "initialization from pointer to non-enclosed address space" } */ -ea_ptr_t ret_ea (void) { return lm; } -lm_ptr_t ret_lm (void) { return ea; } /* { dg-error "return from pointer to non-enclosed address space" } */ -void call_ea2 (void) { call_ea (lm); } -void call_lm2 (void) { call_lm (ea); } /* { dg-error "passing argument 1 of 'call_lm' from pointer to non-enclosed address space" } */ - -/* Explicit casts. */ -void to_ea_with_cast (void) { ea = (ea_ptr_t)lm; } -void to_lm_with_cast (void) { lm = (lm_ptr_t)ea; } -void init_ea_with_cast (void) { ea_ptr_t l_ea = (ea_ptr_t)lm; } -void init_lm_with_cast (void) { lm_ptr_t l_lm = (lm_ptr_t)ea; } -ea_ptr_t ret_ea_with_cast (void) { return (ea_ptr_t)lm; } -lm_ptr_t ret_lm_with_cast (void) { return (lm_ptr_t)ea; } -void call_ea2_with_cast (void) { call_ea ((ea_ptr_t)lm); } -void call_lm2_with_cast (void) { call_lm ((lm_ptr_t)ea); } - -/* Arithmetic operators. */ -int sub_eaea (void) { return ea - ea2; } -int sub_ealm (void) { return ea - lm2; } -int sub_lmea (void) { return lm - ea2; } -int sub_lmlm (void) { return lm - lm2; } -ea_ptr_t if_eaea1 (int test) { return test? ea : ea2; } -lm_ptr_t if_eaea2 (int test) { return test? ea : ea2; } /* { dg-error "return from pointer to non-enclosed address space" } */ -ea_ptr_t if_ealm1 (int test) { return test? ea : lm2; } -lm_ptr_t if_ealm2 (int test) { return test? ea : lm2; } /* { dg-error "return from pointer to non-enclosed address space" } */ -ea_ptr_t if_lmea1 (int test) { return test? lm : ea2; } -lm_ptr_t if_lmea2 (int test) { return test? lm : ea2; } /* { dg-error "return from pointer to non-enclosed address space" } */ -ea_ptr_t if_lmlm1 (int test) { return test? lm : lm2; } -lm_ptr_t if_lmlm2 (int test) { return test? lm : lm2; } - -/* Relational operators. */ -int eq_eaea (void) { return ea == ea2; } -int eq_ealm (void) { return ea == lm2; } -int eq_lmea (void) { return lm == ea2; } -int eq_lmlm (void) { return lm == lm2; } -int lt_eaea (void) { return ea < ea2; } -int lt_ealm (void) { return ea < lm2; } -int lt_lmea (void) { return lm < ea2; } -int lt_lmlm (void) { return lm < lm2; } - -/* Null pointer. */ -void null_ea1 (void) { ea = 0; } -void null_ea2 (void) { ea = (void *)0; } -void null_ea3 (void) { ea = (__ea void *)0; } -void null_lm1 (void) { lm = 0; } -void null_lm2 (void) { lm = (void *)0; } -void null_lm3 (void) { lm = (__ea void *)0; } /* { dg-error "assignment from pointer to non-enclosed address space" } */ - diff --git a/gcc/testsuite/gcc.target/spu/ea/ops2.c b/gcc/testsuite/gcc.target/spu/ea/ops2.c deleted file mode 100644 index 2514e6b..0000000 --- a/gcc/testsuite/gcc.target/spu/ea/ops2.c +++ /dev/null @@ -1,94 +0,0 @@ -/* Copyright (C) 2009 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with this file; see the file COPYING3. If not see - . */ - -/* This is the same as ops1.c except for the compile option. - If you modify this code, please modify ops1.c as well. */ - -/* { dg-do compile } */ -/* { dg-options "-O2 -std=gnu99 -pedantic-errors -mno-address-space-conversion" } */ - -#define __lm - -__ea int ea_var = 1; -__lm int lm_var = 2; - -typedef __ea int *ea_ptr_t; -typedef __lm int *lm_ptr_t; - -typedef __ea void *ea_vptr_t; -typedef __lm void *lm_vptr_t; - -ea_ptr_t ea, ea2; -lm_ptr_t lm, lm2; - -ea_vptr_t eav; -lm_vptr_t lmv; - -extern void call_ea (ea_ptr_t); -extern void call_lm (lm_ptr_t); - -/* Assignment, initialization, argument passing, and return. */ -void to_ea (void) { ea = lm; } /* { dg-error "assignment from pointer to non-enclosed address space" } */ -void to_lm (void) { lm = ea; } /* { dg-error "assignment from pointer to non-enclosed address space" } */ -void init_ea (void) { ea_ptr_t l_ea = lm; } /* { dg-error "initialization from pointer to non-enclosed address space" } */ -void init_lm (void) { lm_ptr_t l_lm = ea; } /* { dg-error "initialization from pointer to non-enclosed address space" } */ -ea_ptr_t ret_ea (void) { return lm; } /* { dg-error "return from pointer to non-enclosed address space" } */ -lm_ptr_t ret_lm (void) { return ea; } /* { dg-error "return from pointer to non-enclosed address space" } */ -void call_ea2 (void) { call_ea (lm); } /* { dg-error "passing argument 1 of 'call_ea' from pointer to non-enclosed address space" } */ -void call_lm2 (void) { call_lm (ea); } /* { dg-error "passing argument 1 of 'call_lm' from pointer to non-enclosed address space" } */ - -/* Explicit casts. */ -void to_ea_with_cast (void) { ea = (ea_ptr_t)lm; } /* { dg-warning "cast to __ea address space pointer" } */ -void to_lm_with_cast (void) { lm = (lm_ptr_t)ea; } /* { dg-warning "cast to generic address space pointer" } */ -void init_ea_with_cast (void) { ea_ptr_t l_ea = (ea_ptr_t)lm; } /* { dg-warning "cast to __ea address space pointer" } */ -void init_lm_with_cast (void) { lm_ptr_t l_lm = (lm_ptr_t)ea; } /* { dg-warning "cast to generic address space pointer" } */ -ea_ptr_t ret_ea_with_cast (void) { return (ea_ptr_t)lm; } /* { dg-warning "cast to __ea address space pointer" } */ -lm_ptr_t ret_lm_with_cast (void) { return (lm_ptr_t)ea; } /* { dg-warning "cast to generic address space pointer" } */ -void call_ea2_with_cast (void) { call_ea ((ea_ptr_t)lm); } /* { dg-warning "cast to __ea address space pointer" } */ -void call_lm2_with_cast (void) { call_lm ((lm_ptr_t)ea); } /* { dg-warning "cast to generic address space pointer" } */ - -/* Arithmetic operators. */ -int sub_eaea (void) { return ea - ea2; } -int sub_ealm (void) { return ea - lm2; } /* { dg-error "invalid operands to binary -" } */ -int sub_lmea (void) { return lm - ea2; } /* { dg-error "invalid operands to binary -" } */ -int sub_lmlm (void) { return lm - lm2; } -ea_ptr_t if_eaea1 (int test) { return test? ea : ea2; } -lm_ptr_t if_eaea2 (int test) { return test? ea : ea2; } /* { dg-error "return from pointer to non-enclosed address space" } */ -ea_ptr_t if_ealm1 (int test) { return test? ea : lm2; } /* { dg-error "pointers to disjoint address spaces used in conditional expression" } */ -lm_ptr_t if_ealm2 (int test) { return test? ea : lm2; } /* { dg-error "pointers to disjoint address spaces used in conditional expression" } */ -ea_ptr_t if_lmea1 (int test) { return test? lm : ea2; } /* { dg-error "pointers to disjoint address spaces used in conditional expression" } */ -lm_ptr_t if_lmea2 (int test) { return test? lm : ea2; } /* { dg-error "pointers to disjoint address spaces used in conditional expression" } */ -ea_ptr_t if_lmlm1 (int test) { return test? lm : lm2; } /* { dg-error "return from pointer to non-enclosed address space" } */ -lm_ptr_t if_lmlm2 (int test) { return test? lm : lm2; } - -/* Relational operators. */ -int eq_eaea (void) { return ea == ea2; } -int eq_ealm (void) { return ea == lm2; } /* { dg-error "comparison of pointers to disjoint address spaces" } */ -int eq_lmea (void) { return lm == ea2; } /* { dg-error "comparison of pointers to disjoint address spaces" } */ -int eq_lmlm (void) { return lm == lm2; } -int lt_eaea (void) { return ea < ea2; } -int lt_ealm (void) { return ea < lm2; } /* { dg-error "comparison of pointers to disjoint address spaces" } */ -int lt_lmea (void) { return lm < ea2; } /* { dg-error "comparison of pointers to disjoint address spaces" } */ -int lt_lmlm (void) { return lm < lm2; } - -/* Null pointer. */ -void null_ea1 (void) { ea = 0; } -void null_ea2 (void) { ea = (void *)0; } -void null_ea3 (void) { ea = (__ea void *)0; } -void null_lm1 (void) { lm = 0; } -void null_lm2 (void) { lm = (void *)0; } -void null_lm3 (void) { lm = (__ea void *)0; } /* { dg-error "assignment from pointer to non-enclosed address space" } */ - diff --git a/gcc/testsuite/gcc.target/spu/ea/options1.c b/gcc/testsuite/gcc.target/spu/ea/options1.c deleted file mode 100644 index 1904009..0000000 --- a/gcc/testsuite/gcc.target/spu/ea/options1.c +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright (C) 2009 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with this file; see the file COPYING3. If not see - . */ - -/* Test -mcache-size. */ - -/* { dg-do compile } */ -/* { dg-options "-mcache-size=128" } */ - -int x; diff --git a/gcc/testsuite/gcc.target/spu/ea/pr41857.c b/gcc/testsuite/gcc.target/spu/ea/pr41857.c deleted file mode 100644 index 1771067..0000000 --- a/gcc/testsuite/gcc.target/spu/ea/pr41857.c +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2009 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with this file; see the file COPYING3. If not see - . */ - -/* { dg-do compile } */ - -__ea char *strchr_ea (__ea const char *s, int c); -__ea char *foo (__ea char *s) -{ - __ea char *ret = s; - int i; - - for (i = 0; i < 3; i++) - ret = strchr_ea (ret, s[i]); - - return ret; -} diff --git a/gcc/testsuite/gcc.target/spu/ea/test-sizes.c b/gcc/testsuite/gcc.target/spu/ea/test-sizes.c deleted file mode 100644 index e467616..0000000 --- a/gcc/testsuite/gcc.target/spu/ea/test-sizes.c +++ /dev/null @@ -1,608 +0,0 @@ -/* Copyright (C) 2009 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with this file; see the file COPYING3. If not see - . */ - -/* { dg-do run } */ - -#ifdef __EA32__ -#define EA_PTRSIZE 4 -#endif -#ifdef __EA64__ -#define EA_PTRSIZE 8 -#endif - -#if !defined(LEVEL1) && !defined(LEVEL2) && !defined(LEVEL3) -#define LEVEL1 1 /* single pointer indirection */ -#define LEVEL2 1 /* 2 levels of pointer indirection */ -#define LEVEL3 1 /* 3 levels of pointer indirection */ - -#else -#ifndef LEVEL1 -#define LEVEL1 0 -#endif - -#ifndef LEVEL2 -#define LEVEL2 0 -#endif - -#ifndef LEVEL3 -#define LEVEL3 0 -#endif -#endif - -#if !defined(USE_SIMPLE) && !defined(USE_COMPLEX) -#define USE_SIMPLE 1 /* build up pointers via multiple typedefs */ -#define USE_COMPLEX 1 /* single typedef for pointer indirections */ - -#else -#ifndef USE_SIMPLE -#define USE_SIMPLE 0 -#endif - -#ifndef USE_COMPLEX -#define USE_COMPLEX 0 -#endif -#endif - -#if !defined(USE_LOCAL_VAR) && !defined(USE_EA_VAR) -#define USE_LOCAL_VAR 1 /* use variables declared locally */ -#define USE_EA_VAR 1 /* use variables on the host */ - -#else -#ifndef USE_LOCAL_VAR -#define USE_LOCAL_VAR 0 -#endif - -#ifndef USE_EA_VAR -#define USE_EA_VAR 0 -#endif -#endif - -static int errors; - -#ifdef USE_PRINTF /* print results via printf */ -#include -#include - -static int num_tests; - -#define TEST_SIZE(EXPR, EXPECTED) \ -do { \ - char *msg; \ - \ - if (sizeof (EXPR) != EXPECTED) \ - { \ - msg = ", FAIL"; \ - errors++; \ - } \ - else \ - msg = ""; \ - \ - num_tests++; \ - printf ("sizeof %-20s = %2u, expected = %2u%s\n", \ - #EXPR, \ - (unsigned) sizeof (EXPR), \ - (unsigned) EXPECTED, \ - msg); \ -} while (0) - -#define PRINT1(FMT) printf (FMT) -#define PRINT2(FMT,A1) printf (FMT,A1) -#define PRINT3(FMT,A1,A2) printf (FMT,A1,A2) - -#else /* standalone */ -extern void abort (void); - -#define TEST_SIZE(EXPR, EXPECTED) \ -do { \ - if (sizeof (EXPR) != EXPECTED) \ - abort (); \ -} while (0) - -#define PRINT1(FMT) -#define PRINT2(FMT,ARG) -#define PRINT3(FMT,A1,A2) -#endif - -/* 'local memory' hack to keep the same spacing. */ -#define __lm - -#if USE_SIMPLE -#if (LEVEL1 || LEVEL2 || LEVEL3) -typedef __lm char *lm_ptr_t; -typedef __ea char *ea_ptr_t; -#endif - -#if LEVEL1 -#if USE_LOCAL_VAR -__lm lm_ptr_t lm_ptr; -__lm ea_ptr_t ea_ptr; -#endif - -#if USE_EA_VAR -__ea lm_ptr_t lm_ptr_ea; -__ea ea_ptr_t ea_ptr_ea; -#endif -#endif - -#if (LEVEL2 || LEVEL3) -typedef __lm lm_ptr_t *lm_lm_ptr_t; -typedef __ea lm_ptr_t *ea_lm_ptr_t; -typedef __lm ea_ptr_t *lm_ea_ptr_t; -typedef __ea ea_ptr_t *ea_ea_ptr_t; -#endif - -#if LEVEL2 -#if USE_LOCAL_VAR -__lm lm_lm_ptr_t lm_lm_ptr; -__lm ea_lm_ptr_t ea_lm_ptr; -__lm lm_ea_ptr_t lm_ea_ptr; -__lm ea_ea_ptr_t ea_ea_ptr; -#endif - -#if USE_EA_VAR -__ea lm_lm_ptr_t lm_lm_ptr_ea; -__ea ea_lm_ptr_t ea_lm_ptr_ea; -__ea lm_ea_ptr_t lm_ea_ptr_ea; -__ea ea_ea_ptr_t ea_ea_ptr_ea; -#endif -#endif - -#if LEVEL3 -typedef __lm lm_lm_ptr_t *lm_lm_lm_ptr_t; -typedef __ea lm_lm_ptr_t *ea_lm_lm_ptr_t; -typedef __lm ea_lm_ptr_t *lm_ea_lm_ptr_t; -typedef __ea ea_lm_ptr_t *ea_ea_lm_ptr_t; -typedef __lm lm_ea_ptr_t *lm_lm_ea_ptr_t; -typedef __ea lm_ea_ptr_t *ea_lm_ea_ptr_t; -typedef __lm ea_ea_ptr_t *lm_ea_ea_ptr_t; -typedef __ea ea_ea_ptr_t *ea_ea_ea_ptr_t; - -#if USE_LOCAL_VAR -__lm lm_lm_lm_ptr_t lm_lm_lm_ptr; -__lm ea_lm_lm_ptr_t ea_lm_lm_ptr; -__lm lm_ea_lm_ptr_t lm_ea_lm_ptr; -__lm ea_ea_lm_ptr_t ea_ea_lm_ptr; -__lm lm_lm_ea_ptr_t lm_lm_ea_ptr; -__lm ea_lm_ea_ptr_t ea_lm_ea_ptr; -__lm lm_ea_ea_ptr_t lm_ea_ea_ptr; -__lm ea_ea_ea_ptr_t ea_ea_ea_ptr; -#endif - -#if USE_EA_VAR -__ea lm_lm_lm_ptr_t lm_lm_lm_ptr_ea; -__ea ea_lm_lm_ptr_t ea_lm_lm_ptr_ea; -__ea lm_ea_lm_ptr_t lm_ea_lm_ptr_ea; -__ea ea_ea_lm_ptr_t ea_ea_lm_ptr_ea; -__ea lm_lm_ea_ptr_t lm_lm_ea_ptr_ea; -__ea ea_lm_ea_ptr_t ea_lm_ea_ptr_ea; -__ea lm_ea_ea_ptr_t lm_ea_ea_ptr_ea; -__ea ea_ea_ea_ptr_t ea_ea_ea_ptr_ea; -#endif -#endif -#endif - -#if USE_COMPLEX -#if LEVEL1 -#if USE_LOCAL_VAR -__lm char *__lm lm_cptr; -__ea char *__lm ea_cptr; -#endif - -#if USE_EA_VAR -__lm char *__ea lm_cptr_ea; -__ea char *__ea ea_cptr_ea; -#endif -#endif - -#if LEVEL2 -#if USE_LOCAL_VAR -__lm char *__lm *__lm lm_lm_cptr; -__lm char *__ea *__lm ea_lm_cptr; -__ea char *__lm *__lm lm_ea_cptr; -__ea char *__ea *__lm ea_ea_cptr; -#endif - -#if USE_EA_VAR -__lm char *__lm *__ea lm_lm_cptr_ea; -__lm char *__ea *__ea ea_lm_cptr_ea; -__ea char *__lm *__ea lm_ea_cptr_ea; -__ea char *__ea *__ea ea_ea_cptr_ea; -#endif -#endif - -#if LEVEL3 -#if USE_LOCAL_VAR -__lm char *__lm *__lm *__lm lm_lm_lm_cptr; -__lm char *__ea *__lm *__lm lm_ea_lm_cptr; -__ea char *__lm *__lm *__lm lm_lm_ea_cptr; -__ea char *__ea *__lm *__lm lm_ea_ea_cptr; -__lm char *__lm *__ea *__lm ea_lm_lm_cptr; -__lm char *__ea *__ea *__lm ea_ea_lm_cptr; -__ea char *__lm *__ea *__lm ea_lm_ea_cptr; -__ea char *__ea *__ea *__lm ea_ea_ea_cptr; -#endif - -#if USE_EA_VAR -__lm char *__lm *__lm *__ea lm_lm_lm_cptr_ea; -__lm char *__ea *__lm *__ea lm_ea_lm_cptr_ea; -__ea char *__lm *__lm *__ea lm_lm_ea_cptr_ea; -__ea char *__ea *__lm *__ea lm_ea_ea_cptr_ea; -__lm char *__lm *__ea *__ea ea_lm_lm_cptr_ea; -__lm char *__ea *__ea *__ea ea_ea_lm_cptr_ea; -__ea char *__lm *__ea *__ea ea_lm_ea_cptr_ea; -__ea char *__ea *__ea *__ea ea_ea_ea_cptr_ea; -#endif -#endif -#endif - -int -main () -{ - PRINT2 ("LEVEL1 = %d\n", LEVEL1); - PRINT2 ("LEVEL2 = %d\n", LEVEL2); - PRINT2 ("LEVEL3 = %d\n", LEVEL3); - PRINT2 ("USE_SIMPLE = %d\n", USE_SIMPLE); - PRINT2 ("USE_COMPLEX = %d\n", USE_COMPLEX); - PRINT2 ("USE_LOCAL_VAR = %d\n", USE_LOCAL_VAR); - PRINT2 ("USE_EA_VAR = %d\n", USE_EA_VAR); - PRINT1 ("\n"); - -#if USE_SIMPLE -#if LEVEL1 -#if USE_LOCAL_VAR - TEST_SIZE ( lm_ptr, 4); - TEST_SIZE (*lm_ptr, 1); - TEST_SIZE ( ea_ptr, EA_PTRSIZE); - TEST_SIZE (*ea_ptr, 1); - PRINT1 ("\n"); -#endif - -#if USE_EA_VAR - TEST_SIZE ( lm_ptr_ea, 4); - TEST_SIZE (*lm_ptr_ea, 1); - TEST_SIZE ( ea_ptr_ea, EA_PTRSIZE); - TEST_SIZE (*ea_ptr_ea, 1); - PRINT1 ("\n"); -#endif -#endif - -#if LEVEL2 -#if USE_LOCAL_VAR - TEST_SIZE ( lm_lm_ptr, 4); - TEST_SIZE ( *lm_lm_ptr, 4); - TEST_SIZE (**lm_lm_ptr, 1); - PRINT1 ("\n"); - - TEST_SIZE ( lm_ea_ptr, 4); - TEST_SIZE ( *lm_ea_ptr, EA_PTRSIZE); - TEST_SIZE (**lm_ea_ptr, 1); - PRINT1 ("\n"); - - TEST_SIZE ( ea_lm_ptr, EA_PTRSIZE); - TEST_SIZE ( *ea_lm_ptr, 4); - TEST_SIZE (**ea_lm_ptr, 1); - PRINT1 ("\n"); - - TEST_SIZE ( ea_ea_ptr, EA_PTRSIZE); - TEST_SIZE ( *ea_ea_ptr, EA_PTRSIZE); - TEST_SIZE (**ea_ea_ptr, 1); - PRINT1 ("\n"); -#endif - -#if USE_EA_VAR - TEST_SIZE ( lm_lm_ptr_ea, 4); - TEST_SIZE ( *lm_lm_ptr_ea, 4); - TEST_SIZE (**lm_lm_ptr_ea, 1); - PRINT1 ("\n"); - - TEST_SIZE ( lm_ea_ptr_ea, 4); - TEST_SIZE ( *lm_ea_ptr_ea, EA_PTRSIZE); - TEST_SIZE (**lm_ea_ptr_ea, 1); - PRINT1 ("\n"); - - TEST_SIZE ( ea_lm_ptr_ea, EA_PTRSIZE); - TEST_SIZE ( *ea_lm_ptr_ea, 4); - TEST_SIZE (**ea_lm_ptr_ea, 1); - PRINT1 ("\n"); - - TEST_SIZE ( ea_ea_ptr_ea, EA_PTRSIZE); - TEST_SIZE ( *ea_ea_ptr_ea, EA_PTRSIZE); - TEST_SIZE (**ea_ea_ptr_ea, 1); - PRINT1 ("\n"); -#endif -#endif - -#if LEVEL3 -#if USE_LOCAL_VAR - TEST_SIZE ( lm_lm_lm_ptr, 4); - TEST_SIZE ( *lm_lm_lm_ptr, 4); - TEST_SIZE ( **lm_lm_lm_ptr, 4); - TEST_SIZE (***lm_lm_lm_ptr, 1); - PRINT1 ("\n"); - - TEST_SIZE ( lm_lm_ea_ptr, 4); - TEST_SIZE ( *lm_lm_ea_ptr, 4); - TEST_SIZE ( **lm_lm_ea_ptr, EA_PTRSIZE); - TEST_SIZE (***lm_lm_ea_ptr, 1); - PRINT1 ("\n"); - - TEST_SIZE ( lm_ea_lm_ptr, 4); - TEST_SIZE ( *lm_ea_lm_ptr, EA_PTRSIZE); - TEST_SIZE ( **lm_ea_lm_ptr, 4); - TEST_SIZE (***lm_ea_lm_ptr, 1); - PRINT1 ("\n"); - - TEST_SIZE ( lm_ea_ea_ptr, 4); - TEST_SIZE ( *lm_ea_ea_ptr, EA_PTRSIZE); - TEST_SIZE ( **lm_ea_ea_ptr, EA_PTRSIZE); - TEST_SIZE (***lm_ea_ea_ptr, 1); - PRINT1 ("\n"); - - TEST_SIZE ( ea_lm_lm_ptr, EA_PTRSIZE); - TEST_SIZE ( *ea_lm_lm_ptr, 4); - TEST_SIZE ( **ea_lm_lm_ptr, 4); - TEST_SIZE (***ea_lm_lm_ptr, 1); - PRINT1 ("\n"); - - TEST_SIZE ( ea_lm_ea_ptr, EA_PTRSIZE); - TEST_SIZE ( *ea_lm_ea_ptr, 4); - TEST_SIZE ( **ea_lm_ea_ptr, EA_PTRSIZE); - TEST_SIZE (***ea_lm_ea_ptr, 1); - PRINT1 ("\n"); - - TEST_SIZE ( ea_ea_lm_ptr, EA_PTRSIZE); - TEST_SIZE ( *ea_ea_lm_ptr, EA_PTRSIZE); - TEST_SIZE ( **ea_ea_lm_ptr, 4); - TEST_SIZE (***ea_ea_lm_ptr, 1); - PRINT1 ("\n"); - - TEST_SIZE ( ea_ea_ea_ptr, EA_PTRSIZE); - TEST_SIZE ( *ea_ea_ea_ptr, EA_PTRSIZE); - TEST_SIZE ( **ea_ea_ea_ptr, EA_PTRSIZE); - TEST_SIZE (***ea_ea_ea_ptr, 1); - PRINT1 ("\n"); -#endif - -#if USE_EA_VAR - TEST_SIZE ( lm_lm_lm_ptr_ea, 4); - TEST_SIZE ( *lm_lm_lm_ptr_ea, 4); - TEST_SIZE ( **lm_lm_lm_ptr_ea, 4); - TEST_SIZE (***lm_lm_lm_ptr_ea, 1); - PRINT1 ("\n"); - - TEST_SIZE ( lm_lm_ea_ptr_ea, 4); - TEST_SIZE ( *lm_lm_ea_ptr_ea, 4); - TEST_SIZE ( **lm_lm_ea_ptr_ea, EA_PTRSIZE); - TEST_SIZE (***lm_lm_ea_ptr_ea, 1); - PRINT1 ("\n"); - - TEST_SIZE ( lm_ea_lm_ptr_ea, 4); - TEST_SIZE ( *lm_ea_lm_ptr_ea, EA_PTRSIZE); - TEST_SIZE ( **lm_ea_lm_ptr_ea, 4); - TEST_SIZE (***lm_ea_lm_ptr_ea, 1); - PRINT1 ("\n"); - - TEST_SIZE ( lm_ea_ea_ptr_ea, 4); - TEST_SIZE ( *lm_ea_ea_ptr_ea, EA_PTRSIZE); - TEST_SIZE ( **lm_ea_ea_ptr_ea, EA_PTRSIZE); - TEST_SIZE (***lm_ea_ea_ptr_ea, 1); - PRINT1 ("\n"); - - TEST_SIZE ( ea_lm_lm_ptr_ea, EA_PTRSIZE); - TEST_SIZE ( *ea_lm_lm_ptr_ea, 4); - TEST_SIZE ( **ea_lm_lm_ptr_ea, 4); - TEST_SIZE (***ea_lm_lm_ptr_ea, 1); - PRINT1 ("\n"); - - TEST_SIZE ( ea_lm_ea_ptr_ea, EA_PTRSIZE); - TEST_SIZE ( *ea_lm_ea_ptr_ea, 4); - TEST_SIZE ( **ea_lm_ea_ptr_ea, EA_PTRSIZE); - TEST_SIZE (***ea_lm_ea_ptr_ea, 1); - PRINT1 ("\n"); - - TEST_SIZE ( ea_ea_lm_ptr_ea, EA_PTRSIZE); - TEST_SIZE ( *ea_ea_lm_ptr_ea, EA_PTRSIZE); - TEST_SIZE ( **ea_ea_lm_ptr_ea, 4); - TEST_SIZE (***ea_ea_lm_ptr_ea, 1); - PRINT1 ("\n"); - - TEST_SIZE ( ea_ea_ea_ptr_ea, EA_PTRSIZE); - TEST_SIZE ( *ea_ea_ea_ptr_ea, EA_PTRSIZE); - TEST_SIZE ( **ea_ea_ea_ptr_ea, EA_PTRSIZE); - TEST_SIZE (***ea_ea_ea_ptr_ea, 1); - PRINT1 ("\n"); -#endif -#endif -#endif - -#if USE_COMPLEX -#if LEVEL1 -#if USE_LOCAL_VAR - TEST_SIZE ( lm_cptr, 4); - TEST_SIZE (*lm_cptr, 1); - TEST_SIZE ( ea_cptr, EA_PTRSIZE); - TEST_SIZE (*ea_cptr, 1); - PRINT1 ("\n"); -#endif - -#if USE_EA_VAR - TEST_SIZE ( lm_cptr_ea, 4); - TEST_SIZE (*lm_cptr_ea, 1); - TEST_SIZE ( ea_cptr_ea, EA_PTRSIZE); - TEST_SIZE (*ea_cptr_ea, 1); - PRINT1 ("\n"); -#endif -#endif - -#if LEVEL2 -#if USE_LOCAL_VAR - TEST_SIZE ( lm_lm_cptr, 4); - TEST_SIZE ( *lm_lm_cptr, 4); - TEST_SIZE (**lm_lm_cptr, 1); - PRINT1 ("\n"); - - TEST_SIZE ( lm_ea_cptr, 4); - TEST_SIZE ( *lm_ea_cptr, EA_PTRSIZE); - TEST_SIZE (**lm_ea_cptr, 1); - PRINT1 ("\n"); - - TEST_SIZE ( ea_lm_cptr, EA_PTRSIZE); - TEST_SIZE ( *ea_lm_cptr, 4); - TEST_SIZE (**ea_lm_cptr, 1); - PRINT1 ("\n"); - - TEST_SIZE ( ea_ea_cptr, EA_PTRSIZE); - TEST_SIZE ( *ea_ea_cptr, EA_PTRSIZE); - TEST_SIZE (**ea_ea_cptr, 1); - PRINT1 ("\n"); -#endif - -#if USE_EA_VAR - TEST_SIZE ( lm_lm_cptr_ea, 4); - TEST_SIZE ( *lm_lm_cptr_ea, 4); - TEST_SIZE (**lm_lm_cptr_ea, 1); - PRINT1 ("\n"); - - TEST_SIZE ( lm_ea_cptr_ea, 4); - TEST_SIZE ( *lm_ea_cptr_ea, EA_PTRSIZE); - TEST_SIZE (**lm_ea_cptr_ea, 1); - PRINT1 ("\n"); - - TEST_SIZE ( ea_lm_cptr_ea, EA_PTRSIZE); - TEST_SIZE ( *ea_lm_cptr_ea, 4); - TEST_SIZE (**ea_lm_cptr_ea, 1); - PRINT1 ("\n"); - - TEST_SIZE ( ea_ea_cptr_ea, EA_PTRSIZE); - TEST_SIZE ( *ea_ea_cptr_ea, EA_PTRSIZE); - TEST_SIZE (**ea_ea_cptr_ea, 1); - PRINT1 ("\n"); -#endif -#endif - -#if LEVEL3 -#if USE_LOCAL_VAR - TEST_SIZE ( lm_lm_lm_cptr, 4); - TEST_SIZE ( *lm_lm_lm_cptr, 4); - TEST_SIZE ( **lm_lm_lm_cptr, 4); - TEST_SIZE (***lm_lm_lm_cptr, 1); - PRINT1 ("\n"); - - TEST_SIZE ( lm_lm_ea_cptr, 4); - TEST_SIZE ( *lm_lm_ea_cptr, 4); - TEST_SIZE ( **lm_lm_ea_cptr, EA_PTRSIZE); - TEST_SIZE (***lm_lm_ea_cptr, 1); - PRINT1 ("\n"); - - TEST_SIZE ( lm_ea_lm_cptr, 4); - TEST_SIZE ( *lm_ea_lm_cptr, EA_PTRSIZE); - TEST_SIZE ( **lm_ea_lm_cptr, 4); - TEST_SIZE (***lm_ea_lm_cptr, 1); - PRINT1 ("\n"); - - TEST_SIZE ( lm_ea_ea_cptr, 4); - TEST_SIZE ( *lm_ea_ea_cptr, EA_PTRSIZE); - TEST_SIZE ( **lm_ea_ea_cptr, EA_PTRSIZE); - TEST_SIZE (***lm_ea_ea_cptr, 1); - PRINT1 ("\n"); - - TEST_SIZE ( ea_lm_lm_cptr, EA_PTRSIZE); - TEST_SIZE ( *ea_lm_lm_cptr, 4); - TEST_SIZE ( **ea_lm_lm_cptr, 4); - TEST_SIZE (***ea_lm_lm_cptr, 1); - PRINT1 ("\n"); - - TEST_SIZE ( ea_lm_ea_cptr, EA_PTRSIZE); - TEST_SIZE ( *ea_lm_ea_cptr, 4); - TEST_SIZE ( **ea_lm_ea_cptr, EA_PTRSIZE); - TEST_SIZE (***ea_lm_ea_cptr, 1); - PRINT1 ("\n"); - - TEST_SIZE ( ea_ea_lm_cptr, EA_PTRSIZE); - TEST_SIZE ( *ea_ea_lm_cptr, EA_PTRSIZE); - TEST_SIZE ( **ea_ea_lm_cptr, 4); - TEST_SIZE (***ea_ea_lm_cptr, 1); - PRINT1 ("\n"); - - TEST_SIZE ( ea_ea_ea_cptr, EA_PTRSIZE); - TEST_SIZE ( *ea_ea_ea_cptr, EA_PTRSIZE); - TEST_SIZE ( **ea_ea_ea_cptr, EA_PTRSIZE); - TEST_SIZE (***ea_ea_ea_cptr, 1); - PRINT1 ("\n"); -#endif - -#if USE_EA_VAR - TEST_SIZE ( lm_lm_lm_cptr_ea, 4); - TEST_SIZE ( *lm_lm_lm_cptr_ea, 4); - TEST_SIZE ( **lm_lm_lm_cptr_ea, 4); - TEST_SIZE (***lm_lm_lm_cptr_ea, 1); - PRINT1 ("\n"); - - TEST_SIZE ( lm_lm_ea_cptr_ea, 4); - TEST_SIZE ( *lm_lm_ea_cptr_ea, 4); - TEST_SIZE ( **lm_lm_ea_cptr_ea, EA_PTRSIZE); - TEST_SIZE (***lm_lm_ea_cptr_ea, 1); - PRINT1 ("\n"); - - TEST_SIZE ( lm_ea_lm_cptr_ea, 4); - TEST_SIZE ( *lm_ea_lm_cptr_ea, EA_PTRSIZE); - TEST_SIZE ( **lm_ea_lm_cptr_ea, 4); - TEST_SIZE (***lm_ea_lm_cptr_ea, 1); - PRINT1 ("\n"); - - TEST_SIZE ( lm_ea_ea_cptr_ea, 4); - TEST_SIZE ( *lm_ea_ea_cptr_ea, EA_PTRSIZE); - TEST_SIZE ( **lm_ea_ea_cptr_ea, EA_PTRSIZE); - TEST_SIZE (***lm_ea_ea_cptr_ea, 1); - PRINT1 ("\n"); - - TEST_SIZE ( ea_lm_lm_cptr_ea, EA_PTRSIZE); - TEST_SIZE ( *ea_lm_lm_cptr_ea, 4); - TEST_SIZE ( **ea_lm_lm_cptr_ea, 4); - TEST_SIZE (***ea_lm_lm_cptr_ea, 1); - PRINT1 ("\n"); - - TEST_SIZE ( ea_lm_ea_cptr_ea, EA_PTRSIZE); - TEST_SIZE ( *ea_lm_ea_cptr_ea, 4); - TEST_SIZE ( **ea_lm_ea_cptr_ea, EA_PTRSIZE); - TEST_SIZE (***ea_lm_ea_cptr_ea, 1); - PRINT1 ("\n"); - - TEST_SIZE ( ea_ea_lm_cptr_ea, EA_PTRSIZE); - TEST_SIZE ( *ea_ea_lm_cptr_ea, EA_PTRSIZE); - TEST_SIZE ( **ea_ea_lm_cptr_ea, 4); - TEST_SIZE (***ea_ea_lm_cptr_ea, 1); - PRINT1 ("\n"); - - TEST_SIZE ( ea_ea_ea_cptr_ea, EA_PTRSIZE); - TEST_SIZE ( *ea_ea_ea_cptr_ea, EA_PTRSIZE); - TEST_SIZE ( **ea_ea_ea_cptr_ea, EA_PTRSIZE); - TEST_SIZE (***ea_ea_ea_cptr_ea, 1); - PRINT1 ("\n"); -#endif -#endif -#endif - - if (errors) - { - PRINT3 ("%d error(s), %d test(s)\n", errors, num_tests); - abort (); - } - else - PRINT2 ("No errors, %d test(s)\n", num_tests); - - return 0; -} diff --git a/gcc/testsuite/gcc.target/spu/fixed-range-bad.c b/gcc/testsuite/gcc.target/spu/fixed-range-bad.c deleted file mode 100644 index 0993283..0000000 --- a/gcc/testsuite/gcc.target/spu/fixed-range-bad.c +++ /dev/null @@ -1,5 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-mfixed-range=1-x" } */ -/* { dg-warning "unknown register name" "" { target spu-*-* } 0 } */ - -int i; diff --git a/gcc/testsuite/gcc.target/spu/fixed-range.c b/gcc/testsuite/gcc.target/spu/fixed-range.c deleted file mode 100644 index 8dcb7fe..0000000 --- a/gcc/testsuite/gcc.target/spu/fixed-range.c +++ /dev/null @@ -1,8 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-mfixed-range=1-20" } */ -/* { dg-final { scan-assembler "lqd.*21" } } */ - -int foo (int i) -{ - return i; -} diff --git a/gcc/testsuite/gcc.target/spu/intrinsics-1.c b/gcc/testsuite/gcc.target/spu/intrinsics-1.c deleted file mode 100644 index b8974f6..0000000 --- a/gcc/testsuite/gcc.target/spu/intrinsics-1.c +++ /dev/null @@ -1,24 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-std=c99 -pedantic-errors" } */ -#include -/* With this intrinsics section, we used to ICE as we would try - to convert from an vector to an integer type. */ -void f(void) -{ - vec_uint4 gt, N; - vec_int4 a; - int *a1; - _Complex double b; - gt = spu_cmpgt(a, N); /* { dg-error "parameter list" } */ - - gt = spu_cmpgt(a, a1); /* { dg-error "integer from pointer without a cast" } */ - /* { dg-message "note: expected 'int'" "" { target *-*-* } .-1 } */ - - gt = spu_cmpgt(a, b); /* { dg-error "parameter list" } */ - - gt = spu_cmpgt(a, a); - - a = spu_cmpgt(a, a); - /* { dg-message "note: use -flax-vector-conversions to permit conversions between vectors with differing element types or numbers of subparts" "" { target *-*-* } .-1 } */ - /* { dg-error "incompatible types when assigning" "" { target *-*-* } .-2 } */ -} diff --git a/gcc/testsuite/gcc.target/spu/intrinsics-2.c b/gcc/testsuite/gcc.target/spu/intrinsics-2.c deleted file mode 100644 index 43a272b..0000000 --- a/gcc/testsuite/gcc.target/spu/intrinsics-2.c +++ /dev/null @@ -1,305 +0,0 @@ -/* { dg-do run } */ -/* { dg-options "-std=c99" } */ -#include -extern void abort (void); -extern void exit (int); - -typedef union { - vec_ullong2 vull; - vec_double2 vd; - unsigned int ui[4]; - unsigned long long ull[2]; - double d[2]; -} v128; - -static v128 a, b, c, d, a0, b0, a1, b1; -static int samples = 10; -unsigned int seed = 0; - -unsigned int rand_local() -{ - seed = seed * 69607 + 54329; - return (seed); -} - -double rand_double(double min, double max) -{ - union { - unsigned int ui[2]; - double d; - } x; - - x.ui[0] = (rand_local() & 0x000FFFFF) | 0x3FF00000; - x.ui[1] = rand_local(); - x.d -= 1.0; - x.d *= max - min; - x.d += min; - return (x.d); -} - -vec_double2 rand_vd(double min, double max) -{ - int i; - static v128 val; - - for (i=0; i<2; i++) val.d[i] = rand_double(min, max); - return (val.vd); -} - -int test_spu_cmpeq() -{ - int i, j; - unsigned long long exp; - - /* double */ - for (i=0; i b.d[j]) ? - (((unsigned long long)(0xFFFFFFFF) << 32) - | (unsigned long long)(0xFFFFFFFF)) : 0; - if (exp != d.ull[j]) abort(); - } - } - - /* compare zeros */ - d.vull = spu_cmpgt(a0.vd, b0.vd); - for (j=0; j<2; j++) { - exp = (a0.d[j] > b0.d[j]) ? - (((unsigned long long)(0xFFFFFFFF) << 32) - | (unsigned long long)(0xFFFFFFFF)) : 0; - if (exp != d.ull[j]) abort(); - } - /* compare NaNs */ - d.vull = spu_cmpgt(a1.vd, b1.vd); - for (j=0; j<2; j++) { - exp = (a1.d[j] > b1.d[j]) ? - (((unsigned long long)(0xFFFFFFFF) << 32) - | (unsigned long long)(0xFFFFFFFF)) : 0; - if (exp != d.ull[j]) abort(); - } - return 0; -} - -int test_spu_cmpabseq() -{ - int i, j; - unsigned long long exp; - - /* double */ - for (i=0; i abs_b) ? - (((unsigned long long)(0xFFFFFFFF) << 32) - | (unsigned long long)(0xFFFFFFFF)) : 0; - if (exp != d.ull[j]) abort(); - } - } - - /* compare zeros */ - d.vull = spu_cmpabsgt(a0.vd, b0.vd); - for (j=0; j<2; j++) { - abs_a = (a0.d[j] < 0.0) ? -a0.d[j] : a0.d[j]; - abs_b = (b0.d[j] < 0.0) ? -b0.d[j] : b0.d[j]; - exp = (abs_a > abs_b) ? - (((unsigned long long)(0xFFFFFFFF) << 32) - | (unsigned long long)(0xFFFFFFFF)) : 0; - if (exp != d.ull[j]) abort(); - } - /* compare NaNs */ - d.vull = spu_cmpabsgt(a1.vd, b1.vd); - for (j=0; j<2; j++) { - abs_a = (a1.d[j] < 0.0) ? -a1.d[j] : a1.d[j]; - abs_b = (b1.d[j] < 0.0) ? -b1.d[j] : b1.d[j]; - exp = (abs_a > abs_b) ? - (((unsigned long long)(0xFFFFFFFF) << 32) - | (unsigned long long)(0xFFFFFFFF)) : 0; - if (exp != d.ull[j]) abort(); - } - return 0; -} - -int test_spu_testsv() -{ - int i, j; - unsigned long long exp; - struct _samples { - unsigned long long v; - unsigned int sv; - } samples[] = { - {0x0000000000000000ULL, SPU_SV_POS_ZERO}, - {0x8000000000000000ULL, SPU_SV_NEG_ZERO}, - {0x0000000000000001ULL, SPU_SV_POS_DENORM}, - {0x0000000080000000ULL, SPU_SV_POS_DENORM}, - {0x0000000100000000ULL, SPU_SV_POS_DENORM}, - {0x0008000000000000ULL, SPU_SV_POS_DENORM}, - {0x000FFFFFFFFFFFFFULL, SPU_SV_POS_DENORM}, - {0x00000000FFF00000ULL, SPU_SV_POS_DENORM}, - {0x8000000000000001ULL, SPU_SV_NEG_DENORM}, - {0x8000000080000000ULL, SPU_SV_NEG_DENORM}, - {0x8000000100000000ULL, SPU_SV_NEG_DENORM}, - {0x8008000000000000ULL, SPU_SV_NEG_DENORM}, - {0x800FFFFFFFFFFFFFULL, SPU_SV_NEG_DENORM}, - {0x80000000FFF00000ULL, SPU_SV_NEG_DENORM}, - {0x0010000000000000ULL, 0}, - {0x0010000000000001ULL, 0}, - {0x3FF0000000000000ULL, 0}, - {0x3FF00000FFF00000ULL, 0}, - {0xBFF0000000000000ULL, 0}, - {0xBFF00000FFF00000ULL, 0}, - {0x7FE0000000000000ULL, 0}, - {0x7FEFFFFFFFFFFFFFULL, 0}, - {0x8010000000000000ULL, 0}, - {0x8010000000000001ULL, 0}, - {0xFFE0000000000000ULL, 0}, - {0xFFEFFFFFFFFFFFFFULL, 0}, - {0x7FF0000000000000ULL, SPU_SV_POS_INFINITY}, - {0xFFF0000000000000ULL, SPU_SV_NEG_INFINITY}, - {0x7FF0000000000001ULL, SPU_SV_NAN}, - {0x7FF0000080000000ULL, SPU_SV_NAN}, - {0x7FF0000100000000ULL, SPU_SV_NAN}, - {0x7FFFFFFFFFFFFFFFULL, SPU_SV_NAN}, - {0xFFF0000000000001ULL, SPU_SV_NAN}, - {0xFFF0000080000000ULL, SPU_SV_NAN}, - {0xFFF0000100000000ULL, SPU_SV_NAN}, - {0xFFFFFFFFFFFFFFFFULL, SPU_SV_NAN} - }; - - unsigned char cnt = sizeof(samples)/sizeof(struct _samples); - int e0; - for (e0=0; e0 -void f0 (vec_uint4 *in) -{ - vec_float4 out = spu_convtf (in[0], 128); /* { dg-error "expects an integer literal in the range" "0, 127" }*/ -} - -void f1 (vec_int4 *in) -{ - vec_float4 out = spu_convtf (in[0], 128); /* { dg-error "expects an integer literal in the range" "0, 127" }*/ -} - -void f2 (vec_float4 *in) -{ - vec_int4 out = spu_convts (in[0], 128); /* { dg-error "expects an integer literal in the range" "0, 127" }*/ -} - -void f3 (vec_float4 *in) -{ - vec_uint4 out = spu_convtu (in[0], 128); /* { dg-error "expects an integer literal in the range" "0, 127" }*/ -} - -/* Test that these intrinsics accept non-literal arguments */ -void f4 (vec_uint4 *in, int n) -{ - vec_float4 out = spu_convtf (in[0], n); -} - -void f5 (vec_int4 *in, int n) -{ - vec_float4 out = spu_convtf (in[0], n); -} - -void f6 (vec_float4 *in, int n) -{ - vec_int4 out = spu_convts (in[0], n); -} - -void f7 (vec_float4 *in, int n) -{ - vec_uint4 out = spu_convtu (in[0], n); -} diff --git a/gcc/testsuite/gcc.target/spu/intrinsics-sr.c b/gcc/testsuite/gcc.target/spu/intrinsics-sr.c deleted file mode 100644 index f7c62dd..0000000 --- a/gcc/testsuite/gcc.target/spu/intrinsics-sr.c +++ /dev/null @@ -1,496 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-std=c99" } */ - -#include - -/* spu_sr */ - -vector unsigned short test_sr_1 (vector unsigned short ra, vector unsigned short count) -{ - return spu_sr (ra, count); -} - -vector signed short test_sr_2 (vector signed short ra, vector unsigned short count) -{ - return spu_sr (ra, count); -} - -vector unsigned int test_sr_3 (vector unsigned int ra, vector unsigned int count) -{ - return spu_sr (ra, count); -} - -vector signed int test_sr_4 (vector signed int ra, vector unsigned int count) -{ - return spu_sr (ra, count); -} - -vector unsigned short test_sr_5 (vector unsigned short ra) -{ - return spu_sr (ra, 11); -} - -vector signed short test_sr_6 (vector signed short ra) -{ - return spu_sr (ra, 11); -} - -vector unsigned short test_sr_7 (vector unsigned short ra, unsigned int count) -{ - return spu_sr (ra, count); -} - -vector signed short test_sr_8 (vector signed short ra, unsigned int count) -{ - return spu_sr (ra, count); -} - -vector unsigned int test_sr_9 (vector unsigned int ra) -{ - return spu_sr (ra, 11); -} - -vector signed int test_sr_10 (vector signed int ra) -{ - return spu_sr (ra, 11); -} - -vector unsigned int test_sr_11 (vector unsigned int ra, unsigned int count) -{ - return spu_sr (ra, count); -} - -vector signed int test_sr_12 (vector signed int ra, unsigned int count) -{ - return spu_sr (ra, count); -} - - -/* spu_sra */ - -vector unsigned short test_sra_1 (vector unsigned short ra, vector unsigned short count) -{ - return spu_sra (ra, count); -} - -vector signed short test_sra_2 (vector signed short ra, vector unsigned short count) -{ - return spu_sra (ra, count); -} - -vector unsigned int test_sra_3 (vector unsigned int ra, vector unsigned int count) -{ - return spu_sra (ra, count); -} - -vector signed int test_sra_4 (vector signed int ra, vector unsigned int count) -{ - return spu_sra (ra, count); -} - -vector unsigned short test_sra_5 (vector unsigned short ra) -{ - return spu_sra (ra, 11); -} - -vector signed short test_sra_6 (vector signed short ra) -{ - return spu_sra (ra, 11); -} - -vector unsigned short test_sra_7 (vector unsigned short ra, unsigned int count) -{ - return spu_sra (ra, count); -} - -vector signed short test_sra_8 (vector signed short ra, unsigned int count) -{ - return spu_sra (ra, count); -} - -vector unsigned int test_sra_9 (vector unsigned int ra) -{ - return spu_sra (ra, 11); -} - -vector signed int test_sra_10 (vector signed int ra) -{ - return spu_sra (ra, 11); -} - -vector unsigned int test_sra_11 (vector unsigned int ra, unsigned int count) -{ - return spu_sra (ra, count); -} - -vector signed int test_sra_12 (vector signed int ra, unsigned int count) -{ - return spu_sra (ra, count); -} - -/* spu_srqw */ - -vector unsigned char test_srqw_1 (vector unsigned char ra) -{ - return spu_srqw (ra, 5); -} - -vector signed char test_srqw_2 (vector signed char ra) -{ - return spu_srqw (ra, 5); -} - -vector unsigned short test_srqw_3 (vector unsigned short ra) -{ - return spu_srqw (ra, 5); -} - -vector signed short test_srqw_4 (vector signed short ra) -{ - return spu_srqw (ra, 5); -} - -vector unsigned int test_srqw_5 (vector unsigned int ra) -{ - return spu_srqw (ra, 5); -} - -vector signed int test_srqw_6 (vector signed int ra) -{ - return spu_srqw (ra, 5); -} - -vector unsigned long test_srqw_7 (vector unsigned long ra) -{ - return spu_srqw (ra, 5); -} - -vector signed long test_srqw_8 (vector signed long ra) -{ - return spu_srqw (ra, 5); -} - -vector unsigned long long test_srqw_9 (vector unsigned long long ra) -{ - return spu_srqw (ra, 5); -} - -vector signed long long test_srqw_10 (vector signed long long ra) -{ - return spu_srqw (ra, 5); -} - -vector float test_srqw_11 (vector float ra) -{ - return spu_srqw (ra, 5); -} - -vector double test_srqw_12 (vector double ra) -{ - return spu_srqw (ra, 5); -} - -vector unsigned char test_srqw_13 (vector unsigned char ra, unsigned int count) -{ - return spu_srqw (ra, count); -} - -vector signed char test_srqw_14 (vector signed char ra, unsigned int count) -{ - return spu_srqw (ra, count); -} - -vector unsigned short test_srqw_15 (vector unsigned short ra, unsigned int count) -{ - return spu_srqw (ra, count); -} - -vector signed short test_srqw_16 (vector signed short ra, unsigned int count) -{ - return spu_srqw (ra, count); -} - -vector unsigned int test_srqw_17 (vector unsigned int ra, unsigned int count) -{ - return spu_srqw (ra, count); -} - -vector signed int test_srqw_18 (vector signed int ra, unsigned int count) -{ - return spu_srqw (ra, count); -} - -vector unsigned long test_srqw_19 (vector unsigned long ra, unsigned int count) -{ - return spu_srqw (ra, count); -} - -vector signed long test_srqw_20 (vector signed long ra, unsigned int count) -{ - return spu_srqw (ra, count); -} - -vector unsigned long long test_srqw_21 (vector unsigned long long ra, unsigned int count) -{ - return spu_srqw (ra, count); -} - -vector signed long long test_srqw_22 (vector signed long long ra, unsigned int count) -{ - return spu_srqw (ra, count); -} - -vector float test_srqw_23 (vector float ra, unsigned int count) -{ - return spu_srqw (ra, count); -} - -vector double test_srqw_24 (vector double ra, unsigned int count) -{ - return spu_srqw (ra, count); -} - -/* spu_srqwbyte */ - -vector unsigned char test_srqwbyte_1 (vector unsigned char ra) -{ - return spu_srqwbyte (ra, 5); -} - -vector signed char test_srqwbyte_2 (vector signed char ra) -{ - return spu_srqwbyte (ra, 5); -} - -vector unsigned short test_srqwbyte_3 (vector unsigned short ra) -{ - return spu_srqwbyte (ra, 5); -} - -vector signed short test_srqwbyte_4 (vector signed short ra) -{ - return spu_srqwbyte (ra, 5); -} - -vector unsigned int test_srqwbyte_5 (vector unsigned int ra) -{ - return spu_srqwbyte (ra, 5); -} - -vector signed int test_srqwbyte_6 (vector signed int ra) -{ - return spu_srqwbyte (ra, 5); -} - -vector unsigned long test_srqwbyte_7 (vector unsigned long ra) -{ - return spu_srqwbyte (ra, 5); -} - -vector signed long test_srqwbyte_8 (vector signed long ra) -{ - return spu_srqwbyte (ra, 5); -} - -vector unsigned long long test_srqwbyte_9 (vector unsigned long long ra) -{ - return spu_srqwbyte (ra, 5); -} - -vector signed long long test_srqwbyte_10 (vector signed long long ra) -{ - return spu_srqwbyte (ra, 5); -} - -vector float test_srqwbyte_11 (vector float ra) -{ - return spu_srqwbyte (ra, 5); -} - -vector double test_srqwbyte_12 (vector double ra) -{ - return spu_srqwbyte (ra, 5); -} - -vector unsigned char test_srqwbyte_13 (vector unsigned char ra, unsigned int count) -{ - return spu_srqwbyte (ra, count); -} - -vector signed char test_srqwbyte_14 (vector signed char ra, unsigned int count) -{ - return spu_srqwbyte (ra, count); -} - -vector unsigned short test_srqwbyte_15 (vector unsigned short ra, unsigned int count) -{ - return spu_srqwbyte (ra, count); -} - -vector signed short test_srqwbyte_16 (vector signed short ra, unsigned int count) -{ - return spu_srqwbyte (ra, count); -} - -vector unsigned int test_srqwbyte_17 (vector unsigned int ra, unsigned int count) -{ - return spu_srqwbyte (ra, count); -} - -vector signed int test_srqwbyte_18 (vector signed int ra, unsigned int count) -{ - return spu_srqwbyte (ra, count); -} - -vector unsigned long test_srqwbyte_19 (vector unsigned long ra, unsigned int count) -{ - return spu_srqwbyte (ra, count); -} - -vector signed long test_srqwbyte_20 (vector signed long ra, unsigned int count) -{ - return spu_srqwbyte (ra, count); -} - -vector unsigned long long test_srqwbyte_21 (vector unsigned long long ra, unsigned int count) -{ - return spu_srqwbyte (ra, count); -} - -vector signed long long test_srqwbyte_22 (vector signed long long ra, unsigned int count) -{ - return spu_srqwbyte (ra, count); -} - -vector float test_srqwbyte_23 (vector float ra, unsigned int count) -{ - return spu_srqwbyte (ra, count); -} - -vector double test_srqwbyte_24 (vector double ra, unsigned int count) -{ - return spu_srqwbyte (ra, count); -} - -/* spu_srqwbytebc */ - -vector unsigned char test_srqwbytebc_1 (vector unsigned char ra) -{ - return spu_srqwbytebc (ra, 40); -} - -vector signed char test_srqwbytebc_2 (vector signed char ra) -{ - return spu_srqwbytebc (ra, 40); -} - -vector unsigned short test_srqwbytebc_3 (vector unsigned short ra) -{ - return spu_srqwbytebc (ra, 40); -} - -vector signed short test_srqwbytebc_4 (vector signed short ra) -{ - return spu_srqwbytebc (ra, 40); -} - -vector unsigned int test_srqwbytebc_5 (vector unsigned int ra) -{ - return spu_srqwbytebc (ra, 40); -} - -vector signed int test_srqwbytebc_6 (vector signed int ra) -{ - return spu_srqwbytebc (ra, 40); -} - -vector unsigned long test_srqwbytebc_7 (vector unsigned long ra) -{ - return spu_srqwbytebc (ra, 40); -} - -vector signed long test_srqwbytebc_8 (vector signed long ra) -{ - return spu_srqwbytebc (ra, 40); -} - -vector unsigned long long test_srqwbytebc_9 (vector unsigned long long ra) -{ - return spu_srqwbytebc (ra, 40); -} - -vector signed long long test_srqwbytebc_10 (vector signed long long ra) -{ - return spu_srqwbytebc (ra, 40); -} - -vector float test_srqwbytebc_11 (vector float ra) -{ - return spu_srqwbytebc (ra, 40); -} - -vector double test_srqwbytebc_12 (vector double ra) -{ - return spu_srqwbytebc (ra, 40); -} - -vector unsigned char test_srqwbytebc_13 (vector unsigned char ra, unsigned int count) -{ - return spu_srqwbytebc (ra, count); -} - -vector signed char test_srqwbytebc_14 (vector signed char ra, unsigned int count) -{ - return spu_srqwbytebc (ra, count); -} - -vector unsigned short test_srqwbytebc_15 (vector unsigned short ra, unsigned int count) -{ - return spu_srqwbytebc (ra, count); -} - -vector signed short test_srqwbytebc_16 (vector signed short ra, unsigned int count) -{ - return spu_srqwbytebc (ra, count); -} - -vector unsigned int test_srqwbytebc_17 (vector unsigned int ra, unsigned int count) -{ - return spu_srqwbytebc (ra, count); -} - -vector signed int test_srqwbytebc_18 (vector signed int ra, unsigned int count) -{ - return spu_srqwbytebc (ra, count); -} - -vector unsigned long test_srqwbytebc_19 (vector unsigned long ra, unsigned int count) -{ - return spu_srqwbytebc (ra, count); -} - -vector signed long test_srqwbytebc_20 (vector signed long ra, unsigned int count) -{ - return spu_srqwbytebc (ra, count); -} - -vector unsigned long long test_srqwbytebc_21 (vector unsigned long long ra, unsigned int count) -{ - return spu_srqwbytebc (ra, count); -} - -vector signed long long test_srqwbytebc_22 (vector signed long long ra, unsigned int count) -{ - return spu_srqwbytebc (ra, count); -} - -vector float test_srqwbytebc_23 (vector float ra, unsigned int count) -{ - return spu_srqwbytebc (ra, count); -} - -vector double test_srqwbytebc_24 (vector double ra, unsigned int count) -{ - return spu_srqwbytebc (ra, count); -} - diff --git a/gcc/testsuite/gcc.target/spu/muldivti3.c b/gcc/testsuite/gcc.target/spu/muldivti3.c deleted file mode 100644 index 0363e34..0000000 --- a/gcc/testsuite/gcc.target/spu/muldivti3.c +++ /dev/null @@ -1,46 +0,0 @@ -/* { dg-do run } */ -/* { dg-options "-std=c99" } */ -#include -typedef unsigned int uqword __attribute__((mode(TI))); -typedef int qword __attribute__((mode(TI))); - -typedef union -{ - uqword uq; - qword q; - unsigned long long ull[2]; -} u; - -int main(void) -{ - uqword e, f; - qword g, h; - - e = 0x1111111111111111ULL; - f = 0xFULL; - g = 0x0000000000111100ULL; - h = 0x0000000000000000ULL; - - u m, n, o, p, q; - - m.ull[0] = f; - m.ull[1] = e; - n.ull[0] = h; - n.ull[1] = g; - - /* __multi3 */ - o.q = m.q * n.q; - - o.q = o.q + n.q + 0x1110FF; - /* __udivti3, __umodti3 */ - p.uq = o.uq / n.uq; - q.uq = o.uq % n.uq; - if (p.uq != (m.uq+1)) abort(); - if (q.uq != 0x1110FF) abort(); - /* __divti3, __modti3 */ - p.q = -o.q / n.q; - q.q = -o.q % n.q; - if ((-p.q * n.q - q.q) != o.q) abort(); - - return 0; -} diff --git a/gcc/testsuite/gcc.target/spu/pr40001.c b/gcc/testsuite/gcc.target/spu/pr40001.c deleted file mode 100644 index 442f72d..0000000 --- a/gcc/testsuite/gcc.target/spu/pr40001.c +++ /dev/null @@ -1,17 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O" } */ - -void * -sbrk (unsigned int increment) -{ - volatile register - __attribute__ ((__spu_vector__)) unsigned int sp_r1 __asm__ ("1"); - unsigned int sps; - - sps = __builtin_spu_extract (sp_r1, 0); - if (sps - 4096 >= increment) - return 0; - else - return ((void *) -1); -} - diff --git a/gcc/testsuite/gcc.target/spu/spu.exp b/gcc/testsuite/gcc.target/spu/spu.exp deleted file mode 100644 index 79ef5b8..0000000 --- a/gcc/testsuite/gcc.target/spu/spu.exp +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright (C) 2005-2019 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# . - -# GCC testsuite that uses the 'dg.exp' driver. - -# Exit immediately if this isn't a SPU target. -if { ![istarget spu-*-*] } then { - return -} - -# Load support procs. -load_lib gcc-dg.exp - -# If a testcase doesn't have special options, use these. -global DEFAULT_CFLAGS -if ![info exists DEFAULT_CFLAGS] then { - set DEFAULT_CFLAGS " -ansi -pedantic-errors" -} - -# Initialize 'dg'. -dg-init - -# Main loop. -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \ - "" $DEFAULT_CFLAGS - -# All done. -dg-finish diff --git a/gcc/testsuite/gcc.target/spu/subti3.c b/gcc/testsuite/gcc.target/spu/subti3.c deleted file mode 100644 index 4112c95..0000000 --- a/gcc/testsuite/gcc.target/spu/subti3.c +++ /dev/null @@ -1,45 +0,0 @@ -/* { dg-do run } */ -/* { dg-options "-std=c99" } */ -#include -typedef int TItype __attribute__ ((mode (TI))); -typedef int DItype __attribute__ ((mode (DI))); -typedef unsigned int UDItype __attribute__ ((mode (DI))); - -struct DIstruct {DItype high, low;}; -typedef union -{ - struct DIstruct s; - TItype t; -} TIunion; - -static -void sub_ddmmss (UDItype *sh, UDItype *sl, UDItype ah, UDItype al, UDItype bh, UDItype bl) -{ - UDItype x; - x = al - bl; - *sh = ah - bh - (x > al); - *sl = x; -} - -int main(void) -{ - TIunion aa, bb, cc; - TItype m = 0x1111111111111110ULL; - TItype n = 0x1111111111111111ULL; - TItype d; - - aa.s.high = m; - aa.s.low = m; - bb.s.high = n; - bb.s.low = n; - - - sub_ddmmss (&cc.s.high, &cc.s.low, aa.s.high, aa.s.low, bb.s.high, bb.s.low); - d = aa.t - bb.t; - if (d != cc.t) - abort(); - cc.t = aa.t -d; - if (cc.t != bb.t) - abort(); - return 0; -} diff --git a/gcc/testsuite/gcc.target/spu/tag_manager.c b/gcc/testsuite/gcc.target/spu/tag_manager.c deleted file mode 100644 index 4b3ab9f..0000000 --- a/gcc/testsuite/gcc.target/spu/tag_manager.c +++ /dev/null @@ -1,312 +0,0 @@ -/* Copyright (C) 2007, 2009 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with this file; see the file COPYING3. If not see - . */ - -/* { dg-do run } */ - -#include -#include - -/* This test directly accesses the internal table used - by the MFC tag manager. */ -extern vector unsigned int __mfc_tag_table; - - -/* This tag tests invalid tag release. Invalid tag release does - nothing to the tag table. */ -void -test_tag_release01 (void) -{ - unsigned int copy; - copy = spu_extract (__mfc_tag_table, 0); - - mfc_tag_release (35); - if (copy != spu_extract (__mfc_tag_table, 0)) - abort (); -} - -/* More invalid release tests. */ -void -test_tag_release_invalid (void) -{ - unsigned int copy; - copy = spu_extract (__mfc_tag_table, 0); - - if (mfc_tag_release (32) != MFC_TAG_INVALID) - abort (); - if (copy != spu_extract (__mfc_tag_table, 0)) - abort (); - - if (mfc_tag_release (17) != MFC_TAG_INVALID) - abort (); - if (copy != spu_extract (__mfc_tag_table, 0)) - abort (); -} - -/* Invalid multiple-tag release tests. */ -void -test_tag_group_release_invalid (void) -{ - unsigned int copy; - copy = spu_extract (__mfc_tag_table, 0); - - if (mfc_multi_tag_release (32, 10) != MFC_TAG_INVALID) - abort (); - if (copy != spu_extract (__mfc_tag_table, 0)) - abort (); - - if (mfc_multi_tag_release (28, 10) != MFC_TAG_INVALID) - abort (); - if (copy != spu_extract (__mfc_tag_table, 0)) - abort (); - - if (mfc_multi_tag_release (17, 10) != MFC_TAG_INVALID) - abort (); - if (copy != spu_extract (__mfc_tag_table, 0)) - abort (); - - if (mfc_multi_tag_release (32, 10) != MFC_TAG_INVALID) - abort (); - if (copy != spu_extract (__mfc_tag_table, 0)) - abort (); -} - -/* The tag table should be in a pristine mode to run this test. */ -void -test_tag_reserve01 (void) -{ - unsigned int correct_table[32] = - { - 0x80000000, 0xC0000000, 0xE0000000, - 0xF0000000, 0xF8000000, 0xFC000000, 0xFE000000, - 0xFF000000, 0xFF800000, 0xFFC00000, 0xFFE00000, - 0xFFF00000, 0xFFF80000, 0xFFFC0000, 0xFFFE0000, - 0xFFFF0000, 0xFFFF8000, 0xFFFFC000, 0xFFFFE000, - 0xFFFFF000, 0xFFFFF800, 0xFFFFFC00, 0xFFFFFE00, - 0xFFFFFF00, 0xFFFFFF80, 0xFFFFFFC0, 0xFFFFFFE0, - 0xFFFFFFF0, 0xFFFFFFF8, 0xFFFFFFFC, 0xFFFFFFFE, - 0xFFFFFFFF - }; - - unsigned int tag; - unsigned int i; - - for (i = 0; i < 32; i++) - { - tag = mfc_tag_reserve (); - if (tag != i) - abort (); - } - - for (i = 0; i < 32; i++) - { - tag = mfc_tag_reserve (); - if (tag != MFC_TAG_INVALID) - abort (); - } - - for (i = 0; i < 32; i++) - { - mfc_tag_release (i); - if (spu_extract (__mfc_tag_table, 0) != correct_table[i]) - abort (); - } -} - -/* The tag table should be in a pristine mode to run this test. */ -void -test_tag_reserve02 (void) -{ - unsigned int correct_table[32] = - { - 0x80000000, 0xC0000000, 0xA0000000, 0xF0000000, - 0xA8000000, 0xFC000000, 0xAA000000, 0xFF000000, - 0xAA800000, 0xFFC00000, 0xAAA00000, 0xFFF00000, - 0xAAA80000, 0xFFFC0000, 0xAAAA0000, 0xFFFF0000, - 0xAAAA8000, 0xFFFFC000, 0xAAAAA000, 0xFFFFF000, - 0xAAAAA800, 0xFFFFFC00, 0xAAAAAA00, 0xFFFFFF00, - 0xAAAAAA80, 0xFFFFFFC0, 0xAAAAAAA0, 0xFFFFFFF0, - 0xAAAAAAA8, 0xFFFFFFFC, 0xAAAAAAAA, 0xFFFFFFFF - }; - - unsigned int correct_table2[32] = - { - 0x80000000, 0xEAAAAAAA, 0xA0000000, 0xFAAAAAAA, - 0xA8000000, 0xFEAAAAAA, 0xAA000000, 0xFFAAAAAA, - 0xAA800000, 0xFFEAAAAA, 0xAAA00000, 0xFFFAAAAA, - 0xAAA80000, 0xFFFEAAAA, 0xAAAA0000, 0xFFFFAAAA, - 0xAAAA8000, 0xFFFFEAAA, 0xAAAAA000, 0xFFFFFAAA, - 0xAAAAA800, 0xFFFFFEAA, 0xAAAAAA00, 0xFFFFFFAA, - 0xAAAAAA80, 0xFFFFFFEA, 0xAAAAAAA0, 0xFFFFFFFA, - 0xAAAAAAA8, 0xFFFFFFFE, 0xAAAAAAAA, 0xFFFFFFFF - }; - - unsigned int tag; - unsigned int i; - - /* Reserve all 32 tags. */ - for (i = 0; i < 32; i++) - { - tag = mfc_tag_reserve(); - if (tag != i) - abort (); - } - - for (i = 0; i < 32; i++) - { - tag = mfc_tag_reserve(); - if (tag != MFC_TAG_INVALID) - abort (); - } - - /* Release only 16 tags with a stride of 2. */ - for (i = 0; i < 32; i += 2) - { - mfc_tag_release (i); - if (spu_extract (__mfc_tag_table, 0) != correct_table[i]) - abort (); - } - - /* Release the other 16 tags with a stride of 2. */ - for (i = 1; i < 32; i += 2) - { - mfc_tag_release (i); - if (spu_extract (__mfc_tag_table, 0) != correct_table2[i]) - abort (); - } -} - -/* The tag table should be in a pristine mode to run this test. */ -void -test_tag_reserve03 (void) -{ - unsigned int tag; - unsigned int i; - - /* Reserve all 32 tags. */ - for (i = 0; i < 32; i++) - { - tag = mfc_tag_reserve (); - if (tag != i) - abort (); - } - - for (i = 0; i < 32; i++) - { - tag = mfc_tag_reserve (); - if (tag != MFC_TAG_INVALID) - abort (); - } - - /* Release only 16 tags with a stride of 2. */ - for (i = 0; i < 32; i += 2) - mfc_tag_release (i); - - /* Now let's re-reserve those tags. */ - for (i = 0; i < 32; i += 2) - { - tag = mfc_tag_reserve (); - if (tag != i) - abort (); - } - - /* Release all tags. */ - for (i = 0; i < 32; i++) - mfc_tag_release (i); - - if (spu_extract (__mfc_tag_table,0) != 0xFFFFFFFF) - abort (); -} - - -void -test_tag_group_reserve (void) -{ - unsigned int tag; - unsigned int i; - unsigned int copy; - - /* Reserve all tags. */ - for (i = 0; i < 32; i++) - mfc_tag_reserve(); - - /* Release the first 4. */ - for (i = 0; i < 4; i++) - mfc_tag_release (i); - - /* Release tag 5 to 7. */ - for (i = 5; i < 8; i++) - mfc_tag_release (i); - - /* Release tag 9 to 19. */ - for (i = 9; i < 20; i++) - mfc_tag_release (i); - - /* Tag table should be 0xF77FF000. */ - if (spu_extract (__mfc_tag_table, 0) != 0xF77FF000) - abort (); - - - /* Verify invalid release is detected. */ - copy = spu_extract (__mfc_tag_table, 0); - if (mfc_multi_tag_release (1, 5) != MFC_TAG_INVALID) - abort (); - if (copy != spu_extract (__mfc_tag_table, 0)) - abort (); - - - /* Reserve multiple tags. */ - tag = mfc_multi_tag_reserve (5); - if (tag != 9) - abort (); - - /* Tag table should be 0xF703F000. */ - if (spu_extract (__mfc_tag_table, 0) != 0xF703F000) - abort (); - - - /* Release 5 tags in the group. */ - mfc_multi_tag_release (tag, 5); - - /* Tag table should be 0xF77FF000. */ - if (spu_extract (__mfc_tag_table, 0) != 0xF77FF000) - abort (); - - - /* This call should not do anything. */ - mfc_multi_tag_release (32, 5); - - /* Tag table should be 0xF77FF000. */ - if (spu_extract (__mfc_tag_table, 0) != 0xF77FF000) - abort (); -} - - -int -main (void) -{ - test_tag_release01 (); - test_tag_release_invalid (); - test_tag_group_release_invalid (); - - test_tag_reserve01 (); - test_tag_reserve02 (); - test_tag_reserve03 (); - - test_tag_group_reserve (); - - return 0; -} - diff --git a/gcc/testsuite/gcc.target/spu/vector-ansi.c b/gcc/testsuite/gcc.target/spu/vector-ansi.c deleted file mode 100644 index 3c08616..0000000 --- a/gcc/testsuite/gcc.target/spu/vector-ansi.c +++ /dev/null @@ -1,35 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-ansi" } */ - -/* This is done by spu_internals.h, but we not include it here to keep - down the dependencies. */ - -#ifndef __VECTOR_KEYWORD_SUPPORTED__ -#define vector __vector -#endif - -/* __vector is expanded unconditionally by the preprocessor. */ -__vector int vi; -__vector unsigned char vuc; -__vector signed char vsc; -__vector unsigned short vus; -__vector signed short vss; -__vector unsigned int vui; -__vector signed int vsi; -__vector unsigned long long ull; -__vector signed long long sll; -__vector float vf; -__vector double vd; - -/* vector is expanded by the define above, regardless of context. */ -vector int vi; -vector unsigned char vuc; -vector signed char vsc; -vector unsigned short vus; -vector signed short vss; -vector unsigned int vui; -vector signed int vsi; -vector unsigned long long ull; -vector signed long long sll; -vector float vf; -vector double vd; diff --git a/gcc/testsuite/gcc.target/spu/vector.c b/gcc/testsuite/gcc.target/spu/vector.c deleted file mode 100644 index 237f93b..0000000 --- a/gcc/testsuite/gcc.target/spu/vector.c +++ /dev/null @@ -1,32 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "" } */ - -#ifndef __VECTOR_KEYWORD_SUPPORTED__ -#error __VECTOR_KEYWORD_SUPPORTED__ is not defined -#endif - -/* __vector is expanded unconditionally. */ -__vector int vi; -__vector unsigned char vuc; -__vector signed char vsc; -__vector unsigned short vus; -__vector signed short vss; -__vector unsigned int vui; -__vector signed int vsi; -__vector unsigned long long ull; -__vector signed long long sll; -__vector float vf; -__vector double vd; - -/* vector is expanded conditionally, based on the context. */ -vector int vi; -vector unsigned char vuc; -vector signed char vsc; -vector unsigned short vus; -vector signed short vss; -vector unsigned int vui; -vector signed int vsi; -vector unsigned long long ull; -vector signed long long sll; -vector float vf; -vector double vd; diff --git a/gcc/testsuite/gfortran.dg/bessel_6.f90 b/gcc/testsuite/gfortran.dg/bessel_6.f90 index e2336a2..07ce13c 100644 --- a/gcc/testsuite/gfortran.dg/bessel_6.f90 +++ b/gcc/testsuite/gfortran.dg/bessel_6.f90 @@ -1,12 +1,8 @@ -! { dg-do run { xfail spu-*-* } } ! { dg-add-options ieee } ! ! PR fortran/36158 ! PR fortran/33197 ! -! XFAILed for SPU targets since we don't have an accurate library -! implementation of the single-precision Bessel functions. -! ! Run-time tests for transformations BESSEL_JN ! implicit none diff --git a/gcc/testsuite/gfortran.dg/bessel_7.f90 b/gcc/testsuite/gfortran.dg/bessel_7.f90 index 16bb484..1937976 100644 --- a/gcc/testsuite/gfortran.dg/bessel_7.f90 +++ b/gcc/testsuite/gfortran.dg/bessel_7.f90 @@ -1,4 +1,4 @@ -! { dg-do run { xfail *-*-mingw* spu-*-* } } +! { dg-do run { xfail *-*-mingw* } } ! { dg-add-options ieee } ! ! PR fortran/36158 @@ -8,9 +8,6 @@ ! of BESSEL_YN(n,x) has different results. It returns NAN rather than ! -INF for "x=0.0" and all "n". ! -! XFAILed for SPU targets since we don't have an accurate library -! implementation of the single-precision Bessel functions. -! ! Run-time tests for transformations BESSEL_YN ! implicit none diff --git a/gcc/testsuite/gfortran.dg/char4_iunit_1.f03 b/gcc/testsuite/gfortran.dg/char4_iunit_1.f03 index eaa2bd8..92c7bec 100644 --- a/gcc/testsuite/gfortran.dg/char4_iunit_1.f03 +++ b/gcc/testsuite/gfortran.dg/char4_iunit_1.f03 @@ -1,6 +1,5 @@ ! { dg-do run } ! { dg-add-options ieee } -! { dg-skip-if "NaN not supported" { spu-*-* } } ! PR37077 Implement Internal Unit I/O for character KIND=4 ! Test case prepared by Jerry DeLisle program char4_iunit_1 diff --git a/gcc/testsuite/gfortran.dg/chmod_1.f90 b/gcc/testsuite/gfortran.dg/chmod_1.f90 index 7aeeaaa..8e50adb 100644 --- a/gcc/testsuite/gfortran.dg/chmod_1.f90 +++ b/gcc/testsuite/gfortran.dg/chmod_1.f90 @@ -1,4 +1,4 @@ -! { dg-do run { target { ! { *-*-mingw* *-*-cygwin* spu-*-* } } } } +! { dg-do run { target { ! { *-*-mingw* *-*-cygwin* } } } } ! { dg-options "-std=gnu" } ! See PR38956. Test fails on cygwin when user has Administrator rights implicit none diff --git a/gcc/testsuite/gfortran.dg/chmod_2.f90 b/gcc/testsuite/gfortran.dg/chmod_2.f90 index 176879d..faed62b 100644 --- a/gcc/testsuite/gfortran.dg/chmod_2.f90 +++ b/gcc/testsuite/gfortran.dg/chmod_2.f90 @@ -1,4 +1,4 @@ -! { dg-do run { target { ! { *-*-mingw* *-*-cygwin* spu-*-* } } } } +! { dg-do run { target { ! { *-*-mingw* *-*-cygwin* } } } } ! { dg-options "-std=gnu" } ! See PR38956. Test fails on cygwin when user has Administrator rights implicit none diff --git a/gcc/testsuite/gfortran.dg/chmod_3.f90 b/gcc/testsuite/gfortran.dg/chmod_3.f90 index 3528acd..81425b3 100644 --- a/gcc/testsuite/gfortran.dg/chmod_3.f90 +++ b/gcc/testsuite/gfortran.dg/chmod_3.f90 @@ -1,4 +1,4 @@ -! { dg-do run { target { ! { *-*-mingw* *-*-cygwin* spu-*-* } } } } +! { dg-do run { target { ! { *-*-mingw* *-*-cygwin* } } } } ! { dg-options "-std=gnu -fdefault-integer-8" } ! See PR38956. Test fails on cygwin when user has Administrator rights implicit none diff --git a/gcc/testsuite/gfortran.dg/default_format_1.f90 b/gcc/testsuite/gfortran.dg/default_format_1.f90 index 9f88d3f..cafda89 100644 --- a/gcc/testsuite/gfortran.dg/default_format_1.f90 +++ b/gcc/testsuite/gfortran.dg/default_format_1.f90 @@ -1,4 +1,4 @@ -! { dg-do run { xfail spu-*-* powerpc-ibm-aix* } } +! { dg-do run { xfail powerpc-ibm-aix* } } ! Test XFAILed on Darwin because the system's printf() lacks ! proper support for denormals. ! diff --git a/gcc/testsuite/gfortran.dg/default_format_denormal_1.f90 b/gcc/testsuite/gfortran.dg/default_format_denormal_1.f90 index 3b76757..6ae79a3 100644 --- a/gcc/testsuite/gfortran.dg/default_format_denormal_1.f90 +++ b/gcc/testsuite/gfortran.dg/default_format_denormal_1.f90 @@ -1,4 +1,4 @@ -! { dg-do run { xfail *-*-darwin[89]* *-*-cygwin* spu-*-* powerpc-ibm-aix* } } +! { dg-do run { xfail *-*-darwin[89]* *-*-cygwin* powerpc-ibm-aix* } } ! Test XFAILed on these platforms because the system's printf() lacks ! proper support for denormals. ! diff --git a/gcc/testsuite/gfortran.dg/erf_2.F90 b/gcc/testsuite/gfortran.dg/erf_2.F90 index e9fd99a..87c99a9 100644 --- a/gcc/testsuite/gfortran.dg/erf_2.F90 +++ b/gcc/testsuite/gfortran.dg/erf_2.F90 @@ -1,10 +1,6 @@ -! { dg-do run { xfail spu-*-* } } ! { dg-options "-fno-range-check -ffree-line-length-none -O0" } ! { dg-add-options ieee } ! -! XFAILed for SPU targets because our library implementation of -! the double-precision erf/erfc functions is not accurate enough. -! ! Check that simplification functions and runtime library agree on ERF, ! ERFC and ERFC_SCALED. diff --git a/gcc/testsuite/gfortran.dg/erf_3.F90 b/gcc/testsuite/gfortran.dg/erf_3.F90 index 8c287e8..69ac843 100644 --- a/gcc/testsuite/gfortran.dg/erf_3.F90 +++ b/gcc/testsuite/gfortran.dg/erf_3.F90 @@ -1,4 +1,4 @@ -! { dg-do run { xfail spu-*-* ia64-*-linux* } } +! { dg-do run { xfail ia64-*-linux* } } ! { dg-options "-fno-range-check -ffree-line-length-none -O0" } ! { dg-add-options ieee } ! { dg-skip-if "PR libfortran/59313" { hppa*-*-hpux* } } @@ -6,9 +6,6 @@ ! Check that simplification functions and runtime library agree on ERF, ! ERFC and ERFC_SCALED, for quadruple-precision. ! -! XFAILed for SPU targets because our library implementation of -! the double-precision erf/erfc functions is not accurate enough. -! ! XFAILed for IA64 Linux because of a glibc bug: ! http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59227 diff --git a/gcc/testsuite/gfortran.dg/init_flag_10.f90 b/gcc/testsuite/gfortran.dg/init_flag_10.f90 index 6478245..49b75f9 100644 --- a/gcc/testsuite/gfortran.dg/init_flag_10.f90 +++ b/gcc/testsuite/gfortran.dg/init_flag_10.f90 @@ -1,7 +1,6 @@ ! { dg-do run } ! { dg-options "-finit-real=NAN" } ! { dg-add-options ieee } -! { dg-skip-if "NaN not supported" { spu-*-* } } ! ! PR fortran/50619 ! diff --git a/gcc/testsuite/gfortran.dg/init_flag_3.f90 b/gcc/testsuite/gfortran.dg/init_flag_3.f90 index 1efde30..6c466a9 100644 --- a/gcc/testsuite/gfortran.dg/init_flag_3.f90 +++ b/gcc/testsuite/gfortran.dg/init_flag_3.f90 @@ -1,7 +1,6 @@ ! { dg-do run } ! { dg-options "-finit-integer=-1 -finit-logical=false -finit-real=nan" } ! { dg-add-options ieee } -! { dg-skip-if "NaN not supported" { spu-*-* } } program init_flag_3 call real_test diff --git a/gcc/testsuite/gfortran.dg/int_conv_2.f90 b/gcc/testsuite/gfortran.dg/int_conv_2.f90 index c6fc00b..ce5f5a2 100644 --- a/gcc/testsuite/gfortran.dg/int_conv_2.f90 +++ b/gcc/testsuite/gfortran.dg/int_conv_2.f90 @@ -1,5 +1,4 @@ ! { dg-do compile } -! { dg-skip-if "NaN not supported" { spu-*-* } } ! PR fortran/37930 program test implicit none diff --git a/gcc/testsuite/gfortran.dg/integer_exponentiation_3.F90 b/gcc/testsuite/gfortran.dg/integer_exponentiation_3.F90 index fe1f3a8..f73d691 100644 --- a/gcc/testsuite/gfortran.dg/integer_exponentiation_3.F90 +++ b/gcc/testsuite/gfortran.dg/integer_exponentiation_3.F90 @@ -1,5 +1,3 @@ -! { dg-do run { xfail spu-*-* } } -! FAILs on SPU because of wrong compile-time rounding mode ! { dg-options "" } ! { dg-options "-ffloat-store" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } ! diff --git a/gcc/testsuite/gfortran.dg/integer_exponentiation_5.F90 b/gcc/testsuite/gfortran.dg/integer_exponentiation_5.F90 index f16b751..f34a457 100644 --- a/gcc/testsuite/gfortran.dg/integer_exponentiation_5.F90 +++ b/gcc/testsuite/gfortran.dg/integer_exponentiation_5.F90 @@ -1,5 +1,3 @@ -! { dg-do run { xfail spu-*-* } } -! FAILs on SPU because of invalid result of 1.0/0.0 inline code ! { dg-options "-fno-range-check" } ! { dg-add-options ieee } module mod_check diff --git a/gcc/testsuite/gfortran.dg/isnan_1.f90 b/gcc/testsuite/gfortran.dg/isnan_1.f90 index fe77bf47..e9506c2 100644 --- a/gcc/testsuite/gfortran.dg/isnan_1.f90 +++ b/gcc/testsuite/gfortran.dg/isnan_1.f90 @@ -2,7 +2,6 @@ ! ! { dg-do run } ! { dg-add-options ieee } -! { dg-skip-if "NaN not supported" { spu-*-* } } ! implicit none real :: x diff --git a/gcc/testsuite/gfortran.dg/isnan_2.f90 b/gcc/testsuite/gfortran.dg/isnan_2.f90 index c52affb..672e564 100644 --- a/gcc/testsuite/gfortran.dg/isnan_2.f90 +++ b/gcc/testsuite/gfortran.dg/isnan_2.f90 @@ -3,7 +3,6 @@ ! { dg-do run } ! { dg-options "-fno-range-check" } ! { dg-add-options ieee } -! { dg-skip-if "NaN not supported" { spu-*-* } } ! implicit none character(len=1) :: s diff --git a/gcc/testsuite/gfortran.dg/maxloc_2.f90 b/gcc/testsuite/gfortran.dg/maxloc_2.f90 index 00318e8..d9d3100 100644 --- a/gcc/testsuite/gfortran.dg/maxloc_2.f90 +++ b/gcc/testsuite/gfortran.dg/maxloc_2.f90 @@ -1,6 +1,5 @@ ! { dg-do run } ! { dg-add-options ieee } -! { dg-skip-if "NaN not supported" { spu-*-* } } real :: a(3), nan, minf, pinf real, allocatable :: c(:) integer :: ia(1) diff --git a/gcc/testsuite/gfortran.dg/maxlocval_2.f90 b/gcc/testsuite/gfortran.dg/maxlocval_2.f90 index ee69a6e..724b607 100644 --- a/gcc/testsuite/gfortran.dg/maxlocval_2.f90 +++ b/gcc/testsuite/gfortran.dg/maxlocval_2.f90 @@ -1,6 +1,5 @@ ! { dg-do run } ! { dg-add-options ieee } -! { dg-skip-if "NaN not supported" { spu-*-* } } real :: a(3), nan, minf, pinf real, allocatable :: c(:) logical :: l diff --git a/gcc/testsuite/gfortran.dg/maxlocval_4.f90 b/gcc/testsuite/gfortran.dg/maxlocval_4.f90 index 67fd8e7..f8f90fd 100644 --- a/gcc/testsuite/gfortran.dg/maxlocval_4.f90 +++ b/gcc/testsuite/gfortran.dg/maxlocval_4.f90 @@ -1,6 +1,5 @@ ! { dg-do run } ! { dg-add-options ieee } -! { dg-skip-if "NaN not supported" { spu-*-* } } real :: a(3,3), b(3), nan, minf, pinf, h logical :: l, l2 logical :: l3(3,3), l4(3,3), l5(3,3) diff --git a/gcc/testsuite/gfortran.dg/minloc_1.f90 b/gcc/testsuite/gfortran.dg/minloc_1.f90 index fe12cae..6418df4 100644 --- a/gcc/testsuite/gfortran.dg/minloc_1.f90 +++ b/gcc/testsuite/gfortran.dg/minloc_1.f90 @@ -1,6 +1,5 @@ ! { dg-do run } ! { dg-add-options ieee } -! { dg-skip-if "NaN not supported" { spu-*-* } } real :: a(3), nan, minf, pinf integer :: ia(1) real, allocatable :: c(:) diff --git a/gcc/testsuite/gfortran.dg/minlocval_1.f90 b/gcc/testsuite/gfortran.dg/minlocval_1.f90 index 8d8f8af..822e4da 100644 --- a/gcc/testsuite/gfortran.dg/minlocval_1.f90 +++ b/gcc/testsuite/gfortran.dg/minlocval_1.f90 @@ -1,6 +1,5 @@ ! { dg-do run } ! { dg-add-options ieee } -! { dg-skip-if "NaN not supported" { spu-*-* } } real :: a(3), nan, minf, pinf real, allocatable :: c(:) logical :: l diff --git a/gcc/testsuite/gfortran.dg/minlocval_4.f90 b/gcc/testsuite/gfortran.dg/minlocval_4.f90 index b06910c..12b5fa7e 100644 --- a/gcc/testsuite/gfortran.dg/minlocval_4.f90 +++ b/gcc/testsuite/gfortran.dg/minlocval_4.f90 @@ -1,6 +1,5 @@ ! { dg-do run } ! { dg-add-options ieee } -! { dg-skip-if "NaN not supported" { spu-*-* } } real :: a(3,3), b(3), nan, minf, pinf, h logical :: l, l2 logical :: l3(3,3), l4(3,3), l5(3,3) diff --git a/gcc/testsuite/gfortran.dg/module_nan.f90 b/gcc/testsuite/gfortran.dg/module_nan.f90 index 81d3784..4b7cd9a 100644 --- a/gcc/testsuite/gfortran.dg/module_nan.f90 +++ b/gcc/testsuite/gfortran.dg/module_nan.f90 @@ -1,7 +1,6 @@ ! { dg-do run } ! { dg-options "-fno-range-check" } ! { dg-add-options ieee } -! { dg-skip-if "NaN not supported" { spu-*-* } } ! ! PR fortran/34318 ! diff --git a/gcc/testsuite/gfortran.dg/namelist_42.f90 b/gcc/testsuite/gfortran.dg/namelist_42.f90 index ea98307..d4a6e71 100644 --- a/gcc/testsuite/gfortran.dg/namelist_42.f90 +++ b/gcc/testsuite/gfortran.dg/namelist_42.f90 @@ -1,6 +1,5 @@ ! { dg-do run { target fd_truncate } } ! { dg-add-options ieee } -! { dg-skip-if "NaN not supported" { spu-*-* } } ! ! PR fortran/34427 ! diff --git a/gcc/testsuite/gfortran.dg/namelist_43.f90 b/gcc/testsuite/gfortran.dg/namelist_43.f90 index a9304f3..0eead9c 100644 --- a/gcc/testsuite/gfortran.dg/namelist_43.f90 +++ b/gcc/testsuite/gfortran.dg/namelist_43.f90 @@ -1,6 +1,5 @@ ! { dg-do run } ! { dg-add-options ieee } -! { dg-skip-if "NaN not supported" { spu-*-* } } ! ! PR fortran/34427 ! diff --git a/gcc/testsuite/gfortran.dg/nan_1.f90 b/gcc/testsuite/gfortran.dg/nan_1.f90 index 1b39cc1..6d49a6f 100644 --- a/gcc/testsuite/gfortran.dg/nan_1.f90 +++ b/gcc/testsuite/gfortran.dg/nan_1.f90 @@ -3,7 +3,6 @@ ! ! { dg-do run } ! { dg-add-options ieee } -! { dg-skip-if "NaN not supported" { spu-*-* } } ! module aux2 interface isnan diff --git a/gcc/testsuite/gfortran.dg/nan_2.f90 b/gcc/testsuite/gfortran.dg/nan_2.f90 index 7c7a8da..e0270a1 100644 --- a/gcc/testsuite/gfortran.dg/nan_2.f90 +++ b/gcc/testsuite/gfortran.dg/nan_2.f90 @@ -1,7 +1,6 @@ ! { dg-do run } ! { dg-options "-fno-range-check -pedantic" } ! { dg-add-options ieee } -! { dg-skip-if "NaN not supported" { spu-*-* } } ! ! PR fortran/34333 ! diff --git a/gcc/testsuite/gfortran.dg/nan_3.f90 b/gcc/testsuite/gfortran.dg/nan_3.f90 index 97b6fef..feb19a8 100644 --- a/gcc/testsuite/gfortran.dg/nan_3.f90 +++ b/gcc/testsuite/gfortran.dg/nan_3.f90 @@ -1,7 +1,6 @@ ! { dg-do run } ! { dg-options "-fno-range-check" } ! { dg-add-options ieee } -! { dg-skip-if "NaN not supported" { spu-*-* } } ! ! PR fortran/34319 ! diff --git a/gcc/testsuite/gfortran.dg/nan_4.f90 b/gcc/testsuite/gfortran.dg/nan_4.f90 index b4c1f71..0821b0f 100644 --- a/gcc/testsuite/gfortran.dg/nan_4.f90 +++ b/gcc/testsuite/gfortran.dg/nan_4.f90 @@ -1,7 +1,6 @@ ! { dg-do compile } ! { dg-options "-std=gnu -fallow-invalid-boz" } ! { dg-add-options ieee } -! { dg-skip-if "NaN not supported" { spu-*-* } } ! ! PR fortran/34398. ! diff --git a/gcc/testsuite/gfortran.dg/nan_5.f90 b/gcc/testsuite/gfortran.dg/nan_5.f90 index af77090..fcfc1b1 100644 --- a/gcc/testsuite/gfortran.dg/nan_5.f90 +++ b/gcc/testsuite/gfortran.dg/nan_5.f90 @@ -4,7 +4,6 @@ ! ! { dg-options "-fno-range-check" } ! { dg-add-options ieee } -! { dg-skip-if "NaN not supported" { spu-*-* } } implicit none real, parameter :: inf = 2 * huge(inf) diff --git a/gcc/testsuite/gfortran.dg/nan_6.f90 b/gcc/testsuite/gfortran.dg/nan_6.f90 index 7cd20c2..d03cc27 100644 --- a/gcc/testsuite/gfortran.dg/nan_6.f90 +++ b/gcc/testsuite/gfortran.dg/nan_6.f90 @@ -1,6 +1,5 @@ ! { dg-do run } ! { dg-add-options ieee } -! { dg-skip-if "NaN not supported" { spu-*-* } } ! ! List-directed part of PR fortran/43298 ! and follow up to PR fortran/34319. diff --git a/gcc/testsuite/gfortran.dg/nearest_1.f90 b/gcc/testsuite/gfortran.dg/nearest_1.f90 index 4be1195..4ba589c 100644 --- a/gcc/testsuite/gfortran.dg/nearest_1.f90 +++ b/gcc/testsuite/gfortran.dg/nearest_1.f90 @@ -1,7 +1,6 @@ ! { dg-do run } ! { dg-options "-O0 -ffloat-store" } ! { dg-add-options ieee } -! { dg-skip-if "Denormals not supported" { spu-*-* } } ! PR fortran/27021 ! Original code submitted by Dominique d'Humieres ! Converted to Dejagnu for the testsuite by Steven G. Kargl diff --git a/gcc/testsuite/gfortran.dg/nearest_3.f90 b/gcc/testsuite/gfortran.dg/nearest_3.f90 index d7d8b4f..68ec930 100644 --- a/gcc/testsuite/gfortran.dg/nearest_3.f90 +++ b/gcc/testsuite/gfortran.dg/nearest_3.f90 @@ -1,6 +1,5 @@ ! { dg-do run } ! { dg-add-options ieee } -! { dg-skip-if "NaN not supported" { spu-*-* } } ! ! PR fortran/34209 ! diff --git a/gcc/testsuite/gfortran.dg/open_errors.f90 b/gcc/testsuite/gfortran.dg/open_errors.f90 index f964338..838fad8 100644 --- a/gcc/testsuite/gfortran.dg/open_errors.f90 +++ b/gcc/testsuite/gfortran.dg/open_errors.f90 @@ -1,4 +1,4 @@ -! { dg-do run { target { ! { *-*-mingw* *-*-cygwin* spu-*-* } } } } +! { dg-do run { target { ! { *-*-mingw* *-*-cygwin* } } } } ! PR30005 Enhanced error messages for OPEN ! Submitted by Jerry DeLisle ! See PR38956. Test fails on cygwin when user has Administrator rights diff --git a/gcc/testsuite/gfortran.dg/pr20257.f90 b/gcc/testsuite/gfortran.dg/pr20257.f90 index 03108b9..3808829 100644 --- a/gcc/testsuite/gfortran.dg/pr20257.f90 +++ b/gcc/testsuite/gfortran.dg/pr20257.f90 @@ -1,5 +1,4 @@ ! { dg-do run } -! { dg-skip-if "Too big for local store" { spu-*-* } } integer,parameter :: n = 10000 real(8) array(10000) diff --git a/gcc/testsuite/gfortran.dg/read_infnan_1.f90 b/gcc/testsuite/gfortran.dg/read_infnan_1.f90 index 09a3382..97f8267 100644 --- a/gcc/testsuite/gfortran.dg/read_infnan_1.f90 +++ b/gcc/testsuite/gfortran.dg/read_infnan_1.f90 @@ -1,6 +1,5 @@ ! { dg-do run } ! { dg-add-options ieee } -! { dg-skip-if "NaN not supported" { spu-*-* } } ! PR43298 Fortran library does not read in NaN, NaN(), -Inf, or Inf diff --git a/gcc/testsuite/gfortran.dg/real_const_3.f90 b/gcc/testsuite/gfortran.dg/real_const_3.f90 index 58e589f..8811632 100644 --- a/gcc/testsuite/gfortran.dg/real_const_3.f90 +++ b/gcc/testsuite/gfortran.dg/real_const_3.f90 @@ -1,7 +1,6 @@ !{ dg-do run } !{ dg-options "-fno-range-check" } !{ dg-add-options ieee } -!{ dg-skip-if "NaN not supported" { spu-*-* } } ! PR19310 and PR19904, allow disabling range check during compile. ! Contributed by Jerry DeLisle program main diff --git a/gcc/testsuite/gfortran.dg/realloc_on_assign_2.f03 b/gcc/testsuite/gfortran.dg/realloc_on_assign_2.f03 index 43c49b5..4e7c419 100644 --- a/gcc/testsuite/gfortran.dg/realloc_on_assign_2.f03 +++ b/gcc/testsuite/gfortran.dg/realloc_on_assign_2.f03 @@ -1,5 +1,4 @@ ! { dg-do run } -! { dg-skip-if "Too big for local store" { spu-*-* } } ! Tests the patch that implements F2003 automatic allocation and ! reallocation of allocatable arrays on assignment. The tests ! below were generated in the final stages of the development of diff --git a/gcc/testsuite/gfortran.dg/reassoc_4.f b/gcc/testsuite/gfortran.dg/reassoc_4.f index 07b4aff..fdcb46e 100644 --- a/gcc/testsuite/gfortran.dg/reassoc_4.f +++ b/gcc/testsuite/gfortran.dg/reassoc_4.f @@ -1,6 +1,5 @@ ! { dg-do compile } ! { dg-options "-O3 -ffast-math -fdump-tree-reassoc1 --param max-completely-peeled-insns=200" } -! { dg-additional-options "--param max-completely-peel-times=16" { target spu-*-* } } subroutine anisonl(w,vo,anisox,s,ii1,jj1,weight) integer ii1,jj1,i1,iii1,j1,jjj1,k1,l1,m1,n1 real*8 w(3,3),vo(3,3),anisox(3,3,3,3),s(60,60),weight diff --git a/gcc/testsuite/gfortran.dg/scalar_mask_2.f90 b/gcc/testsuite/gfortran.dg/scalar_mask_2.f90 index 0a91434..075e2cf 100644 --- a/gcc/testsuite/gfortran.dg/scalar_mask_2.f90 +++ b/gcc/testsuite/gfortran.dg/scalar_mask_2.f90 @@ -1,5 +1,4 @@ -! { dg-do run { xfail spu-*-* } } -! FAILs on SPU because of rounding error reading kinds.h +! { dg-do run } program main ! Test scalar masks for different intrinsics. real, dimension(2,2) :: a diff --git a/gcc/testsuite/gfortran.dg/scratch_1.f90 b/gcc/testsuite/gfortran.dg/scratch_1.f90 index a1762fc..1547bfe 100644 --- a/gcc/testsuite/gfortran.dg/scratch_1.f90 +++ b/gcc/testsuite/gfortran.dg/scratch_1.f90 @@ -1,5 +1,4 @@ ! { dg-do run } -! { dg-skip-if "Too big for local store" { spu-*-* } } ! Check that we can open more than 26 scratch files concurrently integer :: i do i = 1, 30 diff --git a/gcc/testsuite/gfortran.dg/stat_1.f90 b/gcc/testsuite/gfortran.dg/stat_1.f90 index a170393..5c66e0d 100644 --- a/gcc/testsuite/gfortran.dg/stat_1.f90 +++ b/gcc/testsuite/gfortran.dg/stat_1.f90 @@ -1,5 +1,5 @@ ! { dg-do run } -! { dg-skip-if "" { *-*-mingw* spu-*-* } } +! { dg-skip-if "" { *-*-mingw* } } ! { dg-options "-std=gnu" } character(len=*), parameter :: f = "testfile_stat_1" integer :: s1(13), r1, s2(13), r2, s3(13), r3, d(13), rd diff --git a/gcc/testsuite/gfortran.dg/stat_2.f90 b/gcc/testsuite/gfortran.dg/stat_2.f90 index 32563cb..841d33d 100644 --- a/gcc/testsuite/gfortran.dg/stat_2.f90 +++ b/gcc/testsuite/gfortran.dg/stat_2.f90 @@ -1,5 +1,5 @@ ! { dg-do run } -! { dg-skip-if "" { *-*-mingw* spu-*-* } } +! { dg-skip-if "" { *-*-mingw* } } ! { dg-options "-std=gnu" } character(len=*), parameter :: f = "testfile_stat_2" integer :: s1(13), r1, s2(13), r2, s3(13), r3, d(13), rd diff --git a/gcc/testsuite/gfortran.dg/transfer_simplify_1.f90 b/gcc/testsuite/gfortran.dg/transfer_simplify_1.f90 index b62aad4..e5d4e1a 100644 --- a/gcc/testsuite/gfortran.dg/transfer_simplify_1.f90 +++ b/gcc/testsuite/gfortran.dg/transfer_simplify_1.f90 @@ -1,6 +1,5 @@ ! { dg-do run } ! { dg-options "-O2" } -! { dg-skip-if "NaN not supported" { spu-*-* } } ! Tests that the PRs caused by the lack of gfc_simplify_transfer are ! now fixed. These were brought together in the meta-bug PR31237 ! (TRANSFER intrinsic). diff --git a/gcc/testsuite/gfortran.dg/typebound_operator_9.f03 b/gcc/testsuite/gfortran.dg/typebound_operator_9.f03 index 0757ecf..0967f94 100644 --- a/gcc/testsuite/gfortran.dg/typebound_operator_9.f03 +++ b/gcc/testsuite/gfortran.dg/typebound_operator_9.f03 @@ -1,6 +1,5 @@ ! { dg-do run } ! { dg-add-options ieee } -! { dg-skip-if "Too big for local store" { spu-*-* } } ! ! Solve a diffusion problem using an object-oriented approach ! diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/getarg_1.x b/gcc/testsuite/gfortran.fortran-torture/execute/getarg_1.x deleted file mode 100644 index 6356b43..0000000 --- a/gcc/testsuite/gfortran.fortran-torture/execute/getarg_1.x +++ /dev/null @@ -1,5 +0,0 @@ -if [istarget "spu-*-*"] { - # We need -mstdmain to enable argument processing on SPU. - lappend additional_flags "-mstdmain" -} -return 0 diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_nearest.x b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_nearest.x index ec00f03..8ad5a79 100644 --- a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_nearest.x +++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_nearest.x @@ -1,7 +1,3 @@ -if [istarget "spu-*-*"] { - # No Inf/NaN support on SPU. - return 1 -} if [istarget "powerpc-ibm-aix*"] { # z'7f7fffff' value not preserved by lfs instruction. return 1 diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_set_exponent.x b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_set_exponent.x index e49cd40..dad399d 100644 --- a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_set_exponent.x +++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_set_exponent.x @@ -1,6 +1,2 @@ -if [istarget "spu-*-*"] { - # No denormal support on SPU. - return 1 -} add-ieee-options return 0 diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/nan_inf_fmt.x b/gcc/testsuite/gfortran.fortran-torture/execute/nan_inf_fmt.x index 2d2b6ee..dad399d 100644 --- a/gcc/testsuite/gfortran.fortran-torture/execute/nan_inf_fmt.x +++ b/gcc/testsuite/gfortran.fortran-torture/execute/nan_inf_fmt.x @@ -1,6 +1,2 @@ -if [istarget "spu-*-*"] { - # No Inf/NaN support on SPU. - return 1 -} add-ieee-options return 0 diff --git a/gcc/testsuite/lib/compat.exp b/gcc/testsuite/lib/compat.exp index 45296e5..d8e902b 100644 --- a/gcc/testsuite/lib/compat.exp +++ b/gcc/testsuite/lib/compat.exp @@ -277,16 +277,6 @@ proc compat-execute { src1 sid use_alt } { set extra_flags_3 [compat-get-options $src3] set compile_xfail_3 $compiler_conditional_xfail_data - # On the SPU, most of the compat test cases exceed local store size. - # Use automatic overlay support to make them fit. - if { [check_effective_target_spu_auto_overlay] } { - set extra_flags_1 "$extra_flags_1 -Wl,--auto-overlay" - set extra_flags_1 "$extra_flags_1 -Wl,--extra-stack-space=8192" - set extra_flags_1 "$extra_flags_1 -ffunction-sections" - set extra_flags_2 "$extra_flags_2 -ffunction-sections" - set extra_flags_3 "$extra_flags_3 -ffunction-sections" - } - # Define the names of the object files. regsub "sid" "sid_main_tst.o" $sid obj1 regsub "sid" "sid_x_tst.o" $sid obj2_tst diff --git a/gcc/testsuite/lib/fortran-torture.exp b/gcc/testsuite/lib/fortran-torture.exp index f55fb1f..1dcc147 100644 --- a/gcc/testsuite/lib/fortran-torture.exp +++ b/gcc/testsuite/lib/fortran-torture.exp @@ -44,8 +44,6 @@ proc get-fortran-torture-options { } { && [check_vmx_hw_available] } { lappend vectorizer_options "-maltivec" set test_tree_vectorize 1 - } elseif { [istarget spu-*-*] } { - set test_tree_vectorize 1 } elseif { ( [istarget i?86-*-*] || [istarget x86_64-*-*] ) && [check_effective_target_sse2] && [check_sse2_hw_available] diff --git a/gcc/testsuite/lib/gcc-dg.exp b/gcc/testsuite/lib/gcc-dg.exp index e23b63c..88fe666 100644 --- a/gcc/testsuite/lib/gcc-dg.exp +++ b/gcc/testsuite/lib/gcc-dg.exp @@ -414,14 +414,6 @@ proc gcc-dg-prune { system text } { return "::unsupported::memory full" } - # Likewise, if we see ".text exceeds local store range" or - # similar. - if {[string match "spu-*" $system] && \ - [string match "*exceeds local store*" $text]} { - # The format here is important. See dg.exp. - return "::unsupported::memory full" - } - if { [string match "*error: function pointers not supported*" $text] && ![check_effective_target_function_pointers] } { # The format here is important. See dg.exp. diff --git a/gcc/testsuite/lib/gfortran.exp b/gcc/testsuite/lib/gfortran.exp index 387e865..1e80e1f 100644 --- a/gcc/testsuite/lib/gfortran.exp +++ b/gcc/testsuite/lib/gfortran.exp @@ -220,13 +220,6 @@ proc gfortran_init { args } { lappend ALWAYS_GFORTRANFLAGS "additional_flags=$TOOL_OPTIONS" } - # On the SPU, most of the fortran test cases exceed local store size. - # Use automatic overlay support to make them fit. - if { [check_effective_target_spu_auto_overlay] } { - lappend ALWAYS_GFORTRANFLAGS "ldflags=-Wl,--auto-overlay" - lappend ALWAYS_GFORTRANFLAGS "ldflags=-Wl,--reserved-space=131072" - } - verbose -log "ALWAYS_GFORTRANFLAGS set to $ALWAYS_GFORTRANFLAGS" verbose "gfortran is initialized" 3 diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 739321a..e32d424 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -3173,7 +3173,6 @@ proc check_effective_target_vect_cmdline_needed { } { && ([check_effective_target_powerpc_spe] || [check_effective_target_powerpc_altivec])) || ([istarget sparc*-*-*] && [check_effective_target_sparc_vis]) - || [istarget spu-*-*] || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) || [istarget aarch64*-*-*] } { return 0 @@ -3193,7 +3192,6 @@ proc check_effective_target_vect_int { } { || ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*]) || [istarget amdgcn-*-*] - || [istarget spu-*-*] || [istarget sparc*-*-*] || [istarget alpha*-*-*] || [istarget ia64-*-*] @@ -3233,7 +3231,6 @@ proc check_effective_target_vect_doubleint_cvt { } { #endif }]) || [istarget aarch64*-*-*] - || [istarget spu-*-*] || ([istarget powerpc*-*-*] && [check_vsx_hw_available]) || ([istarget mips*-*-*] && [et-is-effective-target mips_msa]) }}] @@ -3251,7 +3248,6 @@ proc check_effective_target_vect_intdouble_cvt { } { #endif }]) || [istarget aarch64*-*-*] - || [istarget spu-*-*] || ([istarget powerpc*-*-*] && [check_vsx_hw_available]) || ([istarget mips*-*-*] && [et-is-effective-target mips_msa]) }}] @@ -5519,19 +5515,6 @@ proc check_effective_target_powerpc_elfv2 { } { } } -# Return 1 if this is a SPU target with a toolchain that -# supports automatic overlay generation. - -proc check_effective_target_spu_auto_overlay { } { - if { [istarget spu*-*-elf*] } { - return [check_no_compiler_messages spu_auto_overlay executable { - int main (void) { } - } "-Wl,--auto-overlay" ] - } else { - return 0 - } -} - # The VxWorks SPARC simulator accepts only EM_SPARC executables and # chokes on EM_SPARC32PLUS or EM_SPARCV9 executables. Return 1 if the # test environment appears to run executables on such a simulator. @@ -5697,7 +5680,6 @@ proc check_effective_target_vect_float { } { return [check_cached_effective_target_indexed vect_float { expr { [istarget i?86-*-*] || [istarget x86_64-*-*] || [istarget powerpc*-*-*] - || [istarget spu-*-*] || [istarget mips-sde-elf] || [istarget mipsisa64*-*-*] || [istarget ia64-*-*] @@ -5731,7 +5713,6 @@ proc check_effective_target_vect_double { } { #endif }]) || [istarget aarch64*-*-*] - || [istarget spu-*-*] || ([istarget powerpc*-*-*] && [check_vsx_hw_available]) || ([istarget mips*-*-*] && [et-is-effective-target mips_msa]) @@ -5770,7 +5751,6 @@ proc check_effective_target_vect_long_long { } { proc check_effective_target_vect_no_int_min_max { } { return [check_cached_effective_target_indexed vect_no_int_min_max { expr { [istarget sparc*-*-*] - || [istarget spu-*-*] || [istarget alpha*-*-*] || ([istarget mips*-*-*] && [et-is-effective-target mips_loongson_mmi]) }}] @@ -5806,7 +5786,6 @@ proc check_effective_target_vect_perm { } { expr { [is-effective-target arm_neon] || [istarget aarch64*-*-*] || [istarget powerpc*-*-*] - || [istarget spu-*-*] || [istarget i?86-*-*] || [istarget x86_64-*-*] || ([istarget mips*-*-*] && ([et-is-effective-target mpaired_single] @@ -5902,7 +5881,6 @@ proc check_effective_target_vect_perm_byte { } { || ([istarget aarch64*-*-*] && [is-effective-target aarch64_little_endian]) || [istarget powerpc*-*-*] - || [istarget spu-*-*] || ([istarget mips-*.*] && [et-is-effective-target mips_msa]) || ([istarget s390*-*-*] @@ -5930,7 +5908,6 @@ proc check_effective_target_vect_perm_short { } { || ([istarget aarch64*-*-*] && [is-effective-target aarch64_little_endian]) || [istarget powerpc*-*-*] - || [istarget spu-*-*] || (([istarget i?86-*-*] || [istarget x86_64-*-*]) && [check_ssse3_available]) || ([istarget mips*-*-*] @@ -6047,7 +6024,6 @@ proc check_effective_target_vect_widen_mult_hi_to_si { } { expr { ([check_effective_target_vect_unpack] && [check_effective_target_vect_int_mult]) || ([istarget powerpc*-*-*] - || [istarget spu-*-*] || [istarget ia64-*-*] || ([istarget aarch64*-*-*] && ![check_effective_target_aarch64_sve]) @@ -6081,7 +6057,6 @@ proc check_effective_target_vect_widen_mult_qi_to_hi_pattern { } { proc check_effective_target_vect_widen_mult_hi_to_si_pattern { } { return [check_cached_effective_target_indexed vect_widen_mult_hi_to_si_pattern { expr { [istarget powerpc*-*-*] - || [istarget spu-*-*] || [istarget ia64-*-*] || [istarget i?86-*-*] || [istarget x86_64-*-*] || ([is-effective-target arm_neon] @@ -6203,7 +6178,6 @@ proc check_effective_target_vect_pack_trunc { } { expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*]) || [istarget i?86-*-*] || [istarget x86_64-*-*] || [istarget aarch64*-*-*] - || [istarget spu-*-*] || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok] && [check_effective_target_arm_little_endian]) || ([istarget mips*-*-*] @@ -6221,7 +6195,6 @@ proc check_effective_target_vect_unpack { } { return [check_cached_effective_target_indexed vect_unpack { expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*paired*]) || [istarget i?86-*-*] || [istarget x86_64-*-*] - || [istarget spu-*-*] || [istarget ia64-*-*] || [istarget aarch64*-*-*] || ([istarget mips*-*-*] @@ -6288,8 +6261,7 @@ proc check_effective_target_vect_aligned_arrays { } { set et_vect_aligned_arrays 0 if { (([istarget i?86-*-*] || [istarget x86_64-*-*]) && !([is-effective-target ia32] - || ([check_avx_available] && ![check_prefer_avx128]))) - || [istarget spu-*-*] } { + || ([check_avx_available] && ![check_prefer_avx128]))) } { set et_vect_aligned_arrays 1 } @@ -6332,8 +6304,7 @@ proc check_effective_target_natural_alignment_32 { } { proc check_effective_target_natural_alignment_64 { } { return [check_cached_effective_target_indexed natural_alignment_64 { expr { [is-effective-target natural_alignment_32] - && (([is-effective-target lp64] && ![istarget *-*-darwin*]) - || [istarget spu-*-*]) } + && [is-effective-target lp64] && ![istarget *-*-darwin*] } }] } @@ -6454,7 +6425,6 @@ proc check_effective_target_vect_condition { } { || [istarget powerpc*-*-*] || [istarget ia64-*-*] || [istarget i?86-*-*] || [istarget x86_64-*-*] - || [istarget spu-*-*] || ([istarget mips*-*-*] && [et-is-effective-target mips_msa]) || ([istarget arm*-*-*] @@ -6500,7 +6470,6 @@ proc check_effective_target_vect_char_mult { } { proc check_effective_target_vect_short_mult { } { return [check_cached_effective_target_indexed vect_short_mult { expr { [istarget ia64-*-*] - || [istarget spu-*-*] || [istarget i?86-*-*] || [istarget x86_64-*-*] || [istarget powerpc*-*-*] || [istarget aarch64*-*-*] @@ -6518,7 +6487,6 @@ proc check_effective_target_vect_short_mult { } { proc check_effective_target_vect_int_mult { } { return [check_cached_effective_target_indexed vect_int_mult { expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*]) - || [istarget spu-*-*] || [istarget i?86-*-*] || [istarget x86_64-*-*] || [istarget ia64-*-*] || [istarget aarch64*-*-*] @@ -6563,7 +6531,6 @@ proc check_effective_target_vect_extract_even_odd { } { || [is-effective-target arm_neon] || [istarget i?86-*-*] || [istarget x86_64-*-*] || [istarget ia64-*-*] - || [istarget spu-*-*] || ([istarget mips*-*-*] && ([et-is-effective-target mips_msa] || [et-is-effective-target mpaired_single])) @@ -6580,7 +6547,6 @@ proc check_effective_target_vect_interleave { } { || [is-effective-target arm_neon] || [istarget i?86-*-*] || [istarget x86_64-*-*] || [istarget ia64-*-*] - || [istarget spu-*-*] || ([istarget mips*-*-*] && ([et-is-effective-target mpaired_single] || [et-is-effective-target mips_msa])) @@ -6827,11 +6793,7 @@ proc check_effective_target_section_anchors { } { # Return 1 if the target supports atomic operations on "int_128" values. proc check_effective_target_sync_int_128 { } { - if { [istarget spu-*-*] } { - return 1 - } else { - return 0 - } + return 0 } # Return 1 if the target supports atomic operations on "int_128" values @@ -6839,11 +6801,7 @@ proc check_effective_target_sync_int_128 { } { # This requires support for both compare-and-swap and true atomic loads. proc check_effective_target_sync_int_128_runtime { } { - if { [istarget spu-*-*] } { - return 1 - } else { - return 0 - } + return 0 } # Return 1 if the target supports atomic operations on "long long". @@ -6857,8 +6815,7 @@ proc check_effective_target_sync_long_long { } { || [istarget arm*-*-*] || [istarget alpha*-*-*] || ([istarget sparc*-*-*] && [check_effective_target_lp64]) - || [istarget s390*-*-*] - || [istarget spu-*-*] } { + || [istarget s390*-*-*] } { return 1 } else { return 0 @@ -6917,7 +6874,6 @@ proc check_effective_target_sync_long_long_runtime { } { || ([istarget sparc*-*-*] && [check_effective_target_lp64] && [check_effective_target_ultrasparc_hw]) - || [istarget spu-*-*] || ([istarget powerpc*-*-*] && [check_effective_target_lp64]) } { return 1 } else { @@ -6964,7 +6920,6 @@ proc check_effective_target_sync_int_long { } { || [istarget powerpc*-*-*] || [istarget crisv32-*-*] || [istarget cris-*-*] || ([istarget sparc*-*-*] && [check_effective_target_sparc_v9]) - || [istarget spu-*-*] || ([istarget arc*-*-*] && [check_effective_target_arc_atomic]) || [check_effective_target_mips_llsc] }}] } @@ -6987,7 +6942,6 @@ proc check_effective_target_sync_char_short { } { || [istarget powerpc*-*-*] || [istarget crisv32-*-*] || [istarget cris-*-*] || ([istarget sparc*-*-*] && [check_effective_target_sparc_v9]) - || [istarget spu-*-*] || ([istarget arc*-*-*] && [check_effective_target_arc_atomic]) || [check_effective_target_mips_llsc] }}] } @@ -8575,8 +8529,6 @@ proc check_vect_support_and_set_flags { } { } set dg-do-what-default compile } - } elseif { [istarget spu-*-*] } { - set dg-do-what-default run } elseif { [istarget i?86-*-*] || [istarget x86_64-*-*] } { lappend DEFAULT_VECTCFLAGS "-msse2" if { [check_effective_target_sse2_runtime] } { @@ -8861,8 +8813,7 @@ proc check_effective_target_branch_cost {} { || [istarget mips*-*-*] || [istarget s390*-*-*] || [istarget riscv*-*-*] - || [istarget sh*-*-*] - || [istarget spu*-*-*] } { + || [istarget sh*-*-*] } { return 1 } return 0 diff --git a/gcc/testsuite/lib/target-utils.exp b/gcc/testsuite/lib/target-utils.exp index 0dd1f34..9e36ec0 100644 --- a/gcc/testsuite/lib/target-utils.exp +++ b/gcc/testsuite/lib/target-utils.exp @@ -40,10 +40,6 @@ proc ${tool}_check_unsupported_p { output } { return "memory full" } - if { [istarget spu-*-*] && \ - [string match "*exceeds local store*" $output] } { - return "memory full" - } if { [string match "*error: function pointers not supported*" $output] && ![check_effective_target_function_pointers] } { return "function pointers not supported" -- cgit v1.1 From deeedbada1aaf79f0e223f492ecaffdc05e91af7 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 3 Sep 2019 18:46:06 +0200 Subject: re PR target/91604 (ICE in extract_insn at recog.c:2310 since r272323) PR target/91604 * config/i386/i386-expand.c (split_double_mode): If there is more than one MEM operand and they are rtx_equal_p, reuse lo_half/hi_half from already split matching MEM operand instead of calling adjust_address again. * gcc.target/i386/pr91604.c: New test. From-SVN: r275344 --- gcc/ChangeLog | 8 ++++++++ gcc/config/i386/i386-expand.c | 16 ++++++++++++++-- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.target/i386/pr91604.c | 11 +++++++++++ 4 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr91604.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4996f8c..6ac810f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2019-09-03 Jakub Jelinek + + PR target/91604 + * config/i386/i386-expand.c (split_double_mode): If there is more than + one MEM operand and they are rtx_equal_p, reuse lo_half/hi_half from + already split matching MEM operand instead of calling adjust_address + again. + 2019-09-03 Ulrich Weigand * config.gcc: Obsolete spu target. Remove references to spu. diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c index ec50de2..862cd81 100644 --- a/gcc/config/i386/i386-expand.c +++ b/gcc/config/i386/i386-expand.c @@ -106,6 +106,8 @@ split_double_mode (machine_mode mode, rtx operands[], { machine_mode half_mode; unsigned int byte; + rtx mem_op = NULL_RTX; + int mem_num = 0; switch (mode) { @@ -129,8 +131,18 @@ split_double_mode (machine_mode mode, rtx operands[], but we still have to handle it. */ if (MEM_P (op)) { - lo_half[num] = adjust_address (op, half_mode, 0); - hi_half[num] = adjust_address (op, half_mode, byte); + if (mem_op && rtx_equal_p (op, mem_op)) + { + lo_half[num] = lo_half[mem_num]; + hi_half[num] = hi_half[mem_num]; + } + else + { + mem_op = op; + mem_num = num; + lo_half[num] = adjust_address (op, half_mode, 0); + hi_half[num] = adjust_address (op, half_mode, byte); + } } else { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1a17b06..44c43d2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-03 Jakub Jelinek + + PR target/91604 + * gcc.target/i386/pr91604.c: New test. + 2019-09-03 Ulrich Weigand * lib/compat.exp: Remove references to spu. diff --git a/gcc/testsuite/gcc.target/i386/pr91604.c b/gcc/testsuite/gcc.target/i386/pr91604.c new file mode 100644 index 0000000..329f17f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr91604.c @@ -0,0 +1,11 @@ +/* PR target/91604 */ +/* { dg-do compile } */ +/* { dg-options "-O3 -msse2 --param max-gcse-memory=0 -fno-rerun-cse-after-loop" } */ + +long long v; + +void +foo (void) +{ + v = ~v; +} -- cgit v1.1 From 5f76ab159a4b86b8e4d74f40b8189994646d562f Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 3 Sep 2019 19:42:38 +0000 Subject: c-cppbuiltin.c (builtin_define_with_hex_fp_value): Always expand when using -fgo-dump-spec. * c-cppbuiltin.c (builtin_define_with_hex_fp_value): Always expand when using -fgo-dump-spec. From-SVN: r275352 --- gcc/c-family/ChangeLog | 5 +++++ gcc/c-family/c-cppbuiltin.c | 1 + 2 files changed, 6 insertions(+) (limited to 'gcc') diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 1723dda..e4f011d 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,8 @@ +2019-09-03 Ian Lance Taylor + + * c-cppbuiltin.c (builtin_define_with_hex_fp_value): Always expand + when using -fgo-dump-spec. + 2019-09-02 Martin Liska PR c++/91155 diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c index 6b18246..fc68bc4 100644 --- a/gcc/c-family/c-cppbuiltin.c +++ b/gcc/c-family/c-cppbuiltin.c @@ -1644,6 +1644,7 @@ builtin_define_with_hex_fp_value (const char *macro, /* This is very expensive, so if possible expand them lazily. */ if (lazy_hex_fp_value_count < LAZY_HEX_FP_VALUES_CNT && flag_dump_macros == 0 + && flag_dump_go_spec == NULL && !cpp_get_options (parse_in)->traditional) { if (lazy_hex_fp_value_count == 0) -- cgit v1.1 From 52792faa0c8510b7bfc2c184c9f67d4a87f83215 Mon Sep 17 00:00:00 2001 From: Kamlesh Kumar Date: Tue, 3 Sep 2019 20:13:22 +0000 Subject: re PR tree-optimization/91504 (Inlining misses some logical operation folding) PR tree-optimization/91504 * match.pd: Add ((~a & b) ^a) --> (a | b). PR tree-optimization/91504 gcc.dg/tree-ssa/pr91504.c: New test. From-SVN: r275354 --- gcc/ChangeLog | 5 +++++ gcc/match.pd | 5 +++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/tree-ssa/pr91504.c | 18 ++++++++++++++++++ 4 files changed, 33 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr91504.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6ac810f..abbbf16 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-09-03 Kamlesh Kumar + + PR tree-optimization/91504 + * match.pd: Add ((~a & b) ^a) --> (a | b). + 2019-09-03 Jakub Jelinek PR target/91604 diff --git a/gcc/match.pd b/gcc/match.pd index cd75dac..1d13543 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -831,6 +831,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (bit_xor:c (bit_and:cs @0 (bit_not @1)) (bit_not @0)) (bit_not (bit_and @0 @1))) +/* (~a & b) ^ a --> (a | b) */ +(simplify + (bit_xor:c (bit_and:cs (bit_not @0) @1) @0) + (bit_ior @0 @1)) + /* (a | b) & ~(a ^ b) --> a & b */ (simplify (bit_and:c (bit_ior @0 @1) (bit_not (bit_xor:c @0 @1))) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 44c43d2..4cf3e9b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-03 Kamlesh Kumar + + PR tree-optimization/91504 + gcc.dg/tree-ssa/pr91504.c: New test. + 2019-09-03 Jakub Jelinek PR target/91604 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr91504.c b/gcc/testsuite/gcc.dg/tree-ssa/pr91504.c new file mode 100644 index 0000000..a52dea4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr91504.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-optimized-raw" } */ + +static inline unsigned deposit32(unsigned value, int start, int length, + unsigned fieldval) +{ + unsigned mask = (~0U >> (32 - length)) << start; + return (value & ~mask) | ((fieldval << start) & mask); +} + +unsigned foo(unsigned value) +{ + return deposit32(value, 10, 1, 1); +} + +/* { dg-final { scan-tree-dump-not "bit_and_expr" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "bit_xor_expr" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "bit_not_expr" "optimized" } } */ -- cgit v1.1 From 7a4418a53e80d38918a1f7ca4b8c2050cde08a24 Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz Date: Tue, 3 Sep 2019 20:36:49 +0000 Subject: Implement TARGET_HANDLE_GENERIC_ATTRIBUTE gcc/ChangeLog: 2019-09-03 Jozef Lawrynowicz * config/msp430/msp430.c (TARGET_HANDLE_GENERIC_ATTRIBUTE): Define. (msp430_handle_generic_attribute): New function. * doc/tm.texi: Regenerate. * doc/tm.texi.in: Add TARGET_HANDLE_GENERIC_ATTRIBUTE. * hooks.c (hook_tree_treeptr_tree_tree_int_boolptr_null): New. * hooks.h (hook_tree_treeptr_tree_tree_int_boolptr_null): New. * target.def: Define new hook TARGET_HANDLE_GENERIC_ATTRIBUTE. gcc/c-family/ChangeLog: 2019-09-03 Jozef Lawrynowicz * c-attribs.c (handle_section_attribute): Call the handle_generic_attribute target hook after performing target independent processing. (handle_noinit_attribute): Likewise. From-SVN: r275355 --- gcc/ChangeLog | 10 ++++++++++ gcc/c-family/ChangeLog | 7 +++++++ gcc/c-family/c-attribs.c | 39 +++++++++++++++++++++++++++++---------- gcc/config/msp430/msp430.c | 40 ++++++++++++++++++++++++++++++++++++++++ gcc/doc/tm.texi | 8 ++++++++ gcc/doc/tm.texi.in | 2 ++ gcc/hooks.c | 6 ++++++ gcc/hooks.h | 1 + gcc/target.def | 11 +++++++++++ 9 files changed, 114 insertions(+), 10 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index abbbf16..e65e304 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2019-09-03 Jozef Lawrynowicz + + * config/msp430/msp430.c (TARGET_HANDLE_GENERIC_ATTRIBUTE): Define. + (msp430_handle_generic_attribute): New function. + * doc/tm.texi: Regenerate. + * doc/tm.texi.in: Add TARGET_HANDLE_GENERIC_ATTRIBUTE. + * hooks.c (hook_tree_treeptr_tree_tree_int_boolptr_null): New. + * hooks.h (hook_tree_treeptr_tree_tree_int_boolptr_null): New. + * target.def: Define new hook TARGET_HANDLE_GENERIC_ATTRIBUTE. + 2019-09-03 Kamlesh Kumar PR tree-optimization/91504 diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index e4f011d..9ca5a1e 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,10 @@ +2019-09-03 Jozef Lawrynowicz + + * c-attribs.c (handle_section_attribute): Call the + handle_generic_attribute target hook after performing target + independent processing. + (handle_noinit_attribute): Likewise. + 2019-09-03 Ian Lance Taylor * c-cppbuiltin.c (builtin_define_with_hex_fp_value): Always expand diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c index 820c83f..6500b99 100644 --- a/gcc/c-family/c-attribs.c +++ b/gcc/c-family/c-attribs.c @@ -1875,6 +1875,7 @@ handle_section_attribute (tree *node, tree ARG_UNUSED (name), tree args, int ARG_UNUSED (flags), bool *no_add_attrs) { tree decl = *node; + tree res = NULL_TREE; if (!targetm_common.have_named_sections) { @@ -1922,12 +1923,20 @@ handle_section_attribute (tree *node, tree ARG_UNUSED (name), tree args, goto fail; } - set_decl_section_name (decl, TREE_STRING_POINTER (TREE_VALUE (args))); - return NULL_TREE; + res = targetm.handle_generic_attribute (node, name, args, flags, + no_add_attrs); + + /* If the back end confirms the attribute can be added then continue onto + final processing. */ + if (!(*no_add_attrs)) + { + set_decl_section_name (decl, TREE_STRING_POINTER (TREE_VALUE (args))); + return res; + } fail: *no_add_attrs = true; - return NULL_TREE; + return res; } /* If in c++-11, check if the c++-11 alignment constraint with respect @@ -2249,6 +2258,7 @@ handle_noinit_attribute (tree * node, bool *no_add_attrs) { const char *message = NULL; + tree res = NULL_TREE; gcc_assert (DECL_P (*node)); gcc_assert (args == NULL); @@ -2271,14 +2281,23 @@ handle_noinit_attribute (tree * node, *no_add_attrs = true; } else - /* If this var is thought to be common, then change this. Common - variables are assigned to sections before the backend has a - chance to process them. Do this only if the attribute is - valid. */ - if (DECL_COMMON (*node)) - DECL_COMMON (*node) = 0; + { + res = targetm.handle_generic_attribute (node, name, args, flags, + no_add_attrs); + /* If the back end confirms the attribute can be added then continue onto + final processing. */ + if (!(*no_add_attrs)) + { + /* If this var is thought to be common, then change this. Common + variables are assigned to sections before the backend has a + chance to process them. Do this only if the attribute is + valid. */ + if (DECL_COMMON (*node)) + DECL_COMMON (*node) = 0; + } + } - return NULL_TREE; + return res; } diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c index c5cf704..1e61075 100644 --- a/gcc/config/msp430/msp430.c +++ b/gcc/config/msp430/msp430.c @@ -1518,6 +1518,46 @@ const struct attribute_spec msp430_attribute_table[] = { NULL, 0, 0, false, false, false, false, NULL, NULL } }; +#undef TARGET_HANDLE_GENERIC_ATTRIBUTE +#define TARGET_HANDLE_GENERIC_ATTRIBUTE msp430_handle_generic_attribute + +tree +msp430_handle_generic_attribute (tree *node, + tree name, + tree args ATTRIBUTE_UNUSED, + int flags ATTRIBUTE_UNUSED, + bool *no_add_attrs) + +{ + const char *message = NULL; + + if (!(TREE_NAME_EQ (name, ATTR_NOINIT) || TREE_NAME_EQ (name, "section"))) + return NULL_TREE; + + /* The front end has set up an exclusion between the "noinit" and "section" + attributes. */ + if (has_attr (ATTR_LOWER, *node)) + message = G_("ignoring attribute %qE because it conflicts with " + "attribute %"); + else if (has_attr (ATTR_UPPER, *node)) + message = G_("ignoring attribute %qE because it conflicts with " + "attribute %"); + else if (has_attr (ATTR_EITHER, *node)) + message = G_("ignoring attribute %qE because it conflicts with " + "attribute %"); + else if (has_attr (ATTR_PERSIST, *node)) + message = G_("ignoring attribute %qE because it conflicts with " + "attribute %"); + + if (message) + { + warning (OPT_Wattributes, message, name); + *no_add_attrs = true; + } + + return NULL_TREE; +} + #undef TARGET_ASM_FUNCTION_PROLOGUE #define TARGET_ASM_FUNCTION_PROLOGUE msp430_start_function diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 5506908..0b5a08d 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -10391,6 +10391,14 @@ attributes, or a copy of the list may be made if further changes are needed. @end deftypefn +@deftypefn {Target Hook} tree TARGET_HANDLE_GENERIC_ATTRIBUTE (tree *@var{node}, tree @var{name}, tree @var{args}, int @var{flags}, bool *@var{no_add_attrs}) +Define this target hook if you want to be able to perform additional +target-specific processing of an attribute which is handled generically +by a front end. The arguments are the same as those which are passed to +attribute handlers. So far this only affects the @var{noinit} and +@var{section} attribute. +@end deftypefn + @deftypefn {Target Hook} bool TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P (const_tree @var{fndecl}) @cindex inlining This target hook returns @code{true} if it is OK to inline @var{fndecl} diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 98e7100..a920055 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -7200,6 +7200,8 @@ on this implementation detail. @hook TARGET_INSERT_ATTRIBUTES +@hook TARGET_HANDLE_GENERIC_ATTRIBUTE + @hook TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P @hook TARGET_OPTION_VALID_ATTRIBUTE_P diff --git a/gcc/hooks.c b/gcc/hooks.c index f95659b..ca731c4 100644 --- a/gcc/hooks.c +++ b/gcc/hooks.c @@ -442,6 +442,12 @@ hook_tree_tree_tree_tree_null (tree, tree, tree) return NULL; } +tree +hook_tree_treeptr_tree_tree_int_boolptr_null (tree *, tree, tree, int, bool *) +{ + return NULL; +} + /* Generic hook that takes an rtx_insn *and returns a NULL string. */ const char * hook_constcharptr_const_rtx_insn_null (const rtx_insn *) diff --git a/gcc/hooks.h b/gcc/hooks.h index 0bc8117..040eff0 100644 --- a/gcc/hooks.h +++ b/gcc/hooks.h @@ -109,6 +109,7 @@ extern tree hook_tree_void_null (void); extern tree hook_tree_tree_tree_null (tree, tree); extern tree hook_tree_tree_tree_tree_null (tree, tree, tree); extern tree hook_tree_tree_int_treep_bool_null (tree, int, tree *, bool); +extern tree hook_tree_treeptr_tree_tree_int_boolptr_null (tree *, tree, tree, int, bool *); extern unsigned hook_uint_void_0 (void); extern unsigned int hook_uint_mode_0 (machine_mode); diff --git a/gcc/target.def b/gcc/target.def index b2332d8..ca7e7ad 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -2208,6 +2208,17 @@ needed.", void, (tree node, tree *attr_ptr), hook_void_tree_treeptr) +/* Perform additional target-specific processing of generic attributes. */ +DEFHOOK +(handle_generic_attribute, + "Define this target hook if you want to be able to perform additional\n\ +target-specific processing of an attribute which is handled generically\n\ +by a front end. The arguments are the same as those which are passed to\n\ +attribute handlers. So far this only affects the @var{noinit} and\n\ +@var{section} attribute.", + tree, (tree *node, tree name, tree args, int flags, bool *no_add_attrs), + hook_tree_treeptr_tree_tree_int_boolptr_null) + /* Return true if FNDECL (which has at least one machine attribute) can be inlined despite its machine attributes, false otherwise. */ DEFHOOK -- cgit v1.1 From f1deee9179236ea46965e11923c0f8306b6821ef Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz Date: Tue, 3 Sep 2019 20:48:55 +0000 Subject: MSP430: Setup exclusion tables for function and data attributes gcc/ChangeLog: 2019-09-03 Jozef Lawrynowicz * config/msp430/msp430.c (msp430_attr): Remove warnings about conflicting msp430-specific attributes. (msp430_section_attr): Likewise. Add warnings about conflicts with generic "noinit" and "section" attributes. Fix grammar in -mlarge error message. (msp430_data_attr): Rename to msp430_persist_attr. Add warnings about conflicts with generic "noinit" and "section" attributes. Add warning for when variable is not initialized. Chain conditionals which prevent the attribute being added. (ATTR_EXCL): New helper. (attr_reent_exclusions): New exclusion table. (attr_naked_exclusions): Likewise. (attr_crit_exclusions): Likewise. (attr_lower_exclusions): Likewise. (attr_upper_exclusions): Likewise. (attr_either_exclusions): Likewise. (attr_persist_exclusions): Likewise. (msp430_attribute_table): Update with exclusion rules. (msp430_output_aligned_decl_common): Don't output common symbol if decl has a section. gcc/testsuite/ChangeLog: 2019-09-03 Jozef Lawrynowicz * gcc.target/msp430/data-attributes-2.c: New test. * gcc.target/msp430/function-attributes-4.c: Update dg-warning strings. * gcc.target/msp430/region-attribute-misuse.c: Likewise. From-SVN: r275356 --- gcc/ChangeLog | 25 +++ gcc/config/msp430/msp430.c | 199 +++++++++++++-------- gcc/testsuite/ChangeLog | 9 +- .../gcc.target/msp430/data-attributes-2.c | 51 ++++++ .../gcc.target/msp430/function-attributes-4.c | 27 +-- .../gcc.target/msp430/region-attribute-misuse.c | 6 +- 6 files changed, 222 insertions(+), 95 deletions(-) create mode 100644 gcc/testsuite/gcc.target/msp430/data-attributes-2.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e65e304..e78a2b3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,30 @@ 2019-09-03 Jozef Lawrynowicz + * config/msp430/msp430.c (msp430_attr): Remove warnings about + conflicting msp430-specific attributes. + (msp430_section_attr): Likewise. + Add warnings about conflicts with generic "noinit" and "section" + attributes. + Fix grammar in -mlarge error message. + (msp430_data_attr): Rename to msp430_persist_attr. + Add warnings about conflicts with generic "noinit" and "section" + attributes. + Add warning for when variable is not initialized. + Chain conditionals which prevent the attribute being added. + (ATTR_EXCL): New helper. + (attr_reent_exclusions): New exclusion table. + (attr_naked_exclusions): Likewise. + (attr_crit_exclusions): Likewise. + (attr_lower_exclusions): Likewise. + (attr_upper_exclusions): Likewise. + (attr_either_exclusions): Likewise. + (attr_persist_exclusions): Likewise. + (msp430_attribute_table): Update with exclusion rules. + (msp430_output_aligned_decl_common): Don't output common symbol if decl + has a section. + +2019-09-03 Jozef Lawrynowicz + * config/msp430/msp430.c (TARGET_HANDLE_GENERIC_ATTRIBUTE): Define. (msp430_handle_generic_attribute): New function. * doc/tm.texi: Regenerate. diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c index 1e61075..8880522 100644 --- a/gcc/config/msp430/msp430.c +++ b/gcc/config/msp430/msp430.c @@ -1345,35 +1345,19 @@ msp430_attr (tree * node, } if (is_critical_func (* node)) { + /* We always ignore the critical attribute when interrupt and + critical are used together. */ warning (OPT_Wattributes, "critical attribute has no effect on interrupt functions"); DECL_ATTRIBUTES (*node) = remove_attribute (ATTR_CRIT, DECL_ATTRIBUTES (* node)); } } - else if (TREE_NAME_EQ (name, ATTR_REENT)) - { - if (is_naked_func (* node)) - message = "naked functions cannot be reentrant"; - else if (is_critical_func (* node)) - message = "critical functions cannot be reentrant"; - } else if (TREE_NAME_EQ (name, ATTR_CRIT)) { - if (is_naked_func (* node)) - message = "naked functions cannot be critical"; - else if (is_reentrant_func (* node)) - message = "reentrant functions cannot be critical"; - else if (is_interrupt_func ( *node)) + if (is_interrupt_func ( *node)) message = "critical attribute has no effect on interrupt functions"; } - else if (TREE_NAME_EQ (name, ATTR_NAKED)) - { - if (is_critical_func (* node)) - message = "critical functions cannot be naked"; - else if (is_reentrant_func (* node)) - message = "reentrant functions cannot be naked"; - } if (message) { @@ -1396,32 +1380,15 @@ msp430_section_attr (tree * node, const char * message = NULL; - if (TREE_NAME_EQ (name, ATTR_UPPER)) - { - if (has_attr (ATTR_LOWER, * node)) - message = "already marked with 'lower' attribute"; - else if (has_attr (ATTR_EITHER, * node)) - message = "already marked with 'either' attribute"; - else if (! msp430x) - message = "upper attribute needs a 430X cpu"; - } - else if (TREE_NAME_EQ (name, ATTR_LOWER)) - { - if (has_attr (ATTR_UPPER, * node)) - message = "already marked with 'upper' attribute"; - else if (has_attr (ATTR_EITHER, * node)) - message = "already marked with 'either' attribute"; - } - else - { - gcc_assert (TREE_NAME_EQ (name, ATTR_EITHER)); - - if (has_attr (ATTR_LOWER, * node)) - message = "already marked with 'lower' attribute"; - else if (has_attr (ATTR_UPPER, * node)) - message = "already marked with 'upper' attribute"; - } - + /* The "noinit" and "section" attributes are handled generically, so we + cannot set up additional target-specific attribute exclusions using the + existing mechanism. */ + if (has_attr (ATTR_NOINIT, *node)) + message = G_("ignoring attribute %qE because it conflicts with " + "attribute %"); + else if (has_attr ("section", *node)) + message = G_("ignoring attribute %qE because it conflicts with " + "attribute %"); /* It does not make sense to use upper/lower/either attributes without -mlarge. Without -mlarge, "lower" is the default and only region, so is redundant. @@ -1429,9 +1396,9 @@ msp430_section_attr (tree * node, upper region, which for data could result in relocation overflows, and for code could result in stack mismanagement and incorrect call/return instructions. */ - if (!TARGET_LARGE) - message = G_("%qE attribute ignored. large memory model (%<-mlarge%>) " - "is required"); + else if (!TARGET_LARGE) + message = G_("%qE attribute ignored. Large memory model (%<-mlarge%>) " + "is required."); if (message) { @@ -1443,7 +1410,7 @@ msp430_section_attr (tree * node, } static tree -msp430_data_attr (tree * node, +msp430_persist_attr (tree *node, tree name, tree args, int flags ATTRIBUTE_UNUSED, @@ -1453,34 +1420,36 @@ msp430_data_attr (tree * node, gcc_assert (DECL_P (* node)); gcc_assert (args == NULL); + gcc_assert (TREE_NAME_EQ (name, ATTR_PERSIST)); - if (TREE_CODE (* node) != VAR_DECL) - message = G_("%qE attribute only applies to variables"); - + /* Check for the section attribute separately from DECL_SECTION_NAME so + we can provide a clearer warning. */ + if (has_attr ("section", *node)) + message = G_("ignoring attribute %qE because it conflicts with " + "attribute %"); /* Check that it's possible for the variable to have a section. */ - if ((TREE_STATIC (* node) || DECL_EXTERNAL (* node) || in_lto_p) - && DECL_SECTION_NAME (* node)) + else if ((TREE_STATIC (*node) || DECL_EXTERNAL (*node) || in_lto_p) + && (DECL_SECTION_NAME (*node))) message = G_("%qE attribute cannot be applied to variables with specific " "sections"); - - if (!message && TREE_NAME_EQ (name, ATTR_PERSIST) && !TREE_STATIC (* node) - && !TREE_PUBLIC (* node) && !DECL_EXTERNAL (* node)) + else if (has_attr (ATTR_NOINIT, *node)) + message = G_("ignoring attribute %qE because it conflicts with " + "attribute %"); + else if (TREE_CODE (*node) != VAR_DECL) + message = G_("%qE attribute only applies to variables"); + else if (!TREE_STATIC (*node) && !TREE_PUBLIC (*node) + && !DECL_EXTERNAL (*node)) message = G_("%qE attribute has no effect on automatic variables"); - - /* It's not clear if there is anything that can be set here to prevent the - front end placing the variable before the back end can handle it, in a - similar way to how DECL_COMMON is used below. - So just place the variable in the .persistent section now. */ - if ((TREE_STATIC (* node) || DECL_EXTERNAL (* node) || in_lto_p) - && TREE_NAME_EQ (name, ATTR_PERSIST)) + else if (DECL_COMMON (*node) || DECL_INITIAL (*node) == NULL) + message = G_("variables marked with %qE attribute must be initialized"); + else + /* It's not clear if there is anything that can be set here to prevent the + front end placing the variable before the back end can handle it, in a + similar way to how DECL_COMMON is cleared for .noinit variables in + handle_noinit_attribute (gcc/c-family/c-attribs.c). + So just place the variable in the .persistent section now. */ set_decl_section_name (* node, ".persistent"); - /* If this var is thought to be common, then change this. Common variables - are assigned to sections before the backend has a chance to process - them. */ - if (DECL_COMMON (* node)) - DECL_COMMON (* node) = 0; - if (message) { warning (OPT_Wattributes, message, name); @@ -1490,6 +1459,67 @@ msp430_data_attr (tree * node, return NULL_TREE; } +/* Helper to define attribute exclusions. */ +#define ATTR_EXCL(name, function, type, variable) \ + { name, function, type, variable } + +/* "reentrant", "critical" and "naked" functions must conflict because + they all modify the prologue or epilogue of functions in mutually exclusive + ways. */ +static const struct attribute_spec::exclusions attr_reent_exclusions[] = +{ + ATTR_EXCL (ATTR_NAKED, true, true, true), + ATTR_EXCL (ATTR_CRIT, true, true, true), + ATTR_EXCL (NULL, false, false, false) +}; + +static const struct attribute_spec::exclusions attr_naked_exclusions[] = +{ + ATTR_EXCL (ATTR_REENT, true, true, true), + ATTR_EXCL (ATTR_CRIT, true, true, true), + ATTR_EXCL (NULL, false, false, false) +}; + +static const struct attribute_spec::exclusions attr_crit_exclusions[] = +{ + ATTR_EXCL (ATTR_REENT, true, true, true), + ATTR_EXCL (ATTR_NAKED, true, true, true), + ATTR_EXCL (NULL, false, false, false) +}; + +/* Attributes which put the given object in a specific section must conflict + with one another. */ +static const struct attribute_spec::exclusions attr_lower_exclusions[] = +{ + ATTR_EXCL (ATTR_UPPER, true, true, true), + ATTR_EXCL (ATTR_EITHER, true, true, true), + ATTR_EXCL (ATTR_PERSIST, true, true, true), + ATTR_EXCL (NULL, false, false, false) +}; + +static const struct attribute_spec::exclusions attr_upper_exclusions[] = +{ + ATTR_EXCL (ATTR_LOWER, true, true, true), + ATTR_EXCL (ATTR_EITHER, true, true, true), + ATTR_EXCL (ATTR_PERSIST, true, true, true), + ATTR_EXCL (NULL, false, false, false) +}; + +static const struct attribute_spec::exclusions attr_either_exclusions[] = +{ + ATTR_EXCL (ATTR_LOWER, true, true, true), + ATTR_EXCL (ATTR_UPPER, true, true, true), + ATTR_EXCL (ATTR_PERSIST, true, true, true), + ATTR_EXCL (NULL, false, false, false) +}; + +static const struct attribute_spec::exclusions attr_persist_exclusions[] = +{ + ATTR_EXCL (ATTR_LOWER, true, true, true), + ATTR_EXCL (ATTR_UPPER, true, true, true), + ATTR_EXCL (ATTR_EITHER, true, true, true), + ATTR_EXCL (NULL, false, false, false) +}; #undef TARGET_ATTRIBUTE_TABLE #define TARGET_ATTRIBUTE_TABLE msp430_attribute_table @@ -1500,20 +1530,23 @@ const struct attribute_spec msp430_attribute_table[] = /* { name, min_num_args, max_num_args, decl_req, type_req, fn_type_req, affects_type_identity, handler, exclude } */ { ATTR_INTR, 0, 1, true, false, false, false, msp430_attr, NULL }, - { ATTR_NAKED, 0, 0, true, false, false, false, msp430_attr, NULL }, - { ATTR_REENT, 0, 0, true, false, false, false, msp430_attr, NULL }, - { ATTR_CRIT, 0, 0, true, false, false, false, msp430_attr, NULL }, + { ATTR_NAKED, 0, 0, true, false, false, false, msp430_attr, + attr_naked_exclusions }, + { ATTR_REENT, 0, 0, true, false, false, false, msp430_attr, + attr_reent_exclusions }, + { ATTR_CRIT, 0, 0, true, false, false, false, msp430_attr, + attr_crit_exclusions }, { ATTR_WAKEUP, 0, 0, true, false, false, false, msp430_attr, NULL }, { ATTR_LOWER, 0, 0, true, false, false, false, msp430_section_attr, - NULL }, + attr_lower_exclusions }, { ATTR_UPPER, 0, 0, true, false, false, false, msp430_section_attr, - NULL }, + attr_upper_exclusions }, { ATTR_EITHER, 0, 0, true, false, false, false, msp430_section_attr, - NULL }, + attr_either_exclusions }, - { ATTR_PERSIST, 0, 0, true, false, false, false, msp430_data_attr, - NULL }, + { ATTR_PERSIST, 0, 0, true, false, false, false, msp430_persist_attr, + attr_persist_exclusions }, { NULL, 0, 0, false, false, false, false, NULL, NULL } }; @@ -1922,7 +1955,15 @@ msp430_output_aligned_decl_common (FILE * stream, unsigned HOST_WIDE_INT size, unsigned int align) { - if (msp430_data_region == MSP430_REGION_ANY) + /* Only emit a common symbol if the variable does not have a specific section + assigned. */ + if (msp430_data_region == MSP430_REGION_ANY + && !(decl != NULL_TREE && DECL_SECTION_NAME (decl)) + && !has_attr (ATTR_EITHER, decl) + && !has_attr (ATTR_LOWER, decl) + && !has_attr (ATTR_UPPER, decl) + && !has_attr (ATTR_PERSIST, decl) + && !has_attr (ATTR_NOINIT, decl)) { fprintf (stream, COMMON_ASM_OP); assemble_name (stream, name); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4cf3e9b..7c9a9c9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,13 @@ +2019-09-03 Jozef Lawrynowicz + + * gcc.target/msp430/data-attributes-2.c: New test. + * gcc.target/msp430/function-attributes-4.c: Update dg-warning + strings. + * gcc.target/msp430/region-attribute-misuse.c: Likewise. + 2019-09-03 Kamlesh Kumar - PR tree-optimization/91504 + PR tree-optimization/91504 gcc.dg/tree-ssa/pr91504.c: New test. 2019-09-03 Jakub Jelinek diff --git a/gcc/testsuite/gcc.target/msp430/data-attributes-2.c b/gcc/testsuite/gcc.target/msp430/data-attributes-2.c new file mode 100644 index 0000000..d049194 --- /dev/null +++ b/gcc/testsuite/gcc.target/msp430/data-attributes-2.c @@ -0,0 +1,51 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-mcpu=msp430" } } */ +/* { dg-options "-mlarge" } */ + +/* The msp430-specific variable attributes "lower", "upper", either", "noinit" + and "persistent", all conflict with one another. + These attributes also conflict with the "section" attribute, since they + specify sections to put the variables into. */ +int __attribute__((persistent)) p = 10; +int __attribute__((persistent,lower)) pl = 20; /* { dg-warning "ignoring attribute 'lower' because it conflicts with attribute 'persistent'" } */ +int __attribute__((persistent,upper)) pu = 20; /* { dg-warning "ignoring attribute 'upper' because it conflicts with attribute 'persistent'" } */ +int __attribute__((persistent,either)) pe = 20; /* { dg-warning "ignoring attribute 'either' because it conflicts with attribute 'persistent'" } */ +/* This one results in an error because the handler for persistent sets the + section to .persistent there and then. */ +int __attribute__((persistent,section(".data.foo"))) ps = 20; /* { dg-error "section of 'ps' conflicts with previous declaration" } */ +int __attribute__((persistent,noinit)) pn = 2; /* { dg-warning "'noinit' attribute cannot be applied to variables with specific sections" } */ + +int __attribute__((noinit)) n; +int __attribute__((noinit,lower)) nl; /* { dg-warning "ignoring attribute 'lower' because it conflicts with attribute 'noinit'" } */ +int __attribute__((noinit,upper)) nu; /* { dg-warning "ignoring attribute 'upper' because it conflicts with attribute 'noinit'" } */ +int __attribute__((noinit,either)) ne; /* { dg-warning "ignoring attribute 'either' because it conflicts with attribute 'noinit'" } */ +int __attribute__((noinit,persistent)) np; /* { dg-warning "ignoring attribute 'persistent' because it conflicts with attribute 'noinit'" } */ +int __attribute__((noinit,section(".data.foo"))) ns; /* { dg-warning "ignoring attribute 'section' because it conflicts with attribute 'noinit'" } */ + +int __attribute__((lower)) l = 20; +int __attribute__((lower,upper)) lu = 20; /* { dg-warning "ignoring attribute 'upper' because it conflicts with attribute 'lower'" } */ +int __attribute__((lower,either)) le = 20; /* { dg-warning "ignoring attribute 'either' because it conflicts with attribute 'lower'" } */ +int __attribute__((lower,persistent)) lp = 20; /* { dg-warning "ignoring attribute 'persistent' because it conflicts with attribute 'lower'" } */ +int __attribute__((lower,noinit)) ln; /* { dg-warning "ignoring attribute 'noinit' because it conflicts with attribute 'lower'" } */ +int __attribute__((lower,section(".data.foo"))) ls = 30; /* { dg-warning "ignoring attribute 'section' because it conflicts with attribute 'lower'" } */ + +int __attribute__((upper)) u = 20; +int __attribute__((upper,lower)) ul = 20; /* { dg-warning "ignoring attribute 'lower' because it conflicts with attribute 'upper'" } */ +int __attribute__((upper,either)) ue = 20; /* { dg-warning "ignoring attribute 'either' because it conflicts with attribute 'upper'" } */ +int __attribute__((upper,persistent)) up = 20; /* { dg-warning "ignoring attribute 'persistent' because it conflicts with attribute 'upper'" } */ +int __attribute__((upper,noinit)) un; /* { dg-warning "ignoring attribute 'noinit' because it conflicts with attribute 'upper'" } */ +int __attribute__((upper,section(".data.foo"))) us = 30; /* { dg-warning "ignoring attribute 'section' because it conflicts with attribute 'upper'" } */ + +int __attribute__((either)) e = 20; +int __attribute__((either,lower)) el = 20; /* { dg-warning "ignoring attribute 'lower' because it conflicts with attribute 'either'" } */ +int __attribute__((either,upper)) ee = 20; /* { dg-warning "ignoring attribute 'upper' because it conflicts with attribute 'either'" } */ +int __attribute__((either,persistent)) ep = 20; /* { dg-warning "ignoring attribute 'persistent' because it conflicts with attribute 'either'" } */ +int __attribute__((either,noinit)) en; /* { dg-warning "ignoring attribute 'noinit' because it conflicts with attribute 'either'" } */ +int __attribute__((either,section(".data.foo"))) es = 30; /* { dg-warning "ignoring attribute 'section' because it conflicts with attribute 'either'" } */ + +int __attribute__((section(".data.foo"))) s = 20; +int __attribute__((section(".data.foo"),noinit)) sn; /* { dg-warning "ignoring attribute 'noinit' because it conflicts with attribute 'section'" } */ +int __attribute__((section(".data.foo"),persistent)) sp = 20; /* { dg-warning "ignoring attribute 'persistent' because it conflicts with attribute 'section'" } */ +int __attribute__((section(".data.foo"),lower)) sl = 2; /* { dg-warning "ignoring attribute 'lower' because it conflicts with attribute 'section'" } */ +int __attribute__((section(".data.foo"),upper)) su = 20; /* { dg-warning "ignoring attribute 'upper' because it conflicts with attribute 'section'" } */ +int __attribute__((section(".data.foo"),either)) se = 2; /* { dg-warning "ignoring attribute 'either' because it conflicts with attribute 'section'" } */ diff --git a/gcc/testsuite/gcc.target/msp430/function-attributes-4.c b/gcc/testsuite/gcc.target/msp430/function-attributes-4.c index 07d13c9..86224cc 100644 --- a/gcc/testsuite/gcc.target/msp430/function-attributes-4.c +++ b/gcc/testsuite/gcc.target/msp430/function-attributes-4.c @@ -1,6 +1,9 @@ /* { dg-do compile } */ /* Check that the foo interrupt vectors aren't actually removed. */ /* { dg-final { scan-assembler-times "__interrupt_vector_foo" 2 } } */ +/* Check that the out-of-range interrupt vectors aren't actually removed. */ +/* { dg-final { scan-assembler "__interrupt_vector_65" } } */ +/* { dg-final { scan-assembler "__interrupt_vector_100" } } */ /* Check that warnings are emitted when attributes are used incorrectly and that attributes are interpreted correctly whether leading and trailing @@ -8,62 +11,62 @@ void __attribute__((__naked__,__reentrant__)) fn1(void) -{ /* { dg-warning "naked functions cannot be reentrant" } */ +{ /* { dg-warning "ignoring attribute 'reentrant' because it conflicts with attribute 'naked'" } */ } void __attribute__((naked,reentrant)) fn2(void) -{ /* { dg-warning "naked functions cannot be reentrant" } */ +{ /* { dg-warning "ignoring attribute 'reentrant' because it conflicts with attribute 'naked'" } */ } void __attribute__((__reentrant__,__naked__)) fn3(void) -{ /* { dg-warning "reentrant functions cannot be naked" } */ +{ /* { dg-warning "ignoring attribute 'naked' because it conflicts with attribute 'reentrant'" } */ } void __attribute__((reentrant,naked)) fn4(void) -{ /* { dg-warning "reentrant functions cannot be naked" } */ +{ /* { dg-warning "ignoring attribute 'naked' because it conflicts with attribute 'reentrant'" } */ } void __attribute__((__critical__,__reentrant__)) fn5(void) -{ /* { dg-warning "critical functions cannot be reentrant" } */ +{ /* { dg-warning "ignoring attribute 'reentrant' because it conflicts with attribute 'critical'" } */ } void __attribute__((critical,reentrant)) fn6(void) -{ /* { dg-warning "critical functions cannot be reentrant" } */ +{ /* { dg-warning "ignoring attribute 'reentrant' because it conflicts with attribute 'critical'" } */ } void __attribute__((__reentrant__,__critical__)) fn7(void) -{ /* { dg-warning "reentrant functions cannot be critical" } */ +{ /* { dg-warning "ignoring attribute 'critical' because it conflicts with attribute 'reentrant'" } */ } void __attribute__((reentrant,critical)) fn8(void) -{ /* { dg-warning "reentrant functions cannot be critical" } */ +{ /* { dg-warning "ignoring attribute 'critical' because it conflicts with attribute 'reentrant'" } */ } void __attribute__((__critical__,__naked__)) fn9(void) -{ /* { dg-warning "critical functions cannot be naked" } */ +{ /* { dg-warning "ignoring attribute 'naked' because it conflicts with attribute 'critical'" } */ } void __attribute__((critical,naked)) fn10(void) -{ /* { dg-warning "critical functions cannot be naked" } */ +{ /* { dg-warning "ignoring attribute 'naked' because it conflicts with attribute 'critical'" } */ } void __attribute__((__naked__,__critical__)) fn11(void) -{ /* { dg-warning "naked functions cannot be critical" } */ +{ /* { dg-warning "ignoring attribute 'critical' because it conflicts with attribute 'naked'" } */ } void __attribute__((naked,critical)) fn12(void) -{ /* { dg-warning "naked functions cannot be critical" } */ +{ /* { dg-warning "ignoring attribute 'critical' because it conflicts with attribute 'naked'" } */ } int __attribute__((interrupt)) diff --git a/gcc/testsuite/gcc.target/msp430/region-attribute-misuse.c b/gcc/testsuite/gcc.target/msp430/region-attribute-misuse.c index fe4617b..a108e27 100644 --- a/gcc/testsuite/gcc.target/msp430/region-attribute-misuse.c +++ b/gcc/testsuite/gcc.target/msp430/region-attribute-misuse.c @@ -5,9 +5,9 @@ /* { dg-final { scan-assembler ".section.*lower.data" } } */ /* { dg-final { scan-assembler ".section.*either.data" } } */ -int __attribute__((upper)) upper_bss; /* { dg-warning "'upper' attribute ignored. large memory model .'-mlarge'. is required" } */ -int __attribute__((lower)) lower_bss; /* { dg-warning "'lower' attribute ignored. large memory model .'-mlarge'. is required" } */ -int __attribute__((either)) either_bss; /* { dg-warning "'either' attribute ignored. large memory model .'-mlarge'. is required" } */ +int __attribute__((upper)) upper_bss; /* { dg-warning "'upper' attribute ignored. Large memory model .'-mlarge'. is required" } */ +int __attribute__((lower)) lower_bss; /* { dg-warning "'lower' attribute ignored. Large memory model .'-mlarge'. is required" } */ +int __attribute__((either)) either_bss; /* { dg-warning "'either' attribute ignored. Large memory model .'-mlarge'. is required" } */ /* Verify that even without -mlarge, objects can still be placed in upper/lower/either regions manually. */ -- cgit v1.1 From 64be2b26eb94fcb4d4e754aeb06e868535f33169 Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz Date: Tue, 3 Sep 2019 20:57:02 +0000 Subject: MSP430: Use default_elf_select_section to determine sections for data 2019-09-03 Jozef Lawrynowicz * config/msp430/msp430.c (msp430_init_sections): Remove handling of the noinit section. (msp430_select_section): Handle decls with the "noinit" attribute with default_elf_select_section. Handle SECCAT_RODATA_MERGE_* section types with default_elf_select_section. Add comments about handling of unsupported section types. (msp430_section_type_flags): Remove handling of the noinit section. From-SVN: r275357 --- gcc/ChangeLog | 11 +++++++ gcc/config/msp430/msp430.c | 81 ++++++++++++++++++++++++++++------------------ 2 files changed, 61 insertions(+), 31 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e78a2b3..1ed86eb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,16 @@ 2019-09-03 Jozef Lawrynowicz + * config/msp430/msp430.c (msp430_init_sections): Remove handling of the + noinit section. + (msp430_select_section): Handle decls with the "noinit" attribute with + default_elf_select_section. + Handle SECCAT_RODATA_MERGE_* section types with + default_elf_select_section. + Add comments about handling of unsupported section types. + (msp430_section_type_flags): Remove handling of the noinit section. + +2019-09-03 Jozef Lawrynowicz + * config/msp430/msp430.c (msp430_attr): Remove warnings about conflicting msp430-specific attributes. (msp430_section_attr): Likewise. diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c index 8880522..521d9ba 100644 --- a/gcc/config/msp430/msp430.c +++ b/gcc/config/msp430/msp430.c @@ -1785,7 +1785,6 @@ gen_prefix (tree decl) return NULL; } -static section * noinit_section; static section * persist_section; #undef TARGET_ASM_INIT_SECTIONS @@ -1794,8 +1793,6 @@ static section * persist_section; static void msp430_init_sections (void) { - noinit_section = get_unnamed_section (0, output_section_asm_op, - ".section .noinit,\"aw\""); persist_section = get_unnamed_section (0, output_section_asm_op, ".section .persistent,\"aw\""); } @@ -1806,6 +1803,10 @@ msp430_init_sections (void) static section * msp430_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align) { + const char *prefix; + const char *sec_name; + const char *base_sec_name; + gcc_assert (decl != NULL_TREE); if (TREE_CODE (decl) == STRING_CST @@ -1821,51 +1822,71 @@ msp430_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align) && is_interrupt_func (decl)) return get_section (".lowtext", SECTION_CODE | SECTION_WRITE , decl); - const char * prefix = gen_prefix (decl); - if (prefix == NULL) - { - if (TREE_CODE (decl) == FUNCTION_DECL) - return text_section; - /* FIXME: ATTR_NOINIT is handled generically in - default_elf_select_section. */ - else if (has_attr (ATTR_NOINIT, decl)) - return noinit_section; - else if (has_attr (ATTR_PERSIST, decl)) - return persist_section; - else - return default_select_section (decl, reloc, align); - } + if (has_attr (ATTR_PERSIST, decl)) + return persist_section; + + /* ATTR_NOINIT is handled generically. */ + if (has_attr (ATTR_NOINIT, decl)) + return default_elf_select_section (decl, reloc, align); + + prefix = gen_prefix (decl); - const char * sec; switch (categorize_decl_for_section (decl, reloc)) { - case SECCAT_TEXT: sec = ".text"; break; - case SECCAT_DATA: sec = ".data"; break; - case SECCAT_BSS: sec = ".bss"; break; - case SECCAT_RODATA: sec = ".rodata"; break; + case SECCAT_TEXT: + if (!prefix) + return text_section; + base_sec_name = ".text"; + break; + case SECCAT_DATA: + if (!prefix) + return data_section; + base_sec_name = ".data"; + break; + case SECCAT_BSS: + if (!prefix) + return bss_section; + base_sec_name = ".bss"; + break; + case SECCAT_RODATA: + if (!prefix) + return readonly_data_section; + base_sec_name = ".rodata"; + break; + /* Enable merging of constant data by the GNU linker using + default_elf_select_section and therefore enabling creation of + sections with the SHF_MERGE flag. */ case SECCAT_RODATA_MERGE_STR: case SECCAT_RODATA_MERGE_STR_INIT: case SECCAT_RODATA_MERGE_CONST: + return default_elf_select_section (decl, reloc, align); + + /* The sections listed below are are not supported for MSP430. + They should not be generated, but in case they are, we use + default_select_section so they get placed in sections + the msp430 assembler and linker understand. */ + /* "small data" sections are not supported. */ case SECCAT_SRODATA: - case SECCAT_DATA_REL: - case SECCAT_DATA_REL_LOCAL: - case SECCAT_DATA_REL_RO: - case SECCAT_DATA_REL_RO_LOCAL: case SECCAT_SDATA: case SECCAT_SBSS: + /* Thread-local storage (TLS) is not supported. */ case SECCAT_TDATA: case SECCAT_TBSS: + /* Sections used by a dynamic linker are not supported. */ + case SECCAT_DATA_REL: + case SECCAT_DATA_REL_LOCAL: + case SECCAT_DATA_REL_RO: + case SECCAT_DATA_REL_RO_LOCAL: return default_select_section (decl, reloc, align); default: gcc_unreachable (); } - const char * dec_name = DECL_SECTION_NAME (decl); - char * name = ACONCAT ((prefix, sec, dec_name, NULL)); + sec_name = ACONCAT ((prefix, base_sec_name, DECL_SECTION_NAME (decl), NULL)); - return get_named_section (decl, name, 0); + return get_named_section (decl, sec_name, 0); } #undef TARGET_ASM_FUNCTION_SECTION @@ -1901,8 +1922,6 @@ msp430_section_type_flags (tree decl, const char * name, int reloc) name += strlen (upper_prefix); else if (strncmp (name, either_prefix, strlen (either_prefix)) == 0) name += strlen (either_prefix); - else if (strcmp (name, ".noinit") == 0) - return SECTION_WRITE | SECTION_BSS | SECTION_NOTYPE; else if (strcmp (name, ".persistent") == 0) return SECTION_WRITE | SECTION_NOTYPE; -- cgit v1.1 From 2974ecdae50dbeb7d0cec04f18d5f627ed79629b Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 3 Sep 2019 23:35:13 +0000 Subject: compiler: only import variable into . if same package If we dot-import a package, we should only add an imported variable to the package bindings if the variable is in the package being imported. A test case for this is the 1.13 os package, in which ErrClosed and friends are defined both locally and in the imported internal/oserror package. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/192718 From-SVN: r275358 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/import.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 0add2f0..b334136 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -3b8a505824abb2a69f4c04c555a4ba29ab8b102b +ca0fdb4c7735a648b8f10f1248631adf9afb8454 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/import.cc b/gcc/go/gofrontend/import.cc index 64c1ef2..bbc8d7d 100644 --- a/gcc/go/gofrontend/import.cc +++ b/gcc/go/gofrontend/import.cc @@ -777,7 +777,7 @@ Import::import_var() this->location_); Named_object* no; no = vpkg->add_variable(name, var); - if (this->add_to_globals_) + if (this->add_to_globals_ && vpkg == this->package_) this->gogo_->add_dot_import_object(no); } -- cgit v1.1 From 48259207e6a1b888a0fea37b0fd03cfdbdd16939 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Wed, 4 Sep 2019 00:16:33 +0000 Subject: Daily bump. From-SVN: r275362 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index f282342..45edab8 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20190903 +20190904 -- cgit v1.1 From f8e36f0aef5f867fdde0a1abff5bbc66c17a6429 Mon Sep 17 00:00:00 2001 From: "Steven G. Kargl" Date: Wed, 4 Sep 2019 03:43:40 +0000 Subject: gfortran.texi: Update documentation to catch up with BOZ changes. 2019-09-03 Steven G. Kargl * gfortran.texi: Update documentation to catch up with BOZ changes. * invoke.texi: Fix English from previous BOZ changes commit. From-SVN: r275364 --- gcc/fortran/ChangeLog | 5 +++++ gcc/fortran/gfortran.texi | 50 ++++++++++++++++------------------------------- gcc/fortran/invoke.texi | 4 ++-- 3 files changed, 24 insertions(+), 35 deletions(-) (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 065099a..b866cdf 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,8 @@ +2019-09-03 Steven G. Kargl + + * gfortran.texi: Update documentation to catch up with BOZ changes. + * invoke.texi: Fix English from previous BOZ changes commit. + 2019-09-02 Paul Thomas PR fortran/91589 diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi index 22d42f4..02d30e1 100644 --- a/gcc/fortran/gfortran.texi +++ b/gcc/fortran/gfortran.texi @@ -1848,39 +1848,23 @@ Besides decimal constants, Fortran also supports binary (@code{b}), octal (@code{o}) and hexadecimal (@code{z}) integer constants. The syntax is: @samp{prefix quote digits quote}, were the prefix is either @code{b}, @code{o} or @code{z}, quote is either @code{'} or -@code{"} and the digits are for binary @code{0} or @code{1}, for -octal between @code{0} and @code{7}, and for hexadecimal between -@code{0} and @code{F}. (Example: @code{b'01011101'}.) - -Up to Fortran 95, BOZ literals were only allowed to initialize -integer variables in DATA statements. Since Fortran 2003 BOZ literals -are also allowed as argument of @code{REAL}, @code{DBLE}, @code{INT} -and @code{CMPLX}; the result is the same as if the integer BOZ -literal had been converted by @code{TRANSFER} to, respectively, -@code{real}, @code{double precision}, @code{integer} or @code{complex}. -As GNU Fortran extension the intrinsic procedures @code{FLOAT}, -@code{DFLOAT}, @code{COMPLEX} and @code{DCMPLX} are treated alike. - -As an extension, GNU Fortran allows hexadecimal BOZ literal constants to -be specified using the @code{X} prefix, in addition to the standard -@code{Z} prefix. The BOZ literal can also be specified by adding a -suffix to the string, for example, @code{Z'ABC'} and @code{'ABC'Z} are -equivalent. - -Furthermore, GNU Fortran allows using BOZ literal constants outside -DATA statements and the four intrinsic functions allowed by Fortran 2003. -In DATA statements, in direct assignments, where the right-hand side -only contains a BOZ literal constant, and for old-style initializers of -the form @code{integer i /o'0173'/}, the constant is transferred -as if @code{TRANSFER} had been used; for @code{COMPLEX} numbers, only -the real part is initialized unless @code{CMPLX} is used. In all other -cases, the BOZ literal constant is converted to an @code{INTEGER} value with -the largest decimal representation. This value is then converted -numerically to the type and kind of the variable in question. -(For instance, @code{real :: r = b'0000001' + 1} initializes @code{r} -with @code{2.0}.) As different compilers implement the extension -differently, one should be careful when doing bitwise initialization -of non-integer variables. +@code{"} and the digits are @code{0} or @code{1} for binary, +between @code{0} and @code{7} for octal, and between @code{0} and +@code{F} for hexadecimal. (Example: @code{b'01011101'}.) + +Up to Fortran 95, BOZ literal constants were only allowed to initialize +integer variables in DATA statements. Since Fortran 2003 BOZ literal +constants are also allowed as actual arguments to the @code{REAL}, +@code{DBLE}, @code{INT} and @code{CMPLX} intrinsic functions. +The BOZ literal constant is simply a string of bits, which is padded +or truncated as needed, during conversion to a numeric type. The +Fortran standard states that the treatment of the sign bit is processor +dependent. Gfortran interprets the sign bit as a user would expect. + +As a deprecated extension, GNU Fortran allows hexadecimal BOZ literal +constants to be specified using the @code{X} prefix. The BOZ literal +constant can also be specified by adding a suffix to the string, for +example, @code{Z'ABC'} and @code{'ABC'X} are equivalent. @node Real array indices @subsection Real array indices diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi index 6521e25..ed8cefb 100644 --- a/gcc/fortran/invoke.texi +++ b/gcc/fortran/invoke.texi @@ -241,10 +241,10 @@ warning. This option is implied by @option{-std=legacy}. @item -fallow-invalid-boz @opindex @code{allow-invalid-boz} -A BOZ literal constant can occur in a limited number of context in +A BOZ literal constant can occur in a limited number of contexts in standard conforming Fortran. This option degrades an error condition to a warning, and allows a BOZ literal constant to appear where the -Fortran standard would otherwise prohibits it. +Fortran standard would otherwise prohibit its use. @item -fd-lines-as-code @itemx -fd-lines-as-comments -- cgit v1.1 From dc91c65378cd0e6c07dde9ca119ec0cc7304b039 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 4 Sep 2019 07:27:42 +0000 Subject: re PR middle-end/36262 (Extreme memory usage of VRP compared to older versions) 2019-09-04 Richard Biener PR rtl-optimization/36262 * postreload-gcse.c: Include intl.h and gcse.h. (insert_expr_in_table): Insert at the head of cur_expr->avail_occr to avoid linear list walk. (record_last_mem_set_info): Gate off if not computing transparentness. (get_bb_avail_insn): If transparentness isn't computed give up early. (gcse_after_reload_main): Skip compute_transp and extended PRE if gcse_or_cprop_is_too_expensive says so. From-SVN: r275365 --- gcc/ChangeLog | 12 ++++++++++ gcc/postreload-gcse.c | 64 +++++++++++++++++++++++++-------------------------- 2 files changed, 44 insertions(+), 32 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1ed86eb..fa47927 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2019-09-04 Richard Biener + + PR rtl-optimization/36262 + * postreload-gcse.c: Include intl.h and gcse.h. + (insert_expr_in_table): Insert at the head of cur_expr->avail_occr + to avoid linear list walk. + (record_last_mem_set_info): Gate off if not computing transparentness. + (get_bb_avail_insn): If transparentness isn't computed give up + early. + (gcse_after_reload_main): Skip compute_transp and extended PRE + if gcse_or_cprop_is_too_expensive says so. + 2019-09-03 Jozef Lawrynowicz * config/msp430/msp430.c (msp430_init_sections): Remove handling of the diff --git a/gcc/postreload-gcse.c b/gcc/postreload-gcse.c index e473767..786678c 100644 --- a/gcc/postreload-gcse.c +++ b/gcc/postreload-gcse.c @@ -38,7 +38,9 @@ along with GCC; see the file COPYING3. If not see #include "params.h" #include "tree-pass.h" #include "dbgcnt.h" +#include "intl.h" #include "gcse-common.h" +#include "gcse.h" /* The following code implements gcse after reload, the purpose of this pass is to cleanup redundant loads generated by reload and other @@ -364,7 +366,7 @@ insert_expr_in_table (rtx x, rtx_insn *insn) int do_not_record_p; hashval_t hash; struct expr *cur_expr, **slot; - struct occr *avail_occr, *last_occr = NULL; + struct occr *avail_occr; hash = hash_expr (x, &do_not_record_p); @@ -405,38 +407,22 @@ insert_expr_in_table (rtx x, rtx_insn *insn) cur_expr = *slot; } - /* Search for another occurrence in the same basic block. */ + /* Search for another occurrence in the same basic block. We insert + insns blockwise from start to end, so keep appending to the + start of the list so we have to check only a single element. */ avail_occr = cur_expr->avail_occr; - while (avail_occr - && BLOCK_FOR_INSN (avail_occr->insn) != BLOCK_FOR_INSN (insn)) - { - /* If an occurrence isn't found, save a pointer to the end of - the list. */ - last_occr = avail_occr; - avail_occr = avail_occr->next; - } - - if (avail_occr) - /* Found another instance of the expression in the same basic block. - Prefer this occurrence to the currently recorded one. We want - the last one in the block and the block is scanned from start - to end. */ + if (avail_occr + && BLOCK_FOR_INSN (avail_occr->insn) == BLOCK_FOR_INSN (insn)) avail_occr->insn = insn; else { /* First occurrence of this expression in this basic block. */ avail_occr = (struct occr *) obstack_alloc (&occr_obstack, sizeof (struct occr)); - - /* First occurrence of this expression in any block? */ - if (cur_expr->avail_occr == NULL) - cur_expr->avail_occr = avail_occr; - else - last_occr->next = avail_occr; - avail_occr->insn = insn; - avail_occr->next = NULL; + avail_occr->next = cur_expr->avail_occr; avail_occr->deleted_p = 0; + cur_expr->avail_occr = avail_occr; } } @@ -710,6 +696,9 @@ record_last_reg_set_info_regno (rtx_insn *insn, int regno) static void record_last_mem_set_info (rtx_insn *insn) { + if (!transp) + return; + struct modifies_mem *list_entry; list_entry = (struct modifies_mem *) obstack_alloc (&modifies_mem_obstack, @@ -995,7 +984,8 @@ get_bb_avail_insn (basic_block bb, struct occr *orig_occr, int bitmap_index) /* If we could not find an occurrence in BB, see if BB has a single predecessor with an occurrence that is transparent through BB. */ - if (single_pred_p (bb) + if (transp + && single_pred_p (bb) && bitmap_bit_p (transp[bb->index], bitmap_index) && (occr = get_bb_avail_insn (single_pred (bb), orig_occr, bitmap_index))) { @@ -1371,6 +1361,10 @@ delete_redundant_insns (void) static void gcse_after_reload_main (rtx f ATTRIBUTE_UNUSED) { + /* Disable computing transparentness if it is too expensive. */ + bool do_transp + = !gcse_or_cprop_is_too_expensive (_("using simple load CSE after register " + "allocation")); memset (&stats, 0, sizeof (stats)); @@ -1392,15 +1386,21 @@ gcse_after_reload_main (rtx f ATTRIBUTE_UNUSED) increase the number of redundant loads found. So compute transparency information for each memory expression in the hash table. */ df_analyze (); - /* This cannot be part of the normal allocation routine because - we have to know the number of elements in the hash table. */ - transp = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), - expr_table->elements ()); - bitmap_vector_ones (transp, last_basic_block_for_fn (cfun)); - expr_table->traverse (dump_file); + if (do_transp) + { + /* This cannot be part of the normal allocation routine because + we have to know the number of elements in the hash table. */ + transp = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), + expr_table->elements ()); + bitmap_vector_ones (transp, last_basic_block_for_fn (cfun)); + expr_table->traverse (dump_file); + } + else + transp = NULL; eliminate_partially_redundant_loads (); delete_redundant_insns (); - sbitmap_vector_free (transp); + if (do_transp) + sbitmap_vector_free (transp); if (dump_file) { -- cgit v1.1 From 68e2c1996ec6bde27363ce0db15233ac8cae1c4d Mon Sep 17 00:00:00 2001 From: Prathamesh Kulkarni Date: Wed, 4 Sep 2019 16:25:21 +0000 Subject: Add warning Wenum-conversion for C and ObjC. The patch enables warning with Wextra due to PR91593 and warnings with allmodconfig kernel build. Once these issues are resolved, we could consider promoting it to Wall. 2019-09-04 Prathamesh Kulkarni PR c/78736 * doc/invoke.texi: Document -Wenum-conversion. c-family * c.opt (Wenum-conversion): New option. c/ * c-typeck.c (convert_for_assignment): Handle Wenum-conversion. testsuite/ * gcc.dg/Wenum-conversion.c: New test-case. From-SVN: r275376 --- gcc/ChangeLog | 5 +++++ gcc/c-family/ChangeLog | 5 +++++ gcc/c-family/c.opt | 4 ++++ gcc/c/ChangeLog | 5 +++++ gcc/c/c-typeck.c | 15 +++++++++++++++ gcc/doc/invoke.texi | 10 +++++++++- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/Wenum-conversion.c | 20 ++++++++++++++++++++ 8 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/Wenum-conversion.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fa47927..fc18766 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-09-04 Prathamesh Kulkarni + + PR c/78736 + * doc/invoke.texi: Document -Wenum-conversion. + 2019-09-04 Richard Biener PR rtl-optimization/36262 diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 9ca5a1e..ecdaaeb 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,8 @@ +2019-09-04 Prathamesh Kulkarni + + PR c/78736 + * c.opt (Wenum-conversion): New option. + 2019-09-03 Jozef Lawrynowicz * c-attribs.c (handle_section_attribute): Call the diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index f8a1a1d..38a8e7d 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -541,6 +541,10 @@ Wenum-compare C ObjC C++ ObjC++ Var(warn_enum_compare) Init(-1) Warning LangEnabledBy(C ObjC,Wall || Wc++-compat) Warn about comparison of different enum types. +Wenum-conversion +C ObjC Var(warn_enum_conversion) Init(0) Warning LangEnabledBy(C ObjC,Wextra) +Warn about implicit conversion of enum types. + Werror C ObjC C++ ObjC++ ; Documented in common.opt diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index b7b45f5..285ea18 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,8 @@ +2019-09-04 Prathamesh Kulkarni + + PR c/78736 + * c-typeck.c (convert_for_assignment): Handle Wenum-conversion. + 2019-08-23 Iain Sandoe PR pch/61250 diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 2bbf0e2..d4e12eb 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -6726,6 +6726,21 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, } } + if (warn_enum_conversion) + { + tree checktype = origtype != NULL_TREE ? origtype : rhstype; + if (checktype != error_mark_node + && TREE_CODE (checktype) == ENUMERAL_TYPE + && TREE_CODE (type) == ENUMERAL_TYPE + && TYPE_MAIN_VARIANT (checktype) != TYPE_MAIN_VARIANT (type)) + { + gcc_rich_location loc (location); + warning_at (&loc, OPT_Wenum_conversion, + "implicit conversion from %qT to %qT", + checktype, type); + } + } + if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (rhstype)) { warn_for_address_or_pointer_of_packed_member (type, orig_rhs); diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 2e353be..34d0746 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -307,7 +307,8 @@ Objective-C and Objective-C++ Dialects}. -Wno-discarded-qualifiers -Wno-discarded-array-qualifiers @gol -Wno-div-by-zero -Wdouble-promotion @gol -Wduplicated-branches -Wduplicated-cond @gol --Wempty-body -Wenum-compare -Wno-endif-labels -Wexpansion-to-defined @gol +-Wempty-body -Wenum-compare -Wenum-conversion @gol +-Wno-endif-labels -Wexpansion-to-defined @gol -Werror -Werror=* -Wextra-semi -Wfatal-errors @gol -Wfloat-equal -Wformat -Wformat=2 @gol -Wno-format-contains-nul -Wno-format-extra-args @gol @@ -4434,6 +4435,7 @@ Options} and @ref{Objective-C and Objective-C++ Dialect Options}. -Wcomment @gol -Wduplicate-decl-specifier @r{(C and Objective-C only)} @gol -Wenum-compare @r{(in C/ObjC; this is on by default in C++)} @gol +-Wenum-conversion @r{in C/ObjC;} @gol -Wformat @gol -Wint-in-bool-context @gol -Wimplicit @r{(C and Objective-C only)} @gol @@ -7012,6 +7014,12 @@ In C++ enumerated type mismatches in conditional expressions are also diagnosed and the warning is enabled by default. In C this warning is enabled by @option{-Wall}. +@item -Wenum-conversion @r{(C, Objective-C only)} +@opindex Wenum-conversion +@opindex Wno-enum-conversion +Warn when a value of enumerated type is implicitly converted to a +different enumerated type. This warning is enabled by @option{-Wextra}. + @item -Wextra-semi @r{(C++, Objective-C++ only)} @opindex Wextra-semi @opindex Wno-extra-semi diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7c9a9c9..5b6332a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-04 Prathamesh Kulkarni + + PR c/78736 + * gcc.dg/Wenum-conversion.c: New test-case. + 2019-09-03 Jozef Lawrynowicz * gcc.target/msp430/data-attributes-2.c: New test. diff --git a/gcc/testsuite/gcc.dg/Wenum-conversion.c b/gcc/testsuite/gcc.dg/Wenum-conversion.c new file mode 100644 index 0000000..8603339 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wenum-conversion.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-Wenum-conversion" } */ + +enum X { x1, x2 }; +enum Y { y1, y2 }; + +enum X obj = y1; /* { dg-warning "implicit conversion from .enum Y. to .enum X." } */ +enum Y obj2 = y1; + +enum X obj3; +void foo() +{ + obj3 = y2; /* { dg-warning "implicit conversion from .enum Y. to .enum X." } */ +} + +void bar(enum X); +void f(void) +{ + bar (y1); /* { dg-warning "implicit conversion from .enum Y. to .enum X." } */ +} -- cgit v1.1 From 0c7800b29bd48cc0f7685f3c0da2db6fd87ef52c Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Wed, 4 Sep 2019 20:25:05 +0200 Subject: re PR target/32413 (internal compiler error: in reload_cse_simplify_operands, at postreload.c:396) PR target/32413 * config/i386/i386.c (inline_secondary_memory_needed): Return true for QI and HImode moves between SSE and general registers. From-SVN: r275377 --- gcc/ChangeLog | 6 ++++++ gcc/config/i386/i386.c | 1 + 2 files changed, 7 insertions(+) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fc18766..be92d37 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-09-04 Uroš Bizjak + + PR target/32413 + * config/i386/i386.c (inline_secondary_memory_needed): Return true + for QI and HImode moves between SSE and general registers. + 2019-09-04 Prathamesh Kulkarni PR c/78736 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 1c9c719..50571a0 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -18328,6 +18328,7 @@ inline_secondary_memory_needed (machine_mode mode, reg_class_t class1, /* Between SSE and general, we have moves no larger than word size. */ if (!(INTEGER_CLASS_P (class1) || INTEGER_CLASS_P (class2)) + || GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode) || GET_MODE_SIZE (mode) > UNITS_PER_WORD) return true; -- cgit v1.1 From db9d22747831cd595b6e909a588a1c87ead2a698 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Wed, 4 Sep 2019 20:10:13 +0000 Subject: Remove -fdeduce-init-list. From-SVN: r275387 --- gcc/ChangeLog | 4 ++++ gcc/c-family/ChangeLog | 4 ++++ gcc/c-family/c.opt | 4 ++-- gcc/cp/ChangeLog | 5 +++++ gcc/cp/call.c | 32 ---------------------------- gcc/cp/pt.c | 5 ----- gcc/doc/invoke.texi | 22 ------------------- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/cpp0x/initlist-deduce.C | 12 +++-------- 9 files changed, 23 insertions(+), 70 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index be92d37..0f4b61d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2019-09-04 Marek Polacek + + * doc/invoke.texi: Remove -fdeduce-init-list documentation. + 2019-09-04 Uroš Bizjak PR target/32413 diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index ecdaaeb..2720e64 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,7 @@ +2019-09-04 Marek Polacek + + * c.opt (fdeduce-init-list): Ignored. + 2019-09-04 Prathamesh Kulkarni PR c/78736 diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 38a8e7d..143833d 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -1460,8 +1460,8 @@ C ObjC C++ ObjC++ Emit debug annotations during preprocessing. fdeduce-init-list -C++ ObjC++ Var(flag_deduce_init_list) Init(0) --fdeduce-init-list enable deduction of std::initializer_list for a template type parameter from a brace-enclosed initializer-list. +C++ ObjC++ Ignore +Does nothing. Preserved for backward compatibility. fdeclone-ctor-dtor C++ ObjC++ Var(flag_declone_ctor_dtor) Init(-1) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8eb81c5..605b3d7 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2019-09-04 Marek Polacek + + * call.c (build_over_call): Remove -fdeduce-init-list implementation. + * pt.c (unify): Likewise. + 2019-09-01 Marek Polacek PR c++/91129 - wrong error with binary op in template argument. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 01a25ad..c3045d9 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -8337,38 +8337,6 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) && !(flags & LOOKUP_EXPLICIT_TMPL_ARGS)) conversion_warning = false; - /* Warn about initializer_list deduction that isn't currently in the - working draft. */ - if (cxx_dialect > cxx98 - && flag_deduce_init_list - && cand->template_decl - && is_std_init_list (non_reference (type)) - && BRACE_ENCLOSED_INITIALIZER_P (arg)) - { - tree tmpl = TI_TEMPLATE (cand->template_decl); - tree realparm = chain_index (j, DECL_ARGUMENTS (cand->fn)); - tree patparm = get_pattern_parm (realparm, tmpl); - tree pattype = TREE_TYPE (patparm); - if (PACK_EXPANSION_P (pattype)) - pattype = PACK_EXPANSION_PATTERN (pattype); - pattype = non_reference (pattype); - - if (TREE_CODE (pattype) == TEMPLATE_TYPE_PARM - && (cand->explicit_targs == NULL_TREE - || (TREE_VEC_LENGTH (cand->explicit_targs) - <= TEMPLATE_TYPE_IDX (pattype)))) - { - pedwarn (input_location, 0, "deducing %qT as %qT", - non_reference (TREE_TYPE (patparm)), - non_reference (type)); - pedwarn (DECL_SOURCE_LOCATION (cand->fn), 0, - " in call to %qD", cand->fn); - pedwarn (input_location, 0, - " (you can disable this with " - "%<-fno-deduce-init-list%>)"); - } - } - /* Set user_conv_p on the argument conversions, so rvalue/base handling knows not to allow any more UDCs. This needs to happen after we process cand->warnings. */ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 187f9d85..15cc4b2 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -22073,11 +22073,6 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, unsigned i; tree orig_parm = parm; - /* Replace T with std::initializer_list for deduction. */ - if (TREE_CODE (parm) == TEMPLATE_TYPE_PARM - && flag_deduce_init_list) - parm = listify (parm); - if (!is_std_init_list (parm) && TREE_CODE (parm) != ARRAY_TYPE) /* We can only deduce from an initializer list argument if the diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 34d0746..fad19dd 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -2550,28 +2550,6 @@ of a loop too many expressions need to be evaluated, the resulting constexpr evaluation might take too long. The default is 33554432 (1<<25). -@item -fdeduce-init-list -@opindex fdeduce-init-list -Enable deduction of a template type parameter as -@code{std::initializer_list} from a brace-enclosed initializer list, i.e.@: - -@smallexample -template auto forward(T t) -> decltype (realfn (t)) -@{ - return realfn (t); -@} - -void f() -@{ - forward(@{1,2@}); // call forward> -@} -@end smallexample - -This deduction was implemented as a possible extension to the -originally proposed semantics for the C++11 standard, but was not part -of the final standard, so it is disabled by default. This option is -deprecated, and may be removed in a future version of G++. - @item -fno-elide-constructors @opindex fno-elide-constructors @opindex felide-constructors diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5b6332a..ecde4ca 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-04 Marek Polacek + + * g++.dg/cpp0x/initlist-deduce.C: Don't use -fdeduce-init-list. Remove + dg-warning. Add dg-error. + 2019-09-04 Prathamesh Kulkarni PR c/78736 diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-deduce.C b/gcc/testsuite/g++.dg/cpp0x/initlist-deduce.C index 6ae32a6..59d98ef 100644 --- a/gcc/testsuite/g++.dg/cpp0x/initlist-deduce.C +++ b/gcc/testsuite/g++.dg/cpp0x/initlist-deduce.C @@ -1,9 +1,4 @@ -// Test for deduction of T as std::initializer_list. This isn't currently -// supported by the working draft, but is necessary for perfect forwarding -// of initializer-lists to things that can take a std::initializer_list. - -// { dg-options "-fdeduce-init-list" } -// { dg-do run { target c++11 } } +// { dg-do compile { target c++11 } } #include @@ -15,14 +10,13 @@ struct A void f (A a) { } template -auto g (T&& t) -> decltype (f(t)) // { dg-warning "call" } +auto g (T&& t) -> decltype (f(t)) { return f(t); } int main() { - g({1}); // { dg-warning "deduc" } + g({1}); // { dg-error "no matching function" } } -// { dg-prune-output "-fno-deduce-init-list" } -- cgit v1.1 From 9eb730b8391794c7d451c7fde661b18ccacfbc3a Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Wed, 4 Sep 2019 15:33:27 -0700 Subject: Disallow -fvtable-verify and -flto to be used together. Vtable verification currently does not work properly with link time optimization. Until this can be fixed users should not be allowed to specify both options together. 2019-09-04 Caroline Tice * opts.c (finish_options): Disallow -fvtable-verify and -flto to be specified together. From-SVN: r275388 --- gcc/ChangeLog | 5 +++++ gcc/opts.c | 4 ++++ 2 files changed, 9 insertions(+) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0f4b61d..f620ffd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-09-04 Caroline Tice + + * opts.c (finish_options): Disallow -fvtable-verify and -flto to be + specified together. + 2019-09-04 Marek Polacek * doc/invoke.texi: Remove -fdeduce-init-list documentation. diff --git a/gcc/opts.c b/gcc/opts.c index 1417dba..07f701c 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -1226,6 +1226,10 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, if (opts->x_flag_live_patching && opts->x_flag_lto) sorry ("live patching is not supported with LTO"); + /* Currently vtable verification is not supported for LTO */ + if (opts->x_flag_vtable_verify && opts->x_flag_lto) + sorry ("vtable verification is not supported with LTO"); + /* Control IPA optimizations based on different -flive-patching level. */ if (opts->x_flag_live_patching) { -- cgit v1.1 From 4844a5cb8c37e84eb742471a52dc927ac5cdd16d Mon Sep 17 00:00:00 2001 From: "Steven G. Kargl" Date: Wed, 4 Sep 2019 23:21:12 +0000 Subject: re PR fortran/91650 (ICE in gfc_conv_constant_to_tree, at fortran/trans-const.c:370) 2019-09-04 Steven G. Kargl PR fortran/91650 * io.c (match_io_element): An output IO list item cannot be a BOZ. 2019-09-04 Steven G. Kargl PR fortran/91650 * gfortran.dg/pr91650_1.f90: New test. * gfortran.dg/pr91650_2.f90: Ditto. From-SVN: r275391 --- gcc/fortran/ChangeLog | 5 +++++ gcc/fortran/io.c | 9 +++++++++ gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/gfortran.dg/pr91650_1.f90 | 8 ++++++++ gcc/testsuite/gfortran.dg/pr91650_2.f90 | 13 +++++++++++++ 5 files changed, 41 insertions(+) create mode 100644 gcc/testsuite/gfortran.dg/pr91650_1.f90 create mode 100644 gcc/testsuite/gfortran.dg/pr91650_2.f90 (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index b866cdf..4da4910 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,8 @@ +2019-09-04 Steven G. Kargl + + PR fortran/91650 + * io.c (match_io_element): An output IO list item cannot be a BOZ. + 2019-09-03 Steven G. Kargl * gfortran.texi: Update documentation to catch up with BOZ changes. diff --git a/gcc/fortran/io.c b/gcc/fortran/io.c index 632e168..d57b747 100644 --- a/gcc/fortran/io.c +++ b/gcc/fortran/io.c @@ -3675,6 +3675,15 @@ match_io_element (io_kind k, gfc_code **cpp) if (m == MATCH_NO) gfc_error ("Expected expression in %s statement at %C", io_kind_name (k)); + + if (m == MATCH_YES && expr->ts.type == BT_BOZ) + { + if (gfc_invalid_boz ("BOZ literal constant at %L cannot appear in " + "an output IO list", &gfc_current_locus)) + return MATCH_ERROR; + if (!gfc_boz2int (expr, gfc_max_integer_kind)) + return MATCH_ERROR; + }; } if (m == MATCH_YES && k == M_READ && gfc_check_do_variable (expr->symtree)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ecde4ca..11d6fab 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2019-09-04 Steven G. Kargl + + PR fortran/91650 + * gfortran.dg/pr91650_1.f90: New test. + * gfortran.dg/pr91650_2.f90: Ditto. + 2019-09-04 Marek Polacek * g++.dg/cpp0x/initlist-deduce.C: Don't use -fdeduce-init-list. Remove diff --git a/gcc/testsuite/gfortran.dg/pr91650_1.f90 b/gcc/testsuite/gfortran.dg/pr91650_1.f90 new file mode 100644 index 0000000..1cda096 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr91650_1.f90 @@ -0,0 +1,8 @@ +! { dg-do compile } +! PR fortran/91650 +! Code contributed by Gerhard Steinmetz. +program p + print *, b'10110' ! { dg-error "cannot appear in an output IO list" } + print *, o'10110' ! { dg-error "cannot appear in an output IO list" } + print *, z'10110' ! { dg-error "cannot appear in an output IO list" } +end diff --git a/gcc/testsuite/gfortran.dg/pr91650_2.f90 b/gcc/testsuite/gfortran.dg/pr91650_2.f90 new file mode 100644 index 0000000..28316ec --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr91650_2.f90 @@ -0,0 +1,13 @@ +! { dg-do compile } +! { dg-options "-fallow-invalid-boz" } +! PR fortran/91650 +! Code contributed by Gerhard Steinmetz. +program p + character(len=60) str + write(str,*) b'10110' ! { dg-warning "cannot appear in an output IO list" } + if (trim(adjustl(str)) /= '22') stop 1 + write(str,*) o'10110' ! { dg-warning "cannot appear in an output IO list" } + if (trim(adjustl(str)) /= '4168') stop 2 + write(str,*) z'10110' ! { dg-warning "cannot appear in an output IO list" } + if (trim(adjustl(str)) /= '65808') stop 3 +end -- cgit v1.1 From 7d394f772fc6f198c6b1946e2919643287639c40 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Thu, 5 Sep 2019 00:16:27 +0000 Subject: Daily bump. From-SVN: r275395 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 45edab8..59cbaa8 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20190904 +20190905 -- cgit v1.1 From f44526e367a99b8699fbdc31bb9bcc0618dbe072 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 5 Sep 2019 04:12:30 +0000 Subject: re PR tree-optimization/91663 (split function can be re-inlined, leaving bad stack trace) PR tree-optimization/91663 * go-lang.c (go_langhook_post_options): Clear flag_partial_inlining. From-SVN: r275396 --- gcc/go/ChangeLog | 6 ++++++ gcc/go/go-lang.c | 5 +++++ 2 files changed, 11 insertions(+) (limited to 'gcc') diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index 47400e2..c62877f 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,9 @@ +2019-09-04 Ian Lance Taylor + + PR tree-optimization/91663 + * go-lang.c (go_langhook_post_options): Clear + flag_partial_inlining. + 2019-08-23 Jakub Jelinek PR middle-end/91283 diff --git a/gcc/go/go-lang.c b/gcc/go/go-lang.c index a6bda93..75d98933 100644 --- a/gcc/go/go-lang.c +++ b/gcc/go/go-lang.c @@ -300,6 +300,11 @@ go_langhook_post_options (const char **pfilename ATTRIBUTE_UNUSED) if (!global_options_set.x_flag_optimize_sibling_calls) global_options.x_flag_optimize_sibling_calls = 0; + /* Partial inlining can confuses uses of runtime.Callers. + See https://gcc.gnu.org/PR91663. */ + if (!global_options_set.x_flag_partial_inlining) + global_options.x_flag_partial_inlining = 0; + /* If the debug info level is still 1, as set in init_options, make sure that some debugging type is selected. */ if (global_options.x_debug_info_level == DINFO_LEVEL_TERSE -- cgit v1.1 From 359f25f8e224cb398a732d2e7b499d6e8385a007 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Thu, 5 Sep 2019 07:50:07 +0000 Subject: Force IFN_LOAD/STORE_LANES operands to be memory (PR91577) This patch uses the workaround Richi suggested in the PR: make discover_nonconstant_array_refs mark the source of an IFN_LOAD_LANES call and the destination of an IFN_STORE_LANES call as addressable, so that they don't end up being REG rtxes during expansion. I had to move the discover_nonconstant_array_refs call outside the currently_expanding_to_rtl block since otherwise mark_addressable just queues the decision for later. 2019-09-05 Richard Sandiford gcc/ PR middle-end/91577 * cfgexpand.c (discover_nonconstant_array_refs): Force the source of an IFN_LOAD_LANES call and the destination of an IFN_STORE_LANES call to be in memory. (pass_expand::execute): Call discover_nonconstant_array_refs before setting currently_expanding_to_rtl. gcc/testsuite/ PR middle-end/91577 * gfortran.dg/pr91577.f90: New test, taken from temporary_1.f90. From-SVN: r275399 --- gcc/ChangeLog | 9 +++++++++ gcc/cfgexpand.c | 25 +++++++++++++++++++++---- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gfortran.dg/pr91577.f90 | 28 ++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/pr91577.f90 (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f620ffd..ee8c244 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2019-09-05 Richard Sandiford + + PR middle-end/91577 + * cfgexpand.c (discover_nonconstant_array_refs): Force the source + of an IFN_LOAD_LANES call and the destination of an IFN_STORE_LANES + call to be in memory. + (pass_expand::execute): Call discover_nonconstant_array_refs before + setting currently_expanding_to_rtl. + 2019-09-04 Caroline Tice * opts.c (finish_options): Disallow -fvtable-verify and -flto to be diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 33af991..5a93447 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -6155,7 +6155,24 @@ discover_nonconstant_array_refs (void) { gimple *stmt = gsi_stmt (gsi); if (!is_gimple_debug (stmt)) - walk_gimple_op (stmt, discover_nonconstant_array_refs_r, NULL); + { + walk_gimple_op (stmt, discover_nonconstant_array_refs_r, NULL); + gcall *call = dyn_cast (stmt); + if (call && gimple_call_internal_p (call)) + switch (gimple_call_internal_fn (call)) + { + case IFN_LOAD_LANES: + /* The source must be a MEM. */ + mark_addressable (gimple_call_arg (call, 0)); + break; + case IFN_STORE_LANES: + /* The destination must be a MEM. */ + mark_addressable (gimple_call_lhs (call)); + break; + default: + break; + } + } } } @@ -6353,6 +6370,9 @@ pass_expand::execute (function *fun) avoid_deep_ter_for_debug (gsi_stmt (gsi), 0); } + /* Mark arrays indexed with non-constant indices with TREE_ADDRESSABLE. */ + discover_nonconstant_array_refs (); + /* Make sure all values used by the optimization passes have sane defaults. */ reg_renumber = 0; @@ -6387,9 +6407,6 @@ pass_expand::execute (function *fun) Also, final expects a note to appear there. */ emit_note (NOTE_INSN_DELETED); - /* Mark arrays indexed with non-constant indices with TREE_ADDRESSABLE. */ - discover_nonconstant_array_refs (); - targetm.expand_to_rtl_hook (); crtl->init_stack_alignment (); fun->cfg->max_jumptable_ents = 0; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 11d6fab..ce3a385 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-05 Richard Sandiford + + PR middle-end/91577 + * gfortran.dg/pr91577.f90: New test, taken from temporary_1.f90. + 2019-09-04 Steven G. Kargl PR fortran/91650 diff --git a/gcc/testsuite/gfortran.dg/pr91577.f90 b/gcc/testsuite/gfortran.dg/pr91577.f90 new file mode 100644 index 0000000..8c31d37 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr91577.f90 @@ -0,0 +1,28 @@ +! { dg-do run } +! { dg-additional-options "--param max-completely-peel-loop-nest-depth=1" } +! PR 27662. Don't zero the first stride to indicate a temporary. It +! may be used later. +program pr27662 + implicit none + real(kind=kind(1.0d0)), dimension (2, 2):: x, y, z; + integer i, j + x(1,1) = 1.d0 + x(2,1) = 0.d0 + x(1,2) = 0.d0 + x(2,2) = 1.d0 + z = matmul (x, transpose (test ())) + do i = 1, size (x, 1) + do j = 1, size (x, 2) + if (x (i, j) .ne. z (i, j)) STOP 1 + end do + end do + +contains + function test () result (res) + real(kind=kind(1.0d0)), dimension(2,2) :: res + res(1,1) = 1.d0 + res(2,1) = 0.d0 + res(1,2) = 0.d0 + res(2,2) = 1.d0 + end function +end -- cgit v1.1 From 0fd3ee92340b158f8ac283b6dd25f5612ddf3694 Mon Sep 17 00:00:00 2001 From: Arnaud Charlet Date: Thu, 5 Sep 2019 09:51:38 +0000 Subject: install.texi: Update and clarify requirements to build GNAT. * doc/install.texi: Update and clarify requirements to build GNAT. From-SVN: r275400 --- gcc/ChangeLog | 4 ++++ gcc/doc/install.texi | 53 +++++++++++++++++++++++++++------------------------- 2 files changed, 32 insertions(+), 25 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ee8c244..cf11319 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2019-09-05 Arnaud Charlet + + * doc/install.texi: Update and clarify requirements to build GNAT. + 2019-09-05 Richard Sandiford PR middle-end/91577 diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi index d3a2242..6f4dd7b 100644 --- a/gcc/doc/install.texi +++ b/gcc/doc/install.texi @@ -270,12 +270,34 @@ name of the package depends on your distro) or you must build GCC as a @option{--disable-multilib}. Otherwise, you may encounter an error such as @samp{fatal error: gnu/stubs-32.h: No such file} -@item GNAT +@item @anchor{GNAT-prerequisite}GNAT -In order to build the Ada compiler (GNAT) you must already have GNAT -installed because portions of the Ada frontend are written in Ada (with -GNAT extensions.) Refer to the Ada installation instructions for more -specific information. +In order to build GNAT, the Ada compiler, you need a working GNAT +compiler (GCC version 4.7 or later). + +This includes GNAT tools such as @command{gnatmake} and +@command{gnatlink}, since the Ada front end is written in Ada and +uses some GNAT-specific extensions. + +In order to build a cross compiler, it is strongly recommended to install +the new compiler as native first, and then use it to build the cross +compiler. Other native compiler versions may work but this is not guaranteed and +will typically fail with hard to understand compilation errors during the +build. + +Similarly, it is strongly recommended to use an older version of GNAT to build +GNAT. More recent versions of GNAT than the version built are not guaranteed +to work and will often fail during the build with compilation errors. + +Note that @command{configure} does not test whether the GNAT installation works +and has a sufficiently recent version; if too old a GNAT version is +installed and @option{--enable-languages=ada} is used, the build will fail. + +@env{ADA_INCLUDE_PATH} and @env{ADA_OBJECT_PATH} environment variables +must not be set when building the Ada compiler, the Ada tools, or the +Ada runtime libraries. You can check that your build environment is clean +by verifying that @samp{gnatls -v} lists only one explicit path in each +section. @item A ``working'' POSIX compatible shell, or GNU bash @@ -2705,26 +2727,7 @@ and network filesystems. @section Building the Ada compiler -In order to build GNAT, the Ada compiler, you need a working GNAT -compiler (GCC version 4.0 or later). -This includes GNAT tools such as @command{gnatmake} and -@command{gnatlink}, since the Ada front end is written in Ada and -uses some GNAT-specific extensions. - -In order to build a cross compiler, it is suggested to install -the new compiler as native first, and then use it to build the cross -compiler. - -@command{configure} does not test whether the GNAT installation works -and has a sufficiently recent version; if too old a GNAT version is -installed, the build will fail unless @option{--enable-languages} is -used to disable building the Ada front end. - -@env{ADA_INCLUDE_PATH} and @env{ADA_OBJECT_PATH} environment variables -must not be set when building the Ada compiler, the Ada tools, or the -Ada runtime libraries. You can check that your build environment is clean -by verifying that @samp{gnatls -v} lists only one explicit path in each -section. +See @ref{GNAT-prerequisite}. @section Building with profile feedback -- cgit v1.1 From e7414688f16c4c9db2dacbc31da683887b4ba1bd Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 5 Sep 2019 11:02:43 +0000 Subject: re PR middle-end/90501 (ICE: address taken, but ADDRESSABLE bit not set) 2019-09-05 Richard Biener PR middle-end/90501 * tree-inline.c (declare_return_variable): Mark the return slot as addressable after building an address of it. From-SVN: r275401 --- gcc/ChangeLog | 6 ++++++ gcc/tree-inline.c | 1 + 2 files changed, 7 insertions(+) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cf11319..4f3d288 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-09-05 Richard Biener + + PR middle-end/90501 + * tree-inline.c (declare_return_variable): Mark the return + slot as addressable after building an address of it. + 2019-09-05 Arnaud Charlet * doc/install.texi: Update and clarify requirements to build GNAT. diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 46bbec1..b9c1a3b 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -3569,6 +3569,7 @@ declare_return_variable (copy_body_data *id, tree return_slot, tree modify_dest, taken by alias analysis. */ gcc_assert (TREE_CODE (return_slot) != SSA_NAME); var = return_slot_addr; + mark_addressable (return_slot); } else { -- cgit v1.1 From 056f95ec951178a110b57e58a2ee434907de2e38 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Thu, 5 Sep 2019 11:23:48 +0000 Subject: [preprocessor/91639] #includes at EOF https://gcc.gnu.org/ml/gcc-patches/2019-09/msg00280.html libcpp/ PR preprocessor/91639 * directives.c (do_include_common): Tell lexer we're a #include. * files.c (_cpp_stack_file): Lexer will have always incremented. * internal.h (struct cpp_context): Extend in_directive's semantics. * lex.c (_cpp_lex_direct): Increment line for final \n when lexing for an ISO #include. * line-map.c (linemap_line_start): Remember if we overflowed. gcc/testsuite/ PR preprocessor/91639 * c-c++-common/cpp/pr91639.c: New. * c-c++-common/cpp/pr91639-one.h: New. * c-c++-common/cpp/pr91639-two.h: New. From-SVN: r275402 --- gcc/testsuite/ChangeLog | 7 +++++++ gcc/testsuite/c-c++-common/cpp/pr91639-one.h | 2 ++ gcc/testsuite/c-c++-common/cpp/pr91639-two.h | 1 + gcc/testsuite/c-c++-common/cpp/pr91639.c | 9 +++++++++ 4 files changed, 19 insertions(+) create mode 100644 gcc/testsuite/c-c++-common/cpp/pr91639-one.h create mode 100644 gcc/testsuite/c-c++-common/cpp/pr91639-two.h create mode 100644 gcc/testsuite/c-c++-common/cpp/pr91639.c (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ce3a385..cdaa270 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2019-09-05 Nathan Sidwell + + PR preprocessor/91639 + * c-c++-common/cpp/pr91639.c: New. + * c-c++-common/cpp/pr91639-one.h: New. + * c-c++-common/cpp/pr91639-two.h: New. + 2019-09-05 Richard Sandiford PR middle-end/91577 diff --git a/gcc/testsuite/c-c++-common/cpp/pr91639-one.h b/gcc/testsuite/c-c++-common/cpp/pr91639-one.h new file mode 100644 index 0000000..141f6a7 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/pr91639-one.h @@ -0,0 +1,2 @@ +one +#include "pr91639-two.h" diff --git a/gcc/testsuite/c-c++-common/cpp/pr91639-two.h b/gcc/testsuite/c-c++-common/cpp/pr91639-two.h new file mode 100644 index 0000000..f719efd --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/pr91639-two.h @@ -0,0 +1 @@ +two diff --git a/gcc/testsuite/c-c++-common/cpp/pr91639.c b/gcc/testsuite/c-c++-common/cpp/pr91639.c new file mode 100644 index 0000000..6da0b66 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/pr91639.c @@ -0,0 +1,9 @@ +/* PR91639 Line markers for an end-of-file #include */ +/* { dg-do preprocess } */ +/* { dg-additional-options -Wno-pedantic } */ +/* { dg-additional-files {pr91639-one.h pr91639-two.h} } */ + +#include "pr91639-one.h" +main + +/* { dg-final { scan-file pr91639.i "# 1 \"\[^\n\"\]*pr91639-one.h\" 1\none\n# 1 \"\[^\n\"\]*pr91639-two.h\" 1\ntwo\n# 3 \"\[^\n\"\]*pr91639-one.h\" 2\n# 7 \"\[^\n\"\]*pr91639.c\" 2\nmain\n" } } */ -- cgit v1.1 From b101938436936b04ea3913c44cea7b58204a9765 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Thu, 5 Sep 2019 11:31:08 +0000 Subject: [C++ PATCH] vtable decl marking https://gcc.gnu.org/ml/gcc-patches/2019-08/msg02063.html * cp-tree.h (DECL_VTABLE_OR_VTT_P): Forward to DECL_VIRTUAL_P. From-SVN: r275404 --- gcc/cp/ChangeLog | 4 ++++ gcc/cp/cp-tree.h | 7 ++++--- 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 605b3d7..3162bed 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,7 @@ +2019-09-05 Nathan Sidwell + + * cp-tree.h (DECL_VTABLE_OR_VTT_P): Forward to DECL_VIRTUAL_P. + 2019-09-04 Marek Polacek * call.c (build_over_call): Remove -fdeduce-init-list implementation. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 12eb39a..038f58d 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -462,7 +462,6 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; OVL_LOOKUP_P (in OVERLOAD) LOOKUP_FOUND_P (in RECORD_TYPE, UNION_TYPE, NAMESPACE_DECL) 5: IDENTIFIER_VIRTUAL_P (in IDENTIFIER_NODE) - DECL_VTABLE_OR_VTT_P (in VAR_DECL) FUNCTION_RVALUE_QUALIFIED (in FUNCTION_TYPE, METHOD_TYPE) CALL_EXPR_REVERSE_ARGS (in CALL_EXPR, AGGR_INIT_EXPR) CONSTRUCTOR_PLACEHOLDER_BOUNDARY (in CONSTRUCTOR) @@ -3258,8 +3257,10 @@ struct GTY(()) lang_decl { both the primary typeinfo object and the associated NTBS name. */ #define DECL_TINFO_P(NODE) TREE_LANG_FLAG_4 (VAR_DECL_CHECK (NODE)) -/* 1 iff VAR_DECL node NODE is virtual table or VTT. */ -#define DECL_VTABLE_OR_VTT_P(NODE) TREE_LANG_FLAG_5 (VAR_DECL_CHECK (NODE)) +/* 1 iff VAR_DECL node NODE is virtual table or VTT. We forward to + DECL_VIRTUAL_P from the common code, as that has the semantics we + need. But we want a more descriptive name. */ +#define DECL_VTABLE_OR_VTT_P(NODE) DECL_VIRTUAL_P (VAR_DECL_CHECK (NODE)) /* 1 iff FUNCTION_TYPE or METHOD_TYPE has a ref-qualifier (either & or &&). */ #define FUNCTION_REF_QUALIFIED(NODE) \ -- cgit v1.1 From 5a4c9a493153f6f579cd81905d0ab743dd88a33d Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 5 Sep 2019 13:23:28 +0000 Subject: re PR rtl-optimization/91656 (wrong code with -fgcse-after-reload) 2019-09-05 Richard Biener PR rtl-optimization/91656 * postreload-gcse.c (record_last_mem_set_info): Revert addition of early out. * gcc.dg/torture/pr91656-1.c: New testcase. * gcc.dg/torture/pr91656-2.c: Likewise. * gcc.dg/torture/pr91656-3.c: Likewise. From-SVN: r275406 --- gcc/ChangeLog | 6 ++++++ gcc/postreload-gcse.c | 3 --- gcc/testsuite/ChangeLog | 7 +++++++ gcc/testsuite/gcc.dg/torture/pr91656-1.c | 24 ++++++++++++++++++++++++ gcc/testsuite/gcc.dg/torture/pr91656-2.c | 27 +++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/torture/pr91656-3.c | 25 +++++++++++++++++++++++++ 6 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr91656-1.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr91656-2.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr91656-3.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4f3d288..1de9622 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2019-09-05 Richard Biener + PR rtl-optimization/91656 + * postreload-gcse.c (record_last_mem_set_info): Revert addition + of early out. + +2019-09-05 Richard Biener + PR middle-end/90501 * tree-inline.c (declare_return_variable): Mark the return slot as addressable after building an address of it. diff --git a/gcc/postreload-gcse.c b/gcc/postreload-gcse.c index 786678c..c62aee9 100644 --- a/gcc/postreload-gcse.c +++ b/gcc/postreload-gcse.c @@ -696,9 +696,6 @@ record_last_reg_set_info_regno (rtx_insn *insn, int regno) static void record_last_mem_set_info (rtx_insn *insn) { - if (!transp) - return; - struct modifies_mem *list_entry; list_entry = (struct modifies_mem *) obstack_alloc (&modifies_mem_obstack, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cdaa270..1d48a80 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2019-09-05 Richard Biener + + PR rtl-optimization/91656 + * gcc.dg/torture/pr91656-1.c: New testcase. + * gcc.dg/torture/pr91656-2.c: Likewise. + * gcc.dg/torture/pr91656-3.c: Likewise. + 2019-09-05 Nathan Sidwell PR preprocessor/91639 diff --git a/gcc/testsuite/gcc.dg/torture/pr91656-1.c b/gcc/testsuite/gcc.dg/torture/pr91656-1.c new file mode 100644 index 0000000..6c1e73c7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr91656-1.c @@ -0,0 +1,24 @@ +/* { dg-do run } */ +/* { dg-additional-options "-fgcse-after-reload" } */ + +int a, b, c, d, e; + +static __attribute__ ((__noipa__)) +int foo (int i) +{ + __builtin_memmove (&i, &e, 1); + if (a > 0) + i /= e; + e /= 5; + b = 0; + return i + c + d + 5; +} + +int +main (void) +{ + int x = foo (4); + if (x != 5) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr91656-2.c b/gcc/testsuite/gcc.dg/torture/pr91656-2.c new file mode 100644 index 0000000..90374be --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr91656-2.c @@ -0,0 +1,27 @@ +/* { dg-do run { target int128 } } */ +/* { dg-additional-options "-fgcse-after-reload" } */ + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +typedef unsigned long long u64; +int a, b, c; +__int128 e; +int +d (u16 g) +{ + u64 f = __builtin_bswap64 (c); + f = g == a; + __builtin_memmove (&f, &e, 1); + e >>= b; + return a + f; +} + +int +main (void) +{ + __int128 x = d (0); + if (x != 0) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr91656-3.c b/gcc/testsuite/gcc.dg/torture/pr91656-3.c new file mode 100644 index 0000000..8e65d24 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr91656-3.c @@ -0,0 +1,25 @@ +/* { dg-do run { target int128 } } */ +/* { dg-additional-options "-fgcse-after-reload" } */ + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +typedef unsigned long long u64; +int a, b, c; +int +d (u16 e, u64 f) +{ + b |= e; + __builtin_memset (&f, e, 2); + a = (u16) - e >= 2 ? : __builtin_popcountll (f); + return a + c; +} + +int +main (void) +{ + __int128 x = d (~0, 0); + if (x != 16) + __builtin_abort (); + return 0; +} -- cgit v1.1 From 728347922a60d5e560a4071d23c492e8baeab115 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 5 Sep 2019 15:30:23 +0200 Subject: re PR middle-end/91001 (internal compiler error: in extract_insn, at recog.c:2310) PR middle-end/91001 PR middle-end/91105 PR middle-end/91106 * calls.c (load_register_parameters): For TYPE_TRANSPARENT_AGGR types, use type of their first field instead of type of args[i].tree_value. * gcc.c-torture/compile/pr91001.c: New test. From-SVN: r275408 --- gcc/ChangeLog | 9 ++++++++ gcc/calls.c | 12 +++++++---- gcc/testsuite/ChangeLog | 7 ++++++ gcc/testsuite/gcc.c-torture/compile/pr91001.c | 31 +++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr91001.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1de9622..e76ed4a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2019-09-05 Jakub Jelinek + + PR middle-end/91001 + PR middle-end/91105 + PR middle-end/91106 + * calls.c (load_register_parameters): For TYPE_TRANSPARENT_AGGR + types, use type of their first field instead of type of + args[i].tree_value. + 2019-09-05 Richard Biener PR rtl-optimization/91656 diff --git a/gcc/calls.c b/gcc/calls.c index 6eefeec..e5086f4 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -2771,6 +2771,11 @@ load_register_parameters (struct arg_data *args, int num_actuals, poly_int64 size = 0; HOST_WIDE_INT const_size = 0; rtx_insn *before_arg = get_last_insn (); + tree type = TREE_TYPE (args[i].tree_value); + if ((TREE_CODE (type) == UNION_TYPE + || TREE_CODE (type) == RECORD_TYPE) + && TYPE_TRANSPARENT_AGGR (type)) + type = TREE_TYPE (first_field (type)); /* Set non-negative if we must move a word at a time, even if just one word (e.g, partial == 4 && mode == DFmode). Set to -1 if we just use a normal move insn. This value can be @@ -2783,11 +2788,11 @@ load_register_parameters (struct arg_data *args, int num_actuals, gcc_assert (partial % UNITS_PER_WORD == 0); nregs = partial / UNITS_PER_WORD; } - else if (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode) + else if (TYPE_MODE (type) == BLKmode) { /* Variable-sized parameters should be described by a PARALLEL instead. */ - const_size = int_size_in_bytes (TREE_TYPE (args[i].tree_value)); + const_size = int_size_in_bytes (type); gcc_assert (const_size >= 0); nregs = (const_size + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD; size = const_size; @@ -2914,8 +2919,7 @@ load_register_parameters (struct arg_data *args, int num_actuals, if (GET_CODE (reg) == PARALLEL) use_group_regs (call_fusage, reg); else if (nregs == -1) - use_reg_mode (call_fusage, reg, - TYPE_MODE (TREE_TYPE (args[i].tree_value))); + use_reg_mode (call_fusage, reg, TYPE_MODE (type)); else if (nregs > 0) use_regs (call_fusage, REGNO (reg), nregs); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1d48a80..3a905cb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2019-09-05 Jakub Jelinek + + PR middle-end/91001 + PR middle-end/91105 + PR middle-end/91106 + * gcc.c-torture/compile/pr91001.c: New test. + 2019-09-05 Richard Biener PR rtl-optimization/91656 diff --git a/gcc/testsuite/gcc.c-torture/compile/pr91001.c b/gcc/testsuite/gcc.c-torture/compile/pr91001.c new file mode 100644 index 0000000..4b6a017 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr91001.c @@ -0,0 +1,31 @@ +/* PR middle-end/91001 */ +/* PR middle-end/91105 */ +/* PR middle-end/91106 */ + +struct __attribute__((packed)) S { short b; char c; }; +struct T { short b, c, d; }; +struct __attribute__((packed)) R { int b; char c; }; +union __attribute__((aligned(128), transparent_union)) U { struct S c; } u; +union __attribute__((aligned(32), transparent_union)) V { struct T c; } v; +union __attribute__((aligned(32), transparent_union)) W { struct R c; } w; +void foo (union U); +void bar (union V); +void baz (union W); + +void +qux (void) +{ + foo (u); +} + +void +quux (void) +{ + bar (v); +} + +void +corge (void) +{ + baz (w); +} -- cgit v1.1 From 55e8f926f260342e0b89765a306a3027daeaa10e Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Thu, 5 Sep 2019 13:40:17 +0000 Subject: re PR target/91615 ([armeb] ICEs since r274986) 2019-09-05 Bernd Edlinger PR middle-end/91615 * expr.c (expand_expr_real_1): Handle misaligned TARGET_MEM_REF without movmisalign optab. From-SVN: r275409 --- gcc/ChangeLog | 6 ++++++ gcc/expr.c | 33 +++++++++++++++++++-------------- 2 files changed, 25 insertions(+), 14 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e76ed4a..6caf635 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-09-05 Bernd Edlinger + + PR middle-end/91615 + * expr.c (expand_expr_real_1): Handle misaligned TARGET_MEM_REF + without movmisalign optab. + 2019-09-05 Jakub Jelinek PR middle-end/91001 diff --git a/gcc/expr.c b/gcc/expr.c index 0c96551..3f4c98c 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -10313,7 +10313,6 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, { addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0)))); - enum insn_code icode; unsigned int align; op0 = addr_for_mem_ref (exp, as, true); @@ -10325,21 +10324,27 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, if (modifier != EXPAND_WRITE && modifier != EXPAND_MEMORY && mode != BLKmode - && align < GET_MODE_ALIGNMENT (mode) - /* If the target does not have special handling for unaligned - loads of mode then it can use regular moves for them. */ - && ((icode = optab_handler (movmisalign_optab, mode)) - != CODE_FOR_nothing)) + && align < GET_MODE_ALIGNMENT (mode)) { - class expand_operand ops[2]; + enum insn_code icode; - /* We've already validated the memory, and we're creating a - new pseudo destination. The predicates really can't fail, - nor can the generator. */ - create_output_operand (&ops[0], NULL_RTX, mode); - create_fixed_operand (&ops[1], temp); - expand_insn (icode, 2, ops); - temp = ops[0].value; + if ((icode = optab_handler (movmisalign_optab, mode)) + != CODE_FOR_nothing) + { + class expand_operand ops[2]; + + /* We've already validated the memory, and we're creating a + new pseudo destination. The predicates really can't fail, + nor can the generator. */ + create_output_operand (&ops[0], NULL_RTX, mode); + create_fixed_operand (&ops[1], temp); + expand_insn (icode, 2, ops); + temp = ops[0].value; + } + else if (targetm.slow_unaligned_access (mode, align)) + temp = extract_bit_field (temp, GET_MODE_BITSIZE (mode), + 0, unsignedp, NULL_RTX, + mode, mode, false, NULL); } return temp; } -- cgit v1.1 From b2c113aed6f2ae2fca28cd5a8fab9c857b97dd2b Mon Sep 17 00:00:00 2001 From: Andrew Stubbs Date: Thu, 5 Sep 2019 14:21:28 +0000 Subject: Global GCN instructions need nops too. 2019-09-05 Andrew Stubbs gcc/ * config/gcn/gcn.md (*movti_insn): Set delayeduse for global_store. (sync_compare_and_swap_insn): Likewise. From-SVN: r275414 --- gcc/ChangeLog | 5 +++++ gcc/config/gcn/gcn.md | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6caf635..805a24f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-09-05 Andrew Stubbs + + * config/gcn/gcn.md (*movti_insn): Set delayeduse for global_store. + (sync_compare_and_swap_insn): Likewise. + 2019-09-05 Bernd Edlinger PR middle-end/91615 diff --git a/gcc/config/gcn/gcn.md b/gcc/config/gcn/gcn.md index bbd2db2..36908ba 100644 --- a/gcc/config/gcn/gcn.md +++ b/gcc/config/gcn/gcn.md @@ -652,7 +652,7 @@ } [(set_attr "type" "mult,smem,smem,flat,flat,vmult,vmult,vmult,flat,flat,\ ds,ds") - (set_attr "delayeduse" "*,*,yes,*,*,*,*,*,*,*,*,*") + (set_attr "delayeduse" "*,*,yes,*,*,*,*,*,yes,*,*,*") (set_attr "length" "*,12,12,12,12,*,*,*,12,12,12,12")]) ;; }}} @@ -1619,7 +1619,7 @@ [(set_attr "type" "smem,flat,flat") (set_attr "length" "12") (set_attr "gcn_version" "gcn5,*,gcn5") - (set_attr "delayeduse" "*,yes,*")]) + (set_attr "delayeduse" "*,yes,yes")]) (define_insn "sync_compare_and_swap_lds_insn" [(set (match_operand:SIDI 0 "register_operand" "= v") -- cgit v1.1 From bb64bef659dc5b11fe1f8ff1f7df65603c9d8876 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Thu, 5 Sep 2019 15:37:52 +0000 Subject: PR c++/91644 - ICE with constinit in function template. * decl.c (start_decl): Call retrofit_lang_decl for constinit variables. * pt.c (tsubst_expr): Pass LOOKUP_CONSTINIT down to cp_finish_decl for constinit variables. * g++.dg/cpp2a/constinit13.C: New test. From-SVN: r275421 --- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/decl.c | 9 ++++++++- gcc/cp/pt.c | 12 ++++++++++-- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/cpp2a/constinit13.C | 33 ++++++++++++++++++++++++++++++++ 5 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/constinit13.C (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3162bed..31a04ef 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2019-09-05 Marek Polacek + + PR c++/91644 - ICE with constinit in function template. + * decl.c (start_decl): Call retrofit_lang_decl for constinit variables. + * pt.c (tsubst_expr): Pass LOOKUP_CONSTINIT down to cp_finish_decl for + constinit variables. + 2019-09-05 Nathan Sidwell * cp-tree.h (DECL_VTABLE_OR_VTT_P): Forward to DECL_VIRTUAL_P. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 6de95cd..825e1e6 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -5308,7 +5308,14 @@ start_decl (const cp_declarator *declarator, decl = maybe_push_decl (decl); if (processing_template_decl) - decl = push_template_decl (decl); + { + /* Make sure that for a `constinit' decl push_template_decl creates + a DECL_TEMPLATE_INFO info for us, so that cp_finish_decl can then set + TINFO_VAR_DECLARED_CONSTINIT. */ + if (decl_spec_seq_has_spec_p (declspecs, ds_constinit)) + retrofit_lang_decl (decl); + decl = push_template_decl (decl); + } if (decl == error_mark_node) return error_mark_node; diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 15cc4b2..cec9798 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -17108,6 +17108,13 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, else { init = DECL_INITIAL (decl); + /* The following tsubst call will clear the DECL_TEMPLATE_INFO + for local variables, so save if DECL was declared constinit. */ + const bool constinit_p + = (VAR_P (decl) + && DECL_LANG_SPECIFIC (decl) + && DECL_TEMPLATE_INFO (decl) + && TINFO_VAR_DECLARED_CONSTINIT (DECL_TEMPLATE_INFO (decl))); decl = tsubst (decl, args, complain, in_decl); if (decl != error_mark_node) { @@ -17146,7 +17153,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, } else { - int const_init = false; + bool const_init = false; unsigned int cnt = 0; tree first = NULL_TREE, ndecl = error_mark_node; maybe_push_decl (decl); @@ -17167,7 +17174,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, if (ndecl != error_mark_node) cp_maybe_mangle_decomp (ndecl, first, cnt); - cp_finish_decl (decl, init, const_init, NULL_TREE, 0); + cp_finish_decl (decl, init, const_init, NULL_TREE, + constinit_p ? LOOKUP_CONSTINIT : 0); if (ndecl != error_mark_node) cp_finish_decomp (ndecl, first, cnt); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3a905cb..9940cec8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-05 Marek Polacek + + PR c++/91644 - ICE with constinit in function template. + * g++.dg/cpp2a/constinit13.C: New test. + 2019-09-05 Jakub Jelinek PR middle-end/91001 diff --git a/gcc/testsuite/g++.dg/cpp2a/constinit13.C b/gcc/testsuite/g++.dg/cpp2a/constinit13.C new file mode 100644 index 0000000..8ea64cc --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/constinit13.C @@ -0,0 +1,33 @@ +// PR c++/91644 - ICE with constinit in function template. +// { dg-do compile { target c++11 } } + +template +static void fn1 () +{ + static __constinit auto v1 = 0; + static __constinit int v2 = 0; +} + +int nonconst; + +template +static void fn2 () +{ + static __constinit auto v1 = nonconst; // { dg-error "does not have a constant initializer|not usable" } + static __constinit int v2 = nonconst; // { dg-error "does not have a constant initializer|not usable" } +} + +template +static void fn3 () +{ + static __constinit T v1 = 0; + static __constinit T v2 = nonconst; // { dg-error "does not have a constant initializer|not usable" } +} + +void +g () +{ + fn1(); + fn2(); + fn3(); +} -- cgit v1.1 From 0e521c64613e0407bd086a26322402b29daeb370 Mon Sep 17 00:00:00 2001 From: "Steven G. Kargl" Date: Thu, 5 Sep 2019 18:14:34 +0000 Subject: re PR fortran/91660 (Missing error on invalid type declaration) 2019-09-05 Steven G. Kargl PR fortran/91660 * decl.c (gfc_match_decl_type_spec): Improve and restore error message for malformed types-spec. 2019-09-05 Steven G. Kargl PR fortran/91660 * gfortran.dg/pdt_4.f03: Fix invalid code. * gfortran.dg/pr91660_1.f90: New test. * gfortran.dg/pr91660_2.f90: Ditto. From-SVN: r275426 --- gcc/fortran/ChangeLog | 6 ++++++ gcc/fortran/decl.c | 25 ++++++++++++++++++++----- gcc/testsuite/ChangeLog | 7 +++++++ gcc/testsuite/gfortran.dg/pdt_4.f03 | 4 ++-- gcc/testsuite/gfortran.dg/pr91660_1.f90 | 9 +++++++++ gcc/testsuite/gfortran.dg/pr91660_2.f90 | 9 +++++++++ 6 files changed, 53 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/pr91660_1.f90 create mode 100644 gcc/testsuite/gfortran.dg/pr91660_2.f90 (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 4da4910..129bfdd 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,9 @@ +2019-09-05 Steven G. Kargl + + PR fortran/91660 + * decl.c (gfc_match_decl_type_spec): Improve and restore error + message for malformed types-spec. + 2019-09-04 Steven G. Kargl PR fortran/91650 diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c index 0711191..278882d 100644 --- a/gcc/fortran/decl.c +++ b/gcc/fortran/decl.c @@ -4023,7 +4023,6 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag) return MATCH_YES; } - m = gfc_match (" type ("); matched_type = (m == MATCH_YES); if (matched_type) @@ -4071,7 +4070,10 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag) m = MATCH_YES; if (matched_type && m == MATCH_YES && gfc_match_char (')') != MATCH_YES) - m = MATCH_ERROR; + { + gfc_error ("Malformed type-spec at %C"); + return MATCH_ERROR; + } return m; } @@ -4094,8 +4096,12 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag) && !gfc_notify_std (GFC_STD_F2008, "TYPE with " "intrinsic-type-spec at %C")) return MATCH_ERROR; + if (matched_type && gfc_match_char (')') != MATCH_YES) - return MATCH_ERROR; + { + gfc_error ("Malformed type-spec at %C"); + return MATCH_ERROR; + } ts->type = BT_REAL; ts->kind = gfc_default_double_kind; @@ -4125,7 +4131,10 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag) return MATCH_ERROR; if (matched_type && gfc_match_char (')') != MATCH_YES) - return MATCH_ERROR; + { + gfc_error ("Malformed type-spec at %C"); + return MATCH_ERROR; + } ts->type = BT_COMPLEX; ts->kind = gfc_default_double_kind; @@ -4146,7 +4155,13 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag) if (m == MATCH_ERROR) return m; - m = gfc_match_char (')'); + gfc_gobble_whitespace (); + if (gfc_peek_ascii_char () != ')') + { + gfc_error ("Malformed type-spec at %C"); + return MATCH_ERROR; + } + m = gfc_match_char (')'); /* Burn closing ')'. */ } if (m != MATCH_YES) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9940cec8..a43cec3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2019-09-05 Steven G. Kargl + + PR fortran/91660 + * gfortran.dg/pdt_4.f03: Fix invalid code. + * gfortran.dg/pr91660_1.f90: New test. + * gfortran.dg/pr91660_2.f90: Ditto. + 2019-09-05 Marek Polacek PR c++/91644 - ICE with constinit in function template. diff --git a/gcc/testsuite/gfortran.dg/pdt_4.f03 b/gcc/testsuite/gfortran.dg/pdt_4.f03 index 0bb58f9..c1af65a 100644 --- a/gcc/testsuite/gfortran.dg/pdt_4.f03 +++ b/gcc/testsuite/gfortran.dg/pdt_4.f03 @@ -97,9 +97,9 @@ contains type (mytype(4, *)) :: arg ! OK end subroutine subroutine bar(arg) ! { dg-error "is neither allocatable nor a pointer" } - type (thytype(8, :, 4) :: arg + type (thytype(8, :, 4)) :: arg end subroutine subroutine foobar(arg) ! OK - type (thytype(8, *, 4) :: arg + type (thytype(8, *, 4)) :: arg end subroutine end diff --git a/gcc/testsuite/gfortran.dg/pr91660_1.f90 b/gcc/testsuite/gfortran.dg/pr91660_1.f90 new file mode 100644 index 0000000..53a1a80 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr91660_1.f90 @@ -0,0 +1,9 @@ +! { dg-do compile } +! PR fortran/91660 +! Code contributed by Gerhard Steinmetz +program p + type t + end type + type (t x ! { dg-error "Malformed type-spec" } + x = t() ! { dg-error "Cannot convert" } +end diff --git a/gcc/testsuite/gfortran.dg/pr91660_2.f90 b/gcc/testsuite/gfortran.dg/pr91660_2.f90 new file mode 100644 index 0000000..0072aba --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr91660_2.f90 @@ -0,0 +1,9 @@ +! { dg-do compile } +! PR fortran/91660 +program foo + type(doubleprecision :: x ! { dg-error "Malformed type-spec" } + type(double precision :: y ! { dg-error "Malformed type-spec" } + type(character(len=3) :: a ! { dg-error "Malformed type-spec" } + type(doublecomplex :: b ! { dg-error "Malformed type-spec" } + type(double complex :: c ! { dg-error "Malformed type-spec" } +end program foo -- cgit v1.1 From 3c0f026505aca54c200b36870256c886b05eb4ff Mon Sep 17 00:00:00 2001 From: Harald Anlauf Date: Thu, 5 Sep 2019 20:13:00 +0000 Subject: re PR fortran/91496 (!GCC$ directives error if mistyped or unknown) 2019-09-05 Harald Anlauf PR fortran/91496 * parse.c (parse_executable): Improve error messages for improperly placed pragmas not preceeding a loop. PR fortran/91496 * gfortran.dg/directive_unroll_5.f90: Adjust error message. From-SVN: r275442 --- gcc/fortran/ChangeLog | 6 ++++++ gcc/fortran/parse.c | 9 +++++---- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gfortran.dg/directive_unroll_5.f90 | 2 +- 4 files changed, 17 insertions(+), 5 deletions(-) (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 129bfdd..9c787f7 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,9 @@ +2019-09-05 Harald Anlauf + + PR fortran/91496 + * parse.c (parse_executable): Improve error messages for + improperly placed pragmas not preceeding a loop. + 2019-09-05 Steven G. Kargl PR fortran/91660 diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c index caea16b..5bd04b8 100644 --- a/gcc/fortran/parse.c +++ b/gcc/fortran/parse.c @@ -5541,16 +5541,17 @@ parse_executable (gfc_statement st) } if (directive_unroll != -1) - gfc_error ("% directive does not commence a loop at %C"); + gfc_error ("% directive not at the start of a loop at %C"); if (directive_ivdep) - gfc_error ("% directive does not commence a loop at %C"); + gfc_error ("% directive not at the start of a loop at %C"); if (directive_vector) - gfc_error ("% directive does not commence a loop at %C"); + gfc_error ("% directive not at the start of a loop at %C"); if (directive_novector) - gfc_error ("% directive does not commence a loop at %C"); + gfc_error ("% " + "directive not at the start of a loop at %C"); st = next_statement (); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a43cec3..faf5f15 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-05 Harald Anlauf + + PR fortran/91496 + * gfortran.dg/directive_unroll_5.f90: Adjust error message. + 2019-09-05 Steven G. Kargl PR fortran/91660 diff --git a/gcc/testsuite/gfortran.dg/directive_unroll_5.f90 b/gcc/testsuite/gfortran.dg/directive_unroll_5.f90 index b88b4b2..33f2fda5 100644 --- a/gcc/testsuite/gfortran.dg/directive_unroll_5.f90 +++ b/gcc/testsuite/gfortran.dg/directive_unroll_5.f90 @@ -31,7 +31,7 @@ subroutine wrong3(a, b, n) integer :: a(n), b(n) integer (kind=4) :: i !GCC$ unroll 8 - write (*,*) "wrong"! { dg-error "directive does not commence a loop" } + write (*,*) "wrong"! { dg-error "directive not at the start of a loop" } DO i=n, 1, -1 call dummy2(a(i), b(i), i) ENDDO -- cgit v1.1 From 36ec3f57d305e343ad1bbffa53e3484661a176a6 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 5 Sep 2019 22:32:55 +0200 Subject: RISC-V: Fix bad insn splits with paradoxical subregs. Shifting by more than the size of a SUBREG_REG doesn't work, so we either need to disable splits if an input is paradoxical, or else we need to generate a clean temporary for intermediate results. Jakub wrote the first version of this patch, so gets primary credit for it. gcc/ PR target/91635 * config/riscv/riscv.md (zero_extendsidi2, zero_extendhi2, extend2): Don't split if paradoxical_subreg_p (operands[0]). (*lshrsi3_zero_extend_3+1, *lshrsi3_zero_extend_3+2): Add clobber and use as intermediate value. gcc/testsuite/ PR target/91635 * gcc.c-torture/execute/pr91635.c: New test. * gcc.target/riscv/shift-shift-4.c: New test. * gcc.target/riscv/shift-shift-5.c: New test. Co-Authored-By: Jim Wilson From-SVN: r275444 --- gcc/ChangeLog | 10 +++++ gcc/config/riscv/riscv.md | 30 ++++++++++---- gcc/testsuite/ChangeLog | 8 ++++ gcc/testsuite/gcc.c-torture/execute/pr91635.c | 57 ++++++++++++++++++++++++++ gcc/testsuite/gcc.target/riscv/shift-shift-4.c | 13 ++++++ gcc/testsuite/gcc.target/riscv/shift-shift-5.c | 16 ++++++++ 6 files changed, 125 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr91635.c create mode 100644 gcc/testsuite/gcc.target/riscv/shift-shift-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/shift-shift-5.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 805a24f..d0686d0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2019-09-05 Jakub Jelinek + Jim Wilson + + PR target/91635 + * config/riscv/riscv.md (zero_extendsidi2, zero_extendhi2, + extend2): Don't split if + paradoxical_subreg_p (operands[0]). + (*lshrsi3_zero_extend_3+1, *lshrsi3_zero_extend_3+2): Add clobber and + use as intermediate value. + 2019-09-05 Andrew Stubbs * config/gcn/gcn.md (*movti_insn): Set delayeduse for global_store. diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 78260fc..744a027 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -1051,7 +1051,9 @@ "@ # lwu\t%0,%1" - "&& reload_completed && REG_P (operands[1])" + "&& reload_completed + && REG_P (operands[1]) + && !paradoxical_subreg_p (operands[0])" [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 32))) (set (match_dup 0) @@ -1068,7 +1070,9 @@ "@ # lhu\t%0,%1" - "&& reload_completed && REG_P (operands[1])" + "&& reload_completed + && REG_P (operands[1]) + && !paradoxical_subreg_p (operands[0])" [(set (match_dup 0) (ashift:GPR (match_dup 1) (match_dup 2))) (set (match_dup 0) @@ -1117,7 +1121,9 @@ "@ # l\t%0,%1" - "&& reload_completed && REG_P (operands[1])" + "&& reload_completed + && REG_P (operands[1]) + && !paradoxical_subreg_p (operands[0])" [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2))) (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))] { @@ -1766,15 +1772,20 @@ ;; Handle AND with 2^N-1 for N from 12 to XLEN. This can be split into ;; two logical shifts. Otherwise it requires 3 instructions: lui, ;; xor/addi/srli, and. + +;; Generating a temporary for the shift output gives better combiner results; +;; and also fixes a problem where op0 could be a paradoxical reg and shifting +;; by amounts larger than the size of the SUBREG_REG doesn't work. (define_split [(set (match_operand:GPR 0 "register_operand") (and:GPR (match_operand:GPR 1 "register_operand") - (match_operand:GPR 2 "p2m1_shift_operand")))] + (match_operand:GPR 2 "p2m1_shift_operand"))) + (clobber (match_operand:GPR 3 "register_operand"))] "" - [(set (match_dup 0) + [(set (match_dup 3) (ashift:GPR (match_dup 1) (match_dup 2))) (set (match_dup 0) - (lshiftrt:GPR (match_dup 0) (match_dup 2)))] + (lshiftrt:GPR (match_dup 3) (match_dup 2)))] { /* Op2 is a VOIDmode constant, so get the mode size from op1. */ operands[2] = GEN_INT (GET_MODE_BITSIZE (GET_MODE (operands[1])) @@ -1786,12 +1797,13 @@ (define_split [(set (match_operand:DI 0 "register_operand") (and:DI (match_operand:DI 1 "register_operand") - (match_operand:DI 2 "high_mask_shift_operand")))] + (match_operand:DI 2 "high_mask_shift_operand"))) + (clobber (match_operand:DI 3 "register_operand"))] "TARGET_64BIT" - [(set (match_dup 0) + [(set (match_dup 3) (lshiftrt:DI (match_dup 1) (match_dup 2))) (set (match_dup 0) - (ashift:DI (match_dup 0) (match_dup 2)))] + (ashift:DI (match_dup 3) (match_dup 2)))] { operands[2] = GEN_INT (ctz_hwi (INTVAL (operands[2]))); }) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index faf5f15..e591a27 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2019-09-05 Jakub Jelinek + Jim Wilson + + PR target/91635 + * gcc.c-torture/execute/pr91635.c: New test. + * gcc.target/riscv/shift-shift-4.c: New test. + * gcc.target/riscv/shift-shift-5.c: New test. + 2019-09-05 Harald Anlauf PR fortran/91496 diff --git a/gcc/testsuite/gcc.c-torture/execute/pr91635.c b/gcc/testsuite/gcc.c-torture/execute/pr91635.c new file mode 100644 index 0000000..878a491 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr91635.c @@ -0,0 +1,57 @@ +/* PR target/91635 */ + +#if __CHAR_BIT__ == 8 && __SIZEOF_SHORT__ == 2 \ + && __SIZEOF_INT__ == 4 && __SIZEOF_LONG_LONG__ == 8 +unsigned short b, c; +int u, v, w, x; + +__attribute__ ((noipa)) int +foo (unsigned short c) +{ + c <<= __builtin_add_overflow (-c, -1, &b); + c >>= 1; + return c; +} + +__attribute__ ((noipa)) int +bar (unsigned short b) +{ + b <<= -14 & 15; + b = b >> -~1; + return b; +} + +__attribute__ ((noipa)) int +baz (unsigned short e) +{ + e <<= 1; + e >>= __builtin_add_overflow (8719476735, u, &v); + return e; +} + +__attribute__ ((noipa)) int +qux (unsigned int e) +{ + c = ~1; + c *= e; + c = c >> (-15 & 5); + return c + w + x; +} +#endif + +int +main () +{ +#if __CHAR_BIT__ == 8 && __SIZEOF_SHORT__ == 2 \ + && __SIZEOF_INT__ == 4 && __SIZEOF_LONG_LONG__ == 8 + if (foo (0xffff) != 0x7fff) + __builtin_abort (); + if (bar (5) != 5) + __builtin_abort (); + if (baz (~0) != 0x7fff) + __builtin_abort (); + if (qux (2) != 0x7ffe) + __builtin_abort (); +#endif + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/shift-shift-4.c b/gcc/testsuite/gcc.target/riscv/shift-shift-4.c new file mode 100644 index 0000000..72a45ee --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/shift-shift-4.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32i -mabi=ilp32 -O2" } */ + +/* One zero-extend shift can be eliminated by modifying the constant in the + greater than test. Started working after modifying the splitter + lshrsi3_zero_extend_3+1 to use a temporary reg for the first split dest. */ +int +sub (int i) +{ + i &= 0x7fffffff; + return i > 0x7f800000; +} +/* { dg-final { scan-assembler-not "srli" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/shift-shift-5.c b/gcc/testsuite/gcc.target/riscv/shift-shift-5.c new file mode 100644 index 0000000..5b2ae89 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/shift-shift-5.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O2" } */ + +/* Fails if lshrsi3_zero_extend_3+1 uses a temp reg which has no REG_DEST + note. */ +unsigned long +sub (long l) +{ + union u { + struct s { int a : 19; unsigned int b : 13; int x; } s; + long l; + } u; + u.l = l; + return u.s.b; +} +/* { dg-final { scan-assembler "srliw" } } */ -- cgit v1.1 From ebd247d4b3813f3d1ab83d04e338ed566d10de3e Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Fri, 6 Sep 2019 00:16:38 +0000 Subject: Daily bump. From-SVN: r275449 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 59cbaa8..445ed44 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20190905 +20190906 -- cgit v1.1 From 67f6e64994b49ec330708e1655065dbd9741e1d6 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Fri, 6 Sep 2019 08:58:42 +0200 Subject: Remove support for repo files (PR c++/91125). 2019-09-06 Martin Liska PR c++/91125 * Makefile.in: Remove tlink.o. * collect2.c (do_link): New function isolated from do_tlink. (main): Use. * collect2.h (do_tlink): Remove declaration of do_tlink. * doc/extend.texi: Remove documentation of -frepo. * doc/invoke.texi: Likewise. * doc/sourcebuild.texi: Remove cleanup-repo-files. * tlink.c: Remove. 2019-09-06 Martin Liska PR c++/91125 * c-common.c: Remove definition of flag_use_repository. * c-common.h: Likewise. * c-opts.c (c_common_handle_option): Do not handle OPT_frepo option. * c.opt: Mark the option with Deprecated. 2019-09-06 Martin Liska PR c++/91125 * Make-lang.in: Remove repo.o. * config-lang.in: Likewise. * cp-tree.h (init_repo): Remove declarations of repo-related functions. (repo_emit_p): Likewise. (repo_export_class_p): Likewise. (finish_repo): Likewise. * decl2.c (import_export_class): Always set -1 value/ (mark_needed): Remove -frepo from comment. (import_export_decl): Similarly here. (c_parse_final_cleanups): Remove call of finish_repo. * lex.c (cxx_init): Remove call to init_repo. * optimize.c (can_alias_cdtor): Remove dead condition. * pt.c (push_template_decl_real): Update comment. (instantiate_decl): Remove dead code used for -frepo. * repo.c: Remove. 2019-09-06 Martin Liska PR c++/91125 * g++.dg/parse/repo1.C: Remove. * g++.dg/rtti/repo1.C: Remove. * g++.dg/template/repo1.C: Remove. * g++.dg/template/repo10.C: Remove. * g++.dg/template/repo11.C: Remove. * g++.dg/template/repo2.C: Remove. * g++.dg/template/repo3.C: Remove. * g++.dg/template/repo4.C: Remove. * g++.dg/template/repo5.C: Remove. * g++.dg/template/repo6.C: Remove. * g++.dg/template/repo7.C: Remove. * g++.dg/template/repo8.C: Remove. * g++.dg/template/repo9.C: Remove. * g++.old-deja/g++.pt/instantiate4.C: Remove. * g++.old-deja/g++.pt/instantiate6.C: Remove. * g++.old-deja/g++.pt/repo1.C: Remove. * g++.old-deja/g++.pt/repo2.C: Remove. * g++.old-deja/g++.pt/repo3.C: Remove. * g++.old-deja/g++.pt/repo4.C: Remove. * lib/g++.exp: Remove removal of repo files. * lib/gcc-dg.exp: Likewise. * lib/obj-c++.exp: Likewise. From-SVN: r275450 --- gcc/ChangeLog | 13 + gcc/Makefile.in | 2 +- gcc/c-family/ChangeLog | 9 + gcc/c-family/c-common.c | 5 - gcc/c-family/c-common.h | 5 - gcc/c-family/c-opts.c | 6 - gcc/c-family/c.opt | 4 +- gcc/collect2.c | 36 +- gcc/collect2.h | 4 +- gcc/cp/ChangeLog | 21 + gcc/cp/Make-lang.in | 2 +- gcc/cp/config-lang.in | 2 +- gcc/cp/cp-tree.h | 6 - gcc/cp/decl2.c | 37 +- gcc/cp/lex.c | 2 - gcc/cp/optimize.c | 3 - gcc/cp/pt.c | 18 +- gcc/cp/repo.c | 374 ---------- gcc/doc/extend.texi | 25 - gcc/doc/invoke.texi | 8 +- gcc/doc/sourcebuild.texi | 3 - gcc/testsuite/ChangeLog | 26 + gcc/testsuite/g++.dg/parse/repo1.C | 10 - gcc/testsuite/g++.dg/rtti/repo1.C | 19 - gcc/testsuite/g++.dg/template/repo1.C | 20 - gcc/testsuite/g++.dg/template/repo10.C | 16 - gcc/testsuite/g++.dg/template/repo11.C | 31 - gcc/testsuite/g++.dg/template/repo2.C | 18 - gcc/testsuite/g++.dg/template/repo3.C | 11 - gcc/testsuite/g++.dg/template/repo4.C | 18 - gcc/testsuite/g++.dg/template/repo5.C | 14 - gcc/testsuite/g++.dg/template/repo6.C | 26 - gcc/testsuite/g++.dg/template/repo7.C | 25 - gcc/testsuite/g++.dg/template/repo8.C | 24 - gcc/testsuite/g++.dg/template/repo9.C | 49 -- gcc/testsuite/g++.old-deja/g++.pt/instantiate4.C | 31 - gcc/testsuite/g++.old-deja/g++.pt/instantiate6.C | 29 - gcc/testsuite/g++.old-deja/g++.pt/repo1.C | 24 - gcc/testsuite/g++.old-deja/g++.pt/repo2.C | 28 - gcc/testsuite/g++.old-deja/g++.pt/repo3.C | 39 - gcc/testsuite/g++.old-deja/g++.pt/repo4.C | 19 - gcc/testsuite/lib/g++.exp | 6 - gcc/testsuite/lib/gcc-dg.exp | 26 - gcc/testsuite/lib/obj-c++.exp | 6 - gcc/tlink.c | 867 ----------------------- 45 files changed, 112 insertions(+), 1855 deletions(-) delete mode 100644 gcc/cp/repo.c delete mode 100644 gcc/testsuite/g++.dg/parse/repo1.C delete mode 100644 gcc/testsuite/g++.dg/rtti/repo1.C delete mode 100644 gcc/testsuite/g++.dg/template/repo1.C delete mode 100644 gcc/testsuite/g++.dg/template/repo10.C delete mode 100644 gcc/testsuite/g++.dg/template/repo11.C delete mode 100644 gcc/testsuite/g++.dg/template/repo2.C delete mode 100644 gcc/testsuite/g++.dg/template/repo3.C delete mode 100644 gcc/testsuite/g++.dg/template/repo4.C delete mode 100644 gcc/testsuite/g++.dg/template/repo5.C delete mode 100644 gcc/testsuite/g++.dg/template/repo6.C delete mode 100644 gcc/testsuite/g++.dg/template/repo7.C delete mode 100644 gcc/testsuite/g++.dg/template/repo8.C delete mode 100644 gcc/testsuite/g++.dg/template/repo9.C delete mode 100644 gcc/testsuite/g++.old-deja/g++.pt/instantiate4.C delete mode 100644 gcc/testsuite/g++.old-deja/g++.pt/instantiate6.C delete mode 100644 gcc/testsuite/g++.old-deja/g++.pt/repo1.C delete mode 100644 gcc/testsuite/g++.old-deja/g++.pt/repo2.C delete mode 100644 gcc/testsuite/g++.old-deja/g++.pt/repo3.C delete mode 100644 gcc/testsuite/g++.old-deja/g++.pt/repo4.C delete mode 100644 gcc/tlink.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d0686d0..233072e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2019-09-06 Martin Liska + + PR c++/91125 + * Makefile.in: Remove tlink.o. + * collect2.c (do_link): New function isolated + from do_tlink. + (main): Use. + * collect2.h (do_tlink): Remove declaration of do_tlink. + * doc/extend.texi: Remove documentation of -frepo. + * doc/invoke.texi: Likewise. + * doc/sourcebuild.texi: Remove cleanup-repo-files. + * tlink.c: Remove. + 2019-09-05 Jakub Jelinek Jim Wilson diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 597dc01..99d88a4 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2118,7 +2118,7 @@ gcc-ranlib.c: gcc-ar.c gcc-nm.c: gcc-ar.c cp $^ $@ -COLLECT2_OBJS = collect2.o collect2-aix.o tlink.o vec.o ggc-none.o \ +COLLECT2_OBJS = collect2.o collect2-aix.o vec.o ggc-none.o \ collect-utils.o file-find.o hash-table.o selftest.o COLLECT2_LIBS = @COLLECT2_LIBS@ collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS) diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 2720e64..6e20cb4 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,12 @@ +2019-09-06 Martin Liska + + PR c++/91125 + * c-common.c: Remove definition of flag_use_repository. + * c-common.h: Likewise. + * c-opts.c (c_common_handle_option): + Do not handle OPT_frepo option. + * c.opt: Mark the option with Deprecated. + 2019-09-04 Marek Polacek * c.opt (fdeduce-init-list): Ignored. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index abc85cb..3756219 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -249,11 +249,6 @@ const char *constant_string_class_name; int warn_abi_version = -1; -/* Nonzero means generate separate instantiation control files and - juggle them at link time. */ - -int flag_use_repository; - /* The C++ dialect being used. Default set in c_common_post_options. */ enum cxx_dialect cxx_dialect = cxx_unset; diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 17bd7b1..a9f4d0c 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -701,11 +701,6 @@ extern int warn_abi_version; != (warn_abi_version == 0 \ || warn_abi_version >= (N))) -/* Nonzero means generate separate instantiation control files and - juggle them at link time. */ - -extern int flag_use_repository; - /* The supported C++ dialects. */ enum cxx_dialect { diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c index fa8cd0c..23ab4cf 100644 --- a/gcc/c-family/c-opts.c +++ b/gcc/c-family/c-opts.c @@ -501,12 +501,6 @@ c_common_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value, cpp_opts->track_macro_expansion = 2; break; - case OPT_frepo: - flag_use_repository = value; - if (value) - flag_implicit_templates = 0; - break; - case OPT_ftabstop_: /* It is documented that we silently ignore silly values. */ if (value >= 1 && value <= 100) diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 143833d..ec54666 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -1763,8 +1763,8 @@ ObjC ObjC++ LTO Var(flag_replace_objc_classes) Used in Fix-and-Continue mode to indicate that object files may be swapped in at runtime. frepo -C++ ObjC++ -Enable automatic template instantiation. +C++ ObjC++ Deprecated +Deprecated in GCC 10. This switch has no effect. frtti C++ ObjC++ Optimization Var(flag_rtti) Init(1) diff --git a/gcc/collect2.c b/gcc/collect2.c index e25e339..4972072 100644 --- a/gcc/collect2.c +++ b/gcc/collect2.c @@ -825,6 +825,30 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst, else post_ld_pass (false); /* No LTO objects were found, no temp file. */ } +/* Entry point for linker invoation. Called from main in collect2.c. + LD_ARGV is an array of arguments for the linker. */ + +static void +do_link (char **ld_argv) +{ + struct pex_obj *pex; + const char *prog = "ld"; + pex = collect_execute (prog, ld_argv, NULL, NULL, + PEX_LAST | PEX_SEARCH, + HAVE_GNU_LD && at_file_supplied); + int ret = collect_wait (prog, pex); + if (ret) + { + error ("ld returned %d exit status", ret); + exit (ret); + } + else + { + /* We have just successfully produced an output file, so assume that we + may unlink it if need be for now on. */ + may_unlink_output_file = true; + } +} /* Main program. */ @@ -1704,7 +1728,7 @@ main (int argc, char **argv) functions from precise cross reference insertions by the compiler. */ if (early_exit || ld1_filter != SCAN_NOTHING) - do_tlink (ld1_argv, object_lst); + do_link (ld1_argv); if (early_exit) { @@ -1762,10 +1786,10 @@ main (int argc, char **argv) #endif ) { - /* Do tlink without additional code generation now if we didn't + /* Do link without additional code generation now if we didn't do it earlier for scanning purposes. */ if (ld1_filter == SCAN_NOTHING) - do_tlink (ld1_argv, object_lst); + do_link (ld1_argv); if (lto_mode) maybe_run_lto_and_relink (ld1_argv, object_lst, object, false); @@ -1868,13 +1892,13 @@ main (int argc, char **argv) fork_execute ("gcc", c_argv, at_file_supplied); #ifdef COLLECT_EXPORT_LIST - /* On AIX we must call tlink because of possible templates resolution. */ - do_tlink (ld2_argv, object_lst); + /* On AIX we must call link because of possible templates resolution. */ + do_link (ld2_argv); if (lto_mode) maybe_run_lto_and_relink (ld2_argv, object_lst, object, false); #else - /* Otherwise, simply call ld because tlink is already done. */ + /* Otherwise, simply call ld because link is already done. */ if (lto_mode) maybe_run_lto_and_relink (ld2_argv, object_lst, object, true); else diff --git a/gcc/collect2.h b/gcc/collect2.h index 34d17c2..77bb645 100644 --- a/gcc/collect2.h +++ b/gcc/collect2.h @@ -1,4 +1,4 @@ -/* Header file for collect/tlink routines. +/* Header file for collect routines. Copyright (C) 1998-2019 Free Software Foundation, Inc. This file is part of GCC. @@ -20,8 +20,6 @@ along with GCC; see the file COPYING3. If not see #ifndef GCC_COLLECT2_H #define GCC_COLLECT2_H -extern void do_tlink (char **, char **); - extern struct pex_obj *collect_execute (const char *, char **, const char *, const char *, int flags); diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 31a04ef..c1c7282 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,24 @@ +2019-09-06 Martin Liska + + PR c++/91125 + * Make-lang.in: Remove repo.o. + * config-lang.in: Likewise. + * cp-tree.h (init_repo): Remove declarations + of repo-related functions. + (repo_emit_p): Likewise. + (repo_export_class_p): Likewise. + (finish_repo): Likewise. + * decl2.c (import_export_class): Always + set -1 value/ + (mark_needed): Remove -frepo from comment. + (import_export_decl): Similarly here. + (c_parse_final_cleanups): Remove call of finish_repo. + * lex.c (cxx_init): Remove call to init_repo. + * optimize.c (can_alias_cdtor): Remove dead condition. + * pt.c (push_template_decl_real): Update comment. + (instantiate_decl): Remove dead code used for -frepo. + * repo.c: Remove. + 2019-09-05 Marek Polacek PR c++/91644 - ICE with constinit in function template. diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index 8fc1570..8430c4c 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -83,7 +83,7 @@ CXX_AND_OBJCXX_OBJS = \ cp/mangle.o cp/method.o \ cp/name-lookup.o cp/optimize.o \ cp/parser.o cp/pt.o cp/ptree.o \ - cp/repo.o cp/rtti.o \ + cp/rtti.o \ cp/search.o cp/semantics.o \ cp/tree.o cp/typeck.o cp/typeck2.o \ cp/vtable-class-hierarchy.o $(CXX_C_OBJS) diff --git a/gcc/cp/config-lang.in b/gcc/cp/config-lang.in index 4526d1a..6e5f046 100644 --- a/gcc/cp/config-lang.in +++ b/gcc/cp/config-lang.in @@ -49,7 +49,7 @@ gtfiles="\ \$(srcdir)/cp/mangle.c \$(srcdir)/cp/method.c \ \$(srcdir)/cp/name-lookup.c \ \$(srcdir)/cp/parser.c \$(srcdir)/cp/pt.c \ -\$(srcdir)/cp/repo.c \$(srcdir)/cp/rtti.c \ +\$(srcdir)/cp/rtti.c \ \$(srcdir)/cp/semantics.c \ \$(srcdir)/cp/tree.c \$(srcdir)/cp/typeck2.c \ \$(srcdir)/cp/vtable-class-hierarchy.c \ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 038f58d..a045214 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6903,12 +6903,6 @@ extern bool copy_guide_p (const_tree); extern bool template_guide_p (const_tree); extern void store_explicit_specifier (tree, tree); -/* in repo.c */ -extern void init_repo (void); -extern int repo_emit_p (tree); -extern bool repo_export_class_p (const_tree); -extern void finish_repo (void); - /* in rtti.c */ /* A vector of all tinfo decls that haven't been emitted yet. */ extern GTY(()) vec *unemitted_tinfo_decls; diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 36c6f4c..d4bb881 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2079,7 +2079,7 @@ import_export_class (tree ctype) repository. If the virtual table is assigned to this translation unit, then export the class; otherwise, import it. */ - import_export = repo_export_class_p (ctype) ? 1 : -1; + import_export = -1; else if (TYPE_POLYMORPHIC_P (ctype)) { /* The ABI specifies that the virtual table and associated @@ -2135,7 +2135,7 @@ mark_needed (tree decl) struct cgraph_node *node = cgraph_node::get_create (decl); node->forced_by_abi = true; - /* #pragma interface and -frepo code can call mark_needed for + /* #pragma interface can call mark_needed for maybe-in-charge 'tors; mark the clones as well. */ tree clone; FOR_EACH_CLONE (clone, decl) @@ -2969,7 +2969,6 @@ tentative_decl_linkage (tree decl) void import_export_decl (tree decl) { - int emit_p; bool comdat_p; bool import_p; tree class_type = NULL_TREE; @@ -2980,11 +2979,7 @@ import_export_decl (tree decl) /* We cannot determine what linkage to give to an entity with vague linkage until the end of the file. For example, a virtual table for a class will be defined if and only if the key method is - defined in this translation unit. As a further example, consider - that when compiling a translation unit that uses PCH file with - "-frepo" it would be incorrect to make decisions about what - entities to emit when building the PCH; those decisions must be - delayed until the repository information has been processed. */ + defined in this translation unit. */ gcc_assert (at_eof); /* Object file linkage for explicit instantiations is handled in mark_decl_instantiated. For static variables in functions with @@ -3030,27 +3025,7 @@ import_export_decl (tree decl) unit. */ import_p = false; - /* See if the repository tells us whether or not to emit DECL in - this translation unit. */ - emit_p = repo_emit_p (decl); - if (emit_p == 0) - import_p = true; - else if (emit_p == 1) - { - /* The repository indicates that this entity should be defined - here. Make sure the back end honors that request. */ - mark_needed (decl); - /* Output the definition as an ordinary strong definition. */ - DECL_EXTERNAL (decl) = 0; - DECL_INTERFACE_KNOWN (decl) = 1; - return; - } - - if (import_p) - /* We have already decided what to do with this DECL; there is no - need to check anything further. */ - ; - else if (VAR_P (decl) && DECL_VTABLE_OR_VTT_P (decl)) + if (VAR_P (decl) && DECL_VTABLE_OR_VTT_P (decl)) { class_type = DECL_CONTEXT (decl); import_export_class (class_type); @@ -3156,8 +3131,7 @@ import_export_decl (tree decl) { /* DECL is an implicit instantiation of a function or static data member. */ - if ((flag_implicit_templates - && !flag_use_repository) + if (flag_implicit_templates || (flag_implicit_inline_templates && TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl))) @@ -5142,7 +5116,6 @@ c_parse_final_cleanups (void) perform_deferred_noexcept_checks (); - finish_repo (); fini_constexpr (); /* The entire file is now complete. If requested, dump everything diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 5b43723..25529e7ab 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -332,8 +332,6 @@ cxx_init (void) init_cp_pragma (); - init_repo (); - input_location = saved_loc; return true; } diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c index 0774857..994ee91 100644 --- a/gcc/cp/optimize.c +++ b/gcc/cp/optimize.c @@ -223,9 +223,6 @@ can_alias_cdtor (tree fn) /* We can't use an alias if there are virtual bases. */ if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn))) return false; - /* ??? Why not use aliases with -frepo? */ - if (flag_use_repository) - return false; gcc_assert (DECL_MAYBE_IN_CHARGE_CDTOR_P (fn)); /* Don't use aliases for weak/linkonce definitions unless we can put both symbols in the same COMDAT group. */ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index cec9798..c5915a5 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -5835,7 +5835,7 @@ push_template_decl_real (tree decl, bool is_friend) && TREE_PUBLIC (decl) && VAR_OR_FUNCTION_DECL_P (decl)) /* Set DECL_COMDAT on template instantiations; if we force - them to be emitted by explicit instantiation or -frepo, + them to be emitted by explicit instantiation, mark_needed will tell cgraph to do the right thing. */ DECL_COMDAT (decl) = true; @@ -24671,22 +24671,6 @@ instantiate_decl (tree d, bool defer_ok, bool expl_inst_class_mem_p) add_pending_template (d); goto out; } - /* Tell the repository that D is available in this translation unit - -- and see if it is supposed to be instantiated here. */ - if (TREE_PUBLIC (d) && !DECL_REALLY_EXTERN (d) && !repo_emit_p (d)) - { - /* In a PCH file, despite the fact that the repository hasn't - requested instantiation in the PCH it is still possible that - an instantiation will be required in a file that includes the - PCH. */ - if (pch_file) - add_pending_template (d); - /* Instantiate inline functions so that the inliner can do its - job, even though we'll not be emitting a copy of this - function. */ - if (!(TREE_CODE (d) == FUNCTION_DECL && possibly_inlined_p (d))) - goto out; - } bool push_to_top, nested; tree fn_context; diff --git a/gcc/cp/repo.c b/gcc/cp/repo.c deleted file mode 100644 index 4c44a07..0000000 --- a/gcc/cp/repo.c +++ /dev/null @@ -1,374 +0,0 @@ -/* Code to maintain a C++ template repository. - Copyright (C) 1995-2019 Free Software Foundation, Inc. - Contributed by Jason Merrill (jason@cygnus.com) - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -GCC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -/* My strategy here is as follows: - - Everything should be emitted in a translation unit where it is used. - The results of the automatic process should be easily reproducible with - explicit code. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "cp-tree.h" -#include "stringpool.h" -#include "toplev.h" - -static const char *extract_string (const char **); -static const char *get_base_filename (const char *); -static FILE *open_repo_file (const char *); -static char *afgets (FILE *); -static FILE *reopen_repo_file_for_write (void); - -static GTY(()) vec *pending_repo; -static char *repo_name; - -static const char *old_args, *old_dir, *old_main; - -static struct obstack temporary_obstack; -static bool temporary_obstack_initialized_p; - -/* Parse a reasonable subset of shell quoting syntax. */ - -static const char * -extract_string (const char **pp) -{ - const char *p = *pp; - int backquote = 0; - int inside = 0; - - for (;;) - { - char c = *p; - if (c == '\0') - break; - ++p; - if (backquote) - { - obstack_1grow (&temporary_obstack, c); - backquote = 0; - } - else if (! inside && c == ' ') - break; - else if (! inside && c == '\\') - backquote = 1; - else if (c == '\'') - inside = !inside; - else - obstack_1grow (&temporary_obstack, c); - } - - obstack_1grow (&temporary_obstack, '\0'); - *pp = p; - return (char *) obstack_finish (&temporary_obstack); -} - -static const char * -get_base_filename (const char *filename) -{ - const char *p = getenv ("COLLECT_GCC_OPTIONS"); - const char *output = NULL; - int compiling = 0; - - while (p && *p) - { - const char *q = extract_string (&p); - - if (strcmp (q, "-o") == 0) - { - if (flag_compare_debug) - /* Just in case aux_base_name was based on a name with two - or more '.'s, add an arbitrary extension that will be - stripped by the caller. */ - output = concat (aux_base_name, ".o", NULL); - else - output = extract_string (&p); - } - else if (strcmp (q, "-c") == 0) - compiling = 1; - } - - if (compiling && output) - return output; - - if (p && ! compiling) - { - warning (0, "%<-frepo%> must be used with %<-c%>"); - flag_use_repository = 0; - return NULL; - } - - return lbasename (filename); -} - -static FILE * -open_repo_file (const char *filename) -{ - const char *p; - const char *s = get_base_filename (filename); - - if (s == NULL) - return NULL; - - p = lbasename (s); - p = strrchr (p, '.'); - if (! p) - p = s + strlen (s); - - repo_name = XNEWVEC (char, p - s + 5); - memcpy (repo_name, s, p - s); - memcpy (repo_name + (p - s), ".rpo", 5); - - return fopen (repo_name, "r"); -} - -static char * -afgets (FILE *stream) -{ - int c; - while ((c = getc (stream)) != EOF && c != '\n') - obstack_1grow (&temporary_obstack, c); - if (obstack_object_size (&temporary_obstack) == 0) - return NULL; - obstack_1grow (&temporary_obstack, '\0'); - return (char *) obstack_finish (&temporary_obstack); -} - -void -init_repo (void) -{ - char *buf; - const char *p; - FILE *repo_file; - - if (! flag_use_repository) - return; - - /* When a PCH file is loaded, the entire identifier table is - replaced, with the result that IDENTIFIER_REPO_CHOSEN is cleared. - So, we have to reread the repository file. */ - lang_post_pch_load = init_repo; - - if (!temporary_obstack_initialized_p) - gcc_obstack_init (&temporary_obstack); - - repo_file = open_repo_file (main_input_filename); - - if (repo_file == 0) - return; - - while ((buf = afgets (repo_file))) - { - switch (buf[0]) - { - case 'A': - old_args = ggc_strdup (buf + 2); - break; - case 'D': - old_dir = ggc_strdup (buf + 2); - break; - case 'M': - old_main = ggc_strdup (buf + 2); - break; - case 'O': - /* A symbol that we were able to define the last time this - file was compiled. */ - break; - case 'C': - /* A symbol that the prelinker has requested that we - define. */ - { - tree id = get_identifier (buf + 2); - IDENTIFIER_REPO_CHOSEN (id) = 1; - } - break; - default: - error ("mysterious repository information in %s", repo_name); - } - obstack_free (&temporary_obstack, buf); - } - fclose (repo_file); - - if (old_args && !get_random_seed (true) - && (p = strstr (old_args, "'-frandom-seed="))) - set_random_seed (extract_string (&p) + strlen ("-frandom-seed=")); -} - -static FILE * -reopen_repo_file_for_write (void) -{ - FILE *repo_file = fopen (repo_name, "w"); - - if (repo_file == 0) - { - error ("cannot create repository information file %qs", repo_name); - flag_use_repository = 0; - } - - return repo_file; -} - -/* Emit any pending repos. */ - -void -finish_repo (void) -{ - tree val; - char *dir, *args; - FILE *repo_file; - unsigned ix; - - if (!flag_use_repository || flag_compare_debug) - return; - - if (seen_error ()) - return; - - repo_file = reopen_repo_file_for_write (); - if (repo_file == 0) - goto out; - - fprintf (repo_file, "M %s\n", main_input_filename); - dir = getpwd (); - fprintf (repo_file, "D %s\n", dir); - args = getenv ("COLLECT_GCC_OPTIONS"); - if (args) - { - fprintf (repo_file, "A %s", args); - /* If -frandom-seed is not among the ARGS, then add the value - that we chose. That will ensure that the names of types from - anonymous namespaces will get the same mangling when this - file is recompiled. */ - if (!strstr (args, "'-frandom-seed=")) - fprintf (repo_file, " '-frandom-seed=" HOST_WIDE_INT_PRINT_HEX_PURE "'", - get_random_seed (false)); - fprintf (repo_file, "\n"); - } - - FOR_EACH_VEC_SAFE_ELT_REVERSE (pending_repo, ix, val) - { - tree name = DECL_ASSEMBLER_NAME (val); - char type = IDENTIFIER_REPO_CHOSEN (name) ? 'C' : 'O'; - fprintf (repo_file, "%c %s\n", type, IDENTIFIER_POINTER (name)); - } - - out: - if (repo_file) - fclose (repo_file); -} - -/* DECL is a FUNCTION_DECL or VAR_DECL with vague linkage whose - definition is available in this translation unit. Returns 0 if - this definition should not be emitted in this translation unit - because it will be emitted elsewhere. Returns 1 if the repository - file indicates that that DECL should be emitted in this translation - unit, or 2 if the repository file is not in use. */ - -int -repo_emit_p (tree decl) -{ - int ret = 0; - gcc_assert (TREE_PUBLIC (decl)); - gcc_assert (VAR_OR_FUNCTION_DECL_P (decl)); - gcc_assert (!DECL_REALLY_EXTERN (decl) - /* A clone might not have its linkage flags updated yet - because we call import_export_decl before - maybe_clone_body. */ - || DECL_ABSTRACT_ORIGIN (decl)); - - /* When not using the repository, emit everything. */ - if (!flag_use_repository) - return 2; - - /* Only template instantiations are managed by the repository. This - is an artificial restriction; the code in the prelinker and here - will work fine if all entities with vague linkage are managed by - the repository. */ - if (VAR_P (decl)) - { - tree type = NULL_TREE; - if (DECL_VTABLE_OR_VTT_P (decl)) - type = DECL_CONTEXT (decl); - else if (DECL_TINFO_P (decl)) - type = TREE_TYPE (DECL_NAME (decl)); - if (!DECL_TEMPLATE_INSTANTIATION (decl) - && (!TYPE_LANG_SPECIFIC (type) - || !CLASSTYPE_TEMPLATE_INSTANTIATION (type))) - return 2; - /* Const static data members initialized by constant expressions must - be processed where needed so that their definitions are - available. Still record them into *.rpo files, so if they - weren't actually emitted and collect2 requests them, they can - be provided. */ - if (decl_maybe_constant_var_p (decl) - && DECL_CLASS_SCOPE_P (decl)) - ret = 2; - } - else if (!DECL_TEMPLATE_INSTANTIATION (decl)) - return 2; - - if (DECL_EXPLICIT_INSTANTIATION (decl)) - return 2; - - /* For constructors and destructors, the repository contains - information about the clones -- not the original function -- - because only the clones are emitted in the object file. */ - if (DECL_MAYBE_IN_CHARGE_CDTOR_P (decl)) - { - int emit_p = 0; - tree clone; - /* There is no early exit from this loop because we want to - ensure that all of the clones are marked as available in this - object file. */ - FOR_EACH_CLONE (clone, decl) - /* The only possible results from the recursive call to - repo_emit_p are 0 or 1. */ - if (repo_emit_p (clone)) - emit_p = 1; - return emit_p; - } - - /* Keep track of all available entities. */ - if (!DECL_REPO_AVAILABLE_P (decl)) - { - DECL_REPO_AVAILABLE_P (decl) = 1; - vec_safe_push (pending_repo, decl); - } - - return IDENTIFIER_REPO_CHOSEN (DECL_ASSEMBLER_NAME (decl)) ? 1 : ret; -} - -/* Returns true iff the prelinker has explicitly marked CLASS_TYPE for - export from this translation unit. */ - -bool -repo_export_class_p (const_tree class_type) -{ - if (!flag_use_repository) - return false; - if (!CLASSTYPE_VTABLES (class_type)) - return false; - /* If the virtual table has been assigned to this translation unit, - export the class. */ - return (IDENTIFIER_REPO_CHOSEN - (DECL_ASSEMBLER_NAME (CLASSTYPE_VTABLES (class_type)))); -} - -#include "gt-cp-repo.h" diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index cec15e5..a922f5c 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -24424,31 +24424,6 @@ alternative and programs using this approach will work with most modern compilers. @item -@opindex frepo -Compile your template-using code with @option{-frepo}. The compiler -generates files with the extension @samp{.rpo} listing all of the -template instantiations used in the corresponding object files that -could be instantiated there; the link wrapper, @samp{collect2}, -then updates the @samp{.rpo} files to tell the compiler where to place -those instantiations and rebuild any affected object files. The -link-time overhead is negligible after the first pass, as the compiler -continues to place the instantiations in the same files. - -This can be a suitable option for application code written for the Borland -model, as it usually just works. Code written for the Cfront model -needs to be modified so that the template definitions are available at -one or more points of instantiation; usually this is as simple as adding -@code{#include } to the end of each template header. - -For library code, if you want the library to provide all of the template -instantiations it needs, just try to link all of its object files -together; the link will fail, but cause the instantiations to be -generated as a side effect. Be warned, however, that this may cause -conflicts if multiple libraries try to provide the same instantiations. -For greater control, use explicit instantiation as described in the next -option. - -@item @opindex fno-implicit-templates Compile your code with @option{-fno-implicit-templates} to disable the implicit generation of template instances, and explicitly instantiate diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index fad19dd..bfcd76e 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -222,7 +222,7 @@ in the following sections. -fno-nonansi-builtins -fnothrow-opt -fno-operator-names @gol -fno-optional-diags -fpermissive @gol -fno-pretty-templates @gol --frepo -fno-rtti -fsized-deallocation @gol +-fno-rtti -fsized-deallocation @gol -ftemplate-backtrace-limit=@var{n} @gol -ftemplate-depth=@var{n} @gol -fno-threadsafe-statics -fuse-cxa-atexit @gol @@ -2701,12 +2701,6 @@ the default template arguments for that template. If either of these behaviors make it harder to understand the error message rather than easier, you can use @option{-fno-pretty-templates} to disable them. -@item -frepo -@opindex frepo -Enable automatic template instantiation at link time. This option also -implies @option{-fno-implicit-templates}. @xref{Template -Instantiation}, for more information. - @item -fno-rtti @opindex fno-rtti @opindex frtti diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi index 7867ac8..d713c08 100644 --- a/gcc/doc/sourcebuild.texi +++ b/gcc/doc/sourcebuild.texi @@ -2864,9 +2864,6 @@ int main() @{ return 0; @} @item cleanup-profile-file Removes profiling files generated for this test. -@item cleanup-repo-files -Removes files generated for this test for @option{-frepo}. - @end table @node Ada Tests diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e591a27..9a544bc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,29 @@ +2019-09-06 Martin Liska + + PR c++/91125 + * g++.dg/parse/repo1.C: Remove. + * g++.dg/rtti/repo1.C: Remove. + * g++.dg/template/repo1.C: Remove. + * g++.dg/template/repo10.C: Remove. + * g++.dg/template/repo11.C: Remove. + * g++.dg/template/repo2.C: Remove. + * g++.dg/template/repo3.C: Remove. + * g++.dg/template/repo4.C: Remove. + * g++.dg/template/repo5.C: Remove. + * g++.dg/template/repo6.C: Remove. + * g++.dg/template/repo7.C: Remove. + * g++.dg/template/repo8.C: Remove. + * g++.dg/template/repo9.C: Remove. + * g++.old-deja/g++.pt/instantiate4.C: Remove. + * g++.old-deja/g++.pt/instantiate6.C: Remove. + * g++.old-deja/g++.pt/repo1.C: Remove. + * g++.old-deja/g++.pt/repo2.C: Remove. + * g++.old-deja/g++.pt/repo3.C: Remove. + * g++.old-deja/g++.pt/repo4.C: Remove. + * lib/g++.exp: Remove removal of repo files. + * lib/gcc-dg.exp: Likewise. + * lib/obj-c++.exp: Likewise. + 2019-09-05 Jakub Jelinek Jim Wilson diff --git a/gcc/testsuite/g++.dg/parse/repo1.C b/gcc/testsuite/g++.dg/parse/repo1.C deleted file mode 100644 index efadd58..0000000 --- a/gcc/testsuite/g++.dg/parse/repo1.C +++ /dev/null @@ -1,10 +0,0 @@ -// { dg-options "-frepo" } -// { dg-require-host-local "" } - -extern "C" inline void f() {} - -int main () { - f(); -} - -// { dg-final { cleanup-repo-files } } diff --git a/gcc/testsuite/g++.dg/rtti/repo1.C b/gcc/testsuite/g++.dg/rtti/repo1.C deleted file mode 100644 index f72a973..0000000 --- a/gcc/testsuite/g++.dg/rtti/repo1.C +++ /dev/null @@ -1,19 +0,0 @@ -// PR c++/22204 -// { dg-options "-frepo" } -// { dg-require-host-local "" } -// { dg-skip-if "dkms are not final links" { vxworks_kernel } } - -#include -template -struct function1 -{ - function1() - { - typeid(int[100]); - } -}; -function1<1> b; - -int main () {} - -// { dg-final { cleanup-repo-files } } diff --git a/gcc/testsuite/g++.dg/template/repo1.C b/gcc/testsuite/g++.dg/template/repo1.C deleted file mode 100644 index 342993e..0000000 --- a/gcc/testsuite/g++.dg/template/repo1.C +++ /dev/null @@ -1,20 +0,0 @@ -// { dg-options "-frepo" } -// { dg-require-host-local "" } -// { dg-skip-if "dkms are not final links" { vxworks_kernel } } - -struct A { - A(); -}; - -A::A() {} - -template -struct B : public A { - B() {} // { dg-bogus "" } -}; - -B b; - -int main () {} - -// { dg-final { cleanup-repo-files } } diff --git a/gcc/testsuite/g++.dg/template/repo10.C b/gcc/testsuite/g++.dg/template/repo10.C deleted file mode 100644 index c92f7a5..0000000 --- a/gcc/testsuite/g++.dg/template/repo10.C +++ /dev/null @@ -1,16 +0,0 @@ -// PR c++/51910 -// { dg-options -frepo } -// { dg-require-host-local "" } -// { dg-skip-if "dkms are not final links" { vxworks_kernel } } -// { dg-final cleanup-repo-files } - -template -struct Foo -{ - virtual ~Foo() { } -}; - -int main( int, char*[] ) -{ - Foo test; -} diff --git a/gcc/testsuite/g++.dg/template/repo11.C b/gcc/testsuite/g++.dg/template/repo11.C deleted file mode 100644 index 5cabfd4..0000000 --- a/gcc/testsuite/g++.dg/template/repo11.C +++ /dev/null @@ -1,31 +0,0 @@ -// PR c++/64521 -// { dg-options "-frepo -std=c++11" } -// { dg-require-host-local "" } -// { dg-skip-if "dkms are not final links" { vxworks_kernel } } -// { dg-final cleanup-repo-files } - -template struct J { J(H) {} }; -template struct K; -template struct K {}; -template -struct K : K, J { - K(const H &p1, const T &... p2) : K(p2...), J(p1) {} -}; -template struct C : K<0, E...> { - C(const E &... p1) : K<0, E...>(p1...) {} -}; -template struct A { - A() = default; -}; -struct M; -template struct L { - struct B { - template static M *__test(...); - typedef A _Del; - typedef decltype(__test<_Del>()) type; - }; - C> _M_t; - L(typename B::type) : _M_t(0, A()) {} -}; -struct M {}; -int main() { L(new M); } diff --git a/gcc/testsuite/g++.dg/template/repo2.C b/gcc/testsuite/g++.dg/template/repo2.C deleted file mode 100644 index e322415..0000000 --- a/gcc/testsuite/g++.dg/template/repo2.C +++ /dev/null @@ -1,18 +0,0 @@ -// PR c++/17163 -// { dg-options "-frepo" } -// { dg-require-host-local "" } -// { dg-skip-if "dkms are not final links" { vxworks_kernel } } - -template -struct __Atomicity_lock -{ - static unsigned char _S_atomicity_lock; -}; -template -unsigned char __Atomicity_lock<__inst>::_S_atomicity_lock = 0; -template unsigned char __Atomicity_lock<0>::_S_atomicity_lock; - -int main () { -} - -// { dg-final { cleanup-repo-files } } diff --git a/gcc/testsuite/g++.dg/template/repo3.C b/gcc/testsuite/g++.dg/template/repo3.C deleted file mode 100644 index cfa38a9..0000000 --- a/gcc/testsuite/g++.dg/template/repo3.C +++ /dev/null @@ -1,11 +0,0 @@ -// { dg-options "-frepo -DF='a'" } -// { dg-require-host-local "" } -// { dg-skip-if "dkms are not final links" { vxworks_kernel } } - -template void f () {} -template void g () { f(); } -int main () { g(); } - -char c = F; - -// { dg-final { cleanup-repo-files } } diff --git a/gcc/testsuite/g++.dg/template/repo4.C b/gcc/testsuite/g++.dg/template/repo4.C deleted file mode 100644 index 64882a8..0000000 --- a/gcc/testsuite/g++.dg/template/repo4.C +++ /dev/null @@ -1,18 +0,0 @@ -// PR c++/17775 -// { dg-options "-frepo" } -// { dg-final { cleanup-repo-files } } -// { dg-require-host-local "" } -// { dg-skip-if "dkms are not final links" { vxworks_kernel } } - -namespace { - struct Foo {}; -} - -template -void foo(Tp) {} - -int -main() -{ - foo(Foo()); -} diff --git a/gcc/testsuite/g++.dg/template/repo5.C b/gcc/testsuite/g++.dg/template/repo5.C deleted file mode 100644 index e45ade7d..0000000 --- a/gcc/testsuite/g++.dg/template/repo5.C +++ /dev/null @@ -1,14 +0,0 @@ -// PR c++/25625 -// { dg-options "-frepo" } -// { dg-final { cleanup-repo-files } } -// { dg-require-host-local "" } -// { dg-skip-if "dkms are not final links" { vxworks_kernel } } - -template< typename T, T N > struct integral_c { - static const T value = N; - typedef integral_c< T, value + 1 > next; -}; -template< typename T, T N > T const integral_c< T, N >::value; -integral_c a; - -int main () {} diff --git a/gcc/testsuite/g++.dg/template/repo6.C b/gcc/testsuite/g++.dg/template/repo6.C deleted file mode 100644 index 4b7178e..0000000 --- a/gcc/testsuite/g++.dg/template/repo6.C +++ /dev/null @@ -1,26 +0,0 @@ -// PR c++/34178 -// { dg-options "-frepo" } -// { dg-final { cleanup-repo-files } } -// { dg-require-host-local "" } -// { dg-skip-if "dkms are not final links" { vxworks_kernel } } - -template -class A -{ -private: - static const int x; - static int y; - -public: - int getX () { return x + y; } -}; - -template const int A::x = 0; -template int A::y = 0; - -int -main () -{ - A a; - return a.getX(); -} diff --git a/gcc/testsuite/g++.dg/template/repo7.C b/gcc/testsuite/g++.dg/template/repo7.C deleted file mode 100644 index dafb3f5..0000000 --- a/gcc/testsuite/g++.dg/template/repo7.C +++ /dev/null @@ -1,25 +0,0 @@ -// PR c++/34340 -// { dg-options "-frepo" } -// { dg-final { cleanup-repo-files } } -// { dg-require-host-local "" } -// { dg-skip-if "dkms are not final links" { vxworks_kernel } } - -struct A -{ - int a; -}; - -template struct D -{ - static const A b; -}; - -template const A D::b = { 2 }; -template class D; - -const A *x = &D::b; - -int -main () -{ -} diff --git a/gcc/testsuite/g++.dg/template/repo8.C b/gcc/testsuite/g++.dg/template/repo8.C deleted file mode 100644 index c51592c..0000000 --- a/gcc/testsuite/g++.dg/template/repo8.C +++ /dev/null @@ -1,24 +0,0 @@ -// PR c++/34340 -// { dg-options "-frepo" } -// { dg-final { cleanup-repo-files } } -// { dg-require-host-local "" } -// { dg-skip-if "dkms are not final links" { vxworks_kernel } } - -struct A -{ - int a; -}; - -template struct D -{ - static const A b; -}; - -template const A D::b = { 2 }; - -const A *x = &D::b; - -int -main () -{ -} diff --git a/gcc/testsuite/g++.dg/template/repo9.C b/gcc/testsuite/g++.dg/template/repo9.C deleted file mode 100644 index 7ddc6bf..0000000 --- a/gcc/testsuite/g++.dg/template/repo9.C +++ /dev/null @@ -1,49 +0,0 @@ -// PR c++/36364 -// { dg-options "-frepo" } -// { dg-final { cleanup-repo-files } } -// { dg-require-host-local "" } -// { dg-skip-if "dkms are not final links" { vxworks_kernel } } - -template struct A -{ - static void assign (C &c1, const C &c2) { c1 = c2; } -}; - -template struct B -{ - struct D - { - static const C terminal; - static unsigned long stor[]; - static D &empty_rep () - { - void *p = reinterpret_cast (&stor); - return *reinterpret_cast (p); - } - void test (unsigned long n) - { - T::assign (this->refdata ()[n], terminal); - } - C *refdata () throw () - { - return reinterpret_cast (this + 1); - } - }; - C *dataplus; - C *data () const { return dataplus; } - D *rep () const { return &((reinterpret_cast < D * >(data ()))[-1]); } - static D & empty_rep () { return D::empty_rep (); } - B () : dataplus (empty_rep ().refdata ()) { } - ~B () { } - void push_back (C c) { rep ()->test (10); } -}; - -template const C B ::D::terminal = C (); -template unsigned long B ::D::stor[64]; - -int -main () -{ - B > s; - s.push_back ('a'); -} diff --git a/gcc/testsuite/g++.old-deja/g++.pt/instantiate4.C b/gcc/testsuite/g++.old-deja/g++.pt/instantiate4.C deleted file mode 100644 index d7a8cab..0000000 --- a/gcc/testsuite/g++.old-deja/g++.pt/instantiate4.C +++ /dev/null @@ -1,31 +0,0 @@ -// { dg-do link } -// { dg-options "-frepo -Werror" } -// { dg-require-host-local "" } -// { dg-skip-if "dkms are not final links" { vxworks_kernel } } - - -// Submitted by Melissa O'Neill -// the vtable of Foo wouldn't be generated - -template -struct Foo { - virtual void foo() {} -}; - -template -struct Bar { - void bar(); -}; - -template -void Bar::bar() { - Foo oof; -} - -int main () { - Bar rab; - - rab.bar(); -} - -// { dg-final { cleanup-repo-files } } diff --git a/gcc/testsuite/g++.old-deja/g++.pt/instantiate6.C b/gcc/testsuite/g++.old-deja/g++.pt/instantiate6.C deleted file mode 100644 index 6726b21..0000000 --- a/gcc/testsuite/g++.old-deja/g++.pt/instantiate6.C +++ /dev/null @@ -1,29 +0,0 @@ -// { dg-do link } -// { dg-options "-frepo" } -// { dg-require-host-local "" } -// { dg-skip-if "dkms are not final links" { vxworks_kernel } } - -// Simplified from testcase by Erez Louidor Lior - -template -class foo{ -public: - void g(); - void h(); -}; - -template -void foo::g() { - h(); -} - -template -void foo::h() { -} - -int main() { - foo f; - f.g(); -} - -// { dg-final { cleanup-repo-files } } diff --git a/gcc/testsuite/g++.old-deja/g++.pt/repo1.C b/gcc/testsuite/g++.old-deja/g++.pt/repo1.C deleted file mode 100644 index bdfe306b..0000000 --- a/gcc/testsuite/g++.old-deja/g++.pt/repo1.C +++ /dev/null @@ -1,24 +0,0 @@ -// { dg-do link } -// { dg-options "-frepo" } -// { dg-require-host-local "" } -// { dg-skip-if "dkms are not final links" { vxworks_kernel } } - -// Bug: g++ complains about duplicate explicit instantiations with -frepo. -// From Jason Merrill - -// Build then link: - -template struct A { - virtual ~A () { } -}; - -template void g (T t) { } - -template class A; - -int main () -{ - g (42); -} - -// { dg-final { cleanup-repo-files } } diff --git a/gcc/testsuite/g++.old-deja/g++.pt/repo2.C b/gcc/testsuite/g++.old-deja/g++.pt/repo2.C deleted file mode 100644 index a8d8b12..0000000 --- a/gcc/testsuite/g++.old-deja/g++.pt/repo2.C +++ /dev/null @@ -1,28 +0,0 @@ -// { dg-do link } -// { dg-options "-frepo" } -// { dg-require-host-local "" } -// { dg-skip-if "dkms are not final links" { vxworks_kernel } } - -// Test that collect2 isn't confused by GNU ld's "In function `foo':" message. -// Contributed by Jason Merrill - -// Build then link: - -template -T f (T t) -{ - return t; -} - -template -T g (T t) -{ - return f (t); -} - -int main () -{ - int i = g (42); -} - -// { dg-final { cleanup-repo-files } } diff --git a/gcc/testsuite/g++.old-deja/g++.pt/repo3.C b/gcc/testsuite/g++.old-deja/g++.pt/repo3.C deleted file mode 100644 index 2f62139..0000000 --- a/gcc/testsuite/g++.old-deja/g++.pt/repo3.C +++ /dev/null @@ -1,39 +0,0 @@ -// { dg-do link } -// { dg-options "-frepo" } -// { dg-require-host-local "" } -// { dg-skip-if "dkms are not final links" { vxworks_kernel } } - -// Test that we properly generate the vtable and such for C. -// Contributed by scott snyder - -// Build then link: - -struct A -{ - virtual ~A () {} -}; - -template -struct B : virtual public A -{ - virtual void foo () {} -}; - -template -struct C : virtual public A -{ -}; - -template -struct D : public B, public C -{ -}; - -int -main () -{ - D x; - return 0; -} - -// { dg-final { cleanup-repo-files } } diff --git a/gcc/testsuite/g++.old-deja/g++.pt/repo4.C b/gcc/testsuite/g++.old-deja/g++.pt/repo4.C deleted file mode 100644 index 84575cd..0000000 --- a/gcc/testsuite/g++.old-deja/g++.pt/repo4.C +++ /dev/null @@ -1,19 +0,0 @@ -// { dg-do link } -// { dg-options "-frepo" } -// { dg-require-host-local "" } -// { dg-skip-if "dkms are not final links" { vxworks_kernel } } - -template -struct S { - ~S (); -}; - -template -S::~S () {} - -int main () -{ - S s; -} - -// { dg-final { cleanup-repo-files } } diff --git a/gcc/testsuite/lib/g++.exp b/gcc/testsuite/lib/g++.exp index 1610442..bccabbc 100644 --- a/gcc/testsuite/lib/g++.exp +++ b/gcc/testsuite/lib/g++.exp @@ -317,12 +317,6 @@ proc g++_target_compile { source dest type options } { set options [concat "$ALWAYS_CXXFLAGS" $options] - if { [regexp "(^| )-frepo( |$)" $options] && \ - [regexp "\.o(|bj)$" $dest] } then { - regsub "\.o(|bj)$" $dest ".rpo" rponame - exec rm -f $rponame - } - # bind_pic_locally adds -fpie/-fPIE flags to flags_to_postpone and it is # appended here to multilib_flags as it can be overridden by the latter # if it was added earlier. After the target_compile, multilib_flags is diff --git a/gcc/testsuite/lib/gcc-dg.exp b/gcc/testsuite/lib/gcc-dg.exp index 88fe666..1df645e 100644 --- a/gcc/testsuite/lib/gcc-dg.exp +++ b/gcc/testsuite/lib/gcc-dg.exp @@ -242,14 +242,6 @@ proc gcc-dg-test-1 { target_compile prog do_what extra_tool_flags } { set options [list] - # Tests should be able to use "dg-do repo". However, the dg test - # driver checks the argument to dg-do against a list of acceptable - # options, and "repo" is not among them. Therefore, we resort to - # this ugly approach. - if [string match "*-frepo*" $extra_tool_flags] then { - set do_what "repo" - } - switch $do_what { "preprocess" { set compile_type "preprocess" @@ -724,24 +716,6 @@ proc cleanup-coverage-files { } { } } -# Remove compiler-generated files from -repo for the current test. -proc cleanup-repo-files { } { - global additional_sources_used - set testcase [testname-for-summary] - # The name might include a list of options; extract the file name. - set testcase [lindex $testcase 0] - remove-build-file "[file rootname [file tail $testcase]].o" - remove-build-file "[file rootname [file tail $testcase]].rpo" - - # Clean up files for additional source files. - if [info exists additional_sources_used] { - foreach srcfile $additional_sources_used { - remove-build-file "[file rootname [file tail $srcfile]].o" - remove-build-file "[file rootname [file tail $srcfile]].rpo" - } - } -} - # Remove a final insns dump file for the current test. proc cleanup-final-insns-dump { } { set testcase [testname-for-summary] diff --git a/gcc/testsuite/lib/obj-c++.exp b/gcc/testsuite/lib/obj-c++.exp index c32f207..7e7bd3c 100644 --- a/gcc/testsuite/lib/obj-c++.exp +++ b/gcc/testsuite/lib/obj-c++.exp @@ -377,12 +377,6 @@ proc obj-c++_target_compile { source dest type options } { set options [concat "$ALWAYS_OBJCXXFLAGS" $options]; - if { [regexp "(^| )-frepo( |$)" $options] && \ - [regexp "\.o(|bj)$" $dest] } then { - regsub "\.o(|bj)$" $dest ".rpo" rponame - exec rm -f $rponame - } - set options [dg-additional-files-options $options $source] set result [target_compile $source $dest $type $options] diff --git a/gcc/tlink.c b/gcc/tlink.c deleted file mode 100644 index 485000b..0000000 --- a/gcc/tlink.c +++ /dev/null @@ -1,867 +0,0 @@ -/* Scan linker error messages for missing template instantiations and provide - them. - - Copyright (C) 1995-2019 Free Software Foundation, Inc. - Contributed by Jason Merrill (jason@cygnus.com). - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" -#include "intl.h" -#include "obstack.h" -#include "demangle.h" -#include "collect2.h" -#include "collect-utils.h" -#include "filenames.h" -#include "diagnostic-core.h" - -/* TARGET_64BIT may be defined to use driver specific functionality. */ -#undef TARGET_64BIT -#define TARGET_64BIT TARGET_64BIT_DEFAULT - -#define MAX_ITERATIONS 17 - -/* Defined in the automatically-generated underscore.c. */ -extern int prepends_underscore; - -static int tlink_verbose; - -static char *initial_cwd; - -/* Hash table boilerplate for working with htab_t. We have hash tables - for symbol names, file names, and demangled symbols. */ - -typedef struct symbol_hash_entry -{ - const char *key; - struct file_hash_entry *file; - int chosen; - int tweaking; - int tweaked; -} symbol; - -typedef struct file_hash_entry -{ - const char *key; - const char *args; - const char *dir; - const char *main; - int tweaking; -} file; - -typedef const char *str; - -typedef struct demangled_hash_entry -{ - const char *key; - vec mangled; -} demangled; - -/* Hash and comparison functions for these hash tables. */ - -static int hash_string_eq (const void *, const void *); -static hashval_t hash_string_hash (const void *); - -static int -hash_string_eq (const void *s1_p, const void *s2_p) -{ - const char *const *s1 = (const char *const *) s1_p; - const char *s2 = (const char *) s2_p; - return strcmp (*s1, s2) == 0; -} - -static hashval_t -hash_string_hash (const void *s_p) -{ - const char *const *s = (const char *const *) s_p; - return (*htab_hash_string) (*s); -} - -static htab_t symbol_table; - -static struct symbol_hash_entry * symbol_hash_lookup (const char *, int); -static struct file_hash_entry * file_hash_lookup (const char *); -static struct demangled_hash_entry *demangled_hash_lookup (const char *, int); -static void symbol_push (symbol *); -static symbol * symbol_pop (void); -static void file_push (file *); -static file * file_pop (void); -static char * frob_extension (const char *, const char *); -static char * obstack_fgets (FILE *, struct obstack *); -static char * tfgets (FILE *); -static char * pfgets (FILE *); -static void freadsym (FILE *, file *, int); -static void read_repo_file (file *); -static void maybe_tweak (char *, file *); -static int recompile_files (void); -static int read_repo_files (char **); -static void demangle_new_symbols (void); -static int scan_linker_output (const char *); - -/* Look up an entry in the symbol hash table. */ - -static struct symbol_hash_entry * -symbol_hash_lookup (const char *string, int create) -{ - void **e; - e = htab_find_slot_with_hash (symbol_table, string, - (*htab_hash_string) (string), - create ? INSERT : NO_INSERT); - if (e == NULL) - return NULL; - if (*e == NULL) - { - struct symbol_hash_entry *v; - *e = v = XCNEW (struct symbol_hash_entry); - v->key = xstrdup (string); - } - return (struct symbol_hash_entry *) *e; -} - -static htab_t file_table; - -/* Look up an entry in the file hash table. */ - -static struct file_hash_entry * -file_hash_lookup (const char *string) -{ - void **e; - e = htab_find_slot_with_hash (file_table, string, - (*htab_hash_string) (string), - INSERT); - if (*e == NULL) - { - struct file_hash_entry *v; - *e = v = XCNEW (struct file_hash_entry); - v->key = xstrdup (string); - } - return (struct file_hash_entry *) *e; -} - -static htab_t demangled_table; - -/* Look up an entry in the demangled name hash table. */ - -static struct demangled_hash_entry * -demangled_hash_lookup (const char *string, int create) -{ - void **e; - e = htab_find_slot_with_hash (demangled_table, string, - (*htab_hash_string) (string), - create ? INSERT : NO_INSERT); - if (e == NULL) - return NULL; - if (*e == NULL) - { - struct demangled_hash_entry *v; - *e = v = XCNEW (struct demangled_hash_entry); - v->key = xstrdup (string); - } - return (struct demangled_hash_entry *) *e; -} - -/* Stack code. */ - -struct symbol_stack_entry -{ - symbol *value; - struct symbol_stack_entry *next; -}; -struct obstack symbol_stack_obstack; -struct symbol_stack_entry *symbol_stack; - -struct file_stack_entry -{ - file *value; - struct file_stack_entry *next; -}; -struct obstack file_stack_obstack; -struct file_stack_entry *file_stack; - -static void -symbol_push (symbol *p) -{ - struct symbol_stack_entry *ep - = XOBNEW (&symbol_stack_obstack, struct symbol_stack_entry); - ep->value = p; - ep->next = symbol_stack; - symbol_stack = ep; -} - -static symbol * -symbol_pop (void) -{ - struct symbol_stack_entry *ep = symbol_stack; - symbol *p; - if (ep == NULL) - return NULL; - p = ep->value; - symbol_stack = ep->next; - obstack_free (&symbol_stack_obstack, ep); - return p; -} - -static void -file_push (file *p) -{ - struct file_stack_entry *ep; - - if (p->tweaking) - return; - - ep = XOBNEW (&file_stack_obstack, struct file_stack_entry); - ep->value = p; - ep->next = file_stack; - file_stack = ep; - p->tweaking = 1; -} - -static file * -file_pop (void) -{ - struct file_stack_entry *ep = file_stack; - file *p; - if (ep == NULL) - return NULL; - p = ep->value; - file_stack = ep->next; - obstack_free (&file_stack_obstack, ep); - p->tweaking = 0; - return p; -} - -/* Other machinery. */ - -/* Initialize the tlink machinery. Called from do_tlink. */ - -static void -tlink_init (void) -{ - const char *p; - - symbol_table = htab_create (500, hash_string_hash, hash_string_eq, - NULL); - file_table = htab_create (500, hash_string_hash, hash_string_eq, - NULL); - demangled_table = htab_create (500, hash_string_hash, hash_string_eq, - NULL); - - obstack_begin (&symbol_stack_obstack, 0); - obstack_begin (&file_stack_obstack, 0); - - p = getenv ("TLINK_VERBOSE"); - if (p) - tlink_verbose = atoi (p); - else - { - tlink_verbose = 1; - if (verbose) - tlink_verbose = 2; - if (debug) - tlink_verbose = 3; - } - - initial_cwd = getpwd (); -} - -static int -tlink_execute (const char *prog, char **argv, const char *outname, - const char *errname, bool use_atfile) -{ - struct pex_obj *pex; - - pex = collect_execute (prog, argv, outname, errname, - PEX_LAST | PEX_SEARCH, use_atfile); - return collect_wait (prog, pex); -} - -static char * -frob_extension (const char *s, const char *ext) -{ - const char *p; - - p = strrchr (lbasename (s), '.'); - if (! p) - p = s + strlen (s); - - obstack_grow (&temporary_obstack, s, p - s); - return (char *) obstack_copy0 (&temporary_obstack, ext, strlen (ext)); -} - -static char * -obstack_fgets (FILE *stream, struct obstack *ob) -{ - int c; - while ((c = getc (stream)) != EOF && c != '\n') - obstack_1grow (ob, c); - if (obstack_object_size (ob) == 0) - return NULL; - obstack_1grow (ob, '\0'); - return XOBFINISH (ob, char *); -} - -static char * -tfgets (FILE *stream) -{ - return obstack_fgets (stream, &temporary_obstack); -} - -static char * -pfgets (FILE *stream) -{ - return xstrdup (tfgets (stream)); -} - -/* Real tlink code. */ - -/* Subroutine of read_repo_file. We are reading the repo file for file F, - which is coming in on STREAM, and the symbol that comes next in STREAM - is offered, chosen or provided if CHOSEN is 0, 1 or 2, respectively. - - XXX "provided" is unimplemented, both here and in the compiler. */ - -static void -freadsym (FILE *stream, file *f, int chosen) -{ - symbol *sym; - - { - const char *name = tfgets (stream); - sym = symbol_hash_lookup (name, true); - } - - if (sym->file == NULL) - { - /* We didn't have this symbol already, so we choose this file. */ - - symbol_push (sym); - sym->file = f; - sym->chosen = chosen; - } - else if (chosen) - { - /* We want this file; cast aside any pretender. */ - - if (sym->chosen && sym->file != f) - { - if (sym->chosen == 1) - file_push (sym->file); - else - { - file_push (f); - f = sym->file; - chosen = sym->chosen; - } - } - sym->file = f; - sym->chosen = chosen; - } -} - -/* Read in the repo file denoted by F, and record all its information. */ - -static void -read_repo_file (file *f) -{ - char c; - FILE *stream = fopen (f->key, "r"); - - if (tlink_verbose >= 2) - fprintf (stderr, _("collect: reading %s\n"), f->key); - - while (fscanf (stream, "%c ", &c) == 1) - { - switch (c) - { - case 'A': - f->args = pfgets (stream); - break; - case 'D': - f->dir = pfgets (stream); - break; - case 'M': - f->main = pfgets (stream); - break; - case 'P': - freadsym (stream, f, 2); - break; - case 'C': - freadsym (stream, f, 1); - break; - case 'O': - freadsym (stream, f, 0); - break; - } - obstack_free (&temporary_obstack, temporary_firstobj); - } - fclose (stream); - if (f->args == NULL) - f->args = getenv ("COLLECT_GCC_OPTIONS"); - if (f->dir == NULL) - f->dir = "."; -} - -/* We might want to modify LINE, which is a symbol line from file F. We do - this if either we saw an error message referring to the symbol in - question, or we have already allocated the symbol to another file and - this one wants to emit it as well. */ - -static void -maybe_tweak (char *line, file *f) -{ - symbol *sym = symbol_hash_lookup (line + 2, false); - - if ((sym->file == f && sym->tweaking) - || (sym->file != f && line[0] == 'C')) - { - sym->tweaking = 0; - sym->tweaked = 1; - - if (line[0] == 'O') - { - line[0] = 'C'; - sym->chosen = 1; - } - else - { - line[0] = 'O'; - sym->chosen = 0; - } - } -} - -/* Update the repo files for each of the object files we have adjusted and - recompile. */ - -static int -recompile_files (void) -{ - file *f; - - putenv (xstrdup ("COMPILER_PATH=")); - putenv (xstrdup ("LIBRARY_PATH=")); - - while ((f = file_pop ()) != NULL) - { - char *line; - const char *p, *q; - char **argv; - struct obstack arg_stack; - FILE *stream = fopen (f->key, "r"); - const char *const outname = frob_extension (f->key, ".rnw"); - FILE *output = fopen (outname, "w"); - - while ((line = tfgets (stream)) != NULL) - { - switch (line[0]) - { - case 'C': - case 'O': - maybe_tweak (line, f); - } - fprintf (output, "%s\n", line); - } - fclose (stream); - fclose (output); - /* On Windows "rename" returns -1 and sets ERRNO to EACCESS if - the new file name already exists. Therefore, we explicitly - remove the old file first. */ - if (remove (f->key) == -1) - fatal_error (input_location, - "removing repository file %qs: %m", f->key); - if (rename (outname, f->key) == -1) - fatal_error (input_location, "renaming repository file from " - "%qs to %qs: %m", outname, f->key); - - if (!f->args) - { - error ("repository file %qs does not contain command-line " - "arguments", f->key); - return 0; - } - - /* Build a null-terminated argv array suitable for - tlink_execute(). Manipulate arguments on the arg_stack while - building argv on the temporary_obstack. */ - - obstack_init (&arg_stack); - obstack_ptr_grow (&temporary_obstack, c_file_name); - - for (p = f->args; *p != '\0'; p = q + 1) - { - /* Arguments are delimited by single-quotes. Find the - opening quote. */ - p = strchr (p, '\''); - if (!p) - goto done; - - /* Find the closing quote. */ - q = strchr (p + 1, '\''); - if (!q) - goto done; - - obstack_grow (&arg_stack, p + 1, q - (p + 1)); - - /* Replace '\'' with '. This is how set_collect_gcc_options - encodes a single-quote. */ - while (q[1] == '\\' && q[2] == '\'' && q[3] == '\'') - { - const char *r; - - r = strchr (q + 4, '\''); - if (!r) - goto done; - - obstack_grow (&arg_stack, q + 3, r - (q + 3)); - q = r; - } - - obstack_1grow (&arg_stack, '\0'); - obstack_ptr_grow (&temporary_obstack, obstack_finish (&arg_stack)); - } - done: - obstack_ptr_grow (&temporary_obstack, f->main); - obstack_ptr_grow (&temporary_obstack, NULL); - argv = XOBFINISH (&temporary_obstack, char **); - - if (tlink_verbose) - fprintf (stderr, _("collect: recompiling %s\n"), f->main); - - if (chdir (f->dir) != 0 - || tlink_execute (c_file_name, argv, NULL, NULL, false) != 0 - || chdir (initial_cwd) != 0) - return 0; - - read_repo_file (f); - - obstack_free (&arg_stack, NULL); - obstack_free (&temporary_obstack, temporary_firstobj); - } - return 1; -} - -/* The first phase of processing: determine which object files have - .rpo files associated with them, and read in the information. */ - -static int -read_repo_files (char **object_lst) -{ - char **object = object_lst; - - for (; *object; object++) - { - const char *p; - file *f; - - /* Don't bother trying for ld flags. */ - if (*object[0] == '-') - continue; - - p = frob_extension (*object, ".rpo"); - - if (! file_exists (p)) - continue; - - f = file_hash_lookup (p); - - read_repo_file (f); - } - - if (file_stack != NULL && ! recompile_files ()) - return 0; - - return (symbol_stack != NULL); -} - -/* Add the demangled forms of any new symbols to the hash table. */ - -static void -demangle_new_symbols (void) -{ - symbol *sym; - - while ((sym = symbol_pop ()) != NULL) - { - demangled *dem; - const char *p = cplus_demangle (sym->key, DMGL_PARAMS | DMGL_ANSI); - - if (! p) - continue; - - dem = demangled_hash_lookup (p, true); - dem->mangled.safe_push (sym->key); - } -} - -/* We want to tweak symbol SYM. Return true if all is well, false on - error. */ - -static bool -start_tweaking (symbol *sym) -{ - if (sym && sym->tweaked) - { - error ("%qs was assigned to %qs, but was not defined " - "during recompilation, or vice versa", - sym->key, sym->file->key); - return 0; - } - if (sym && !sym->tweaking) - { - if (tlink_verbose >= 2) - fprintf (stderr, _("collect: tweaking %s in %s\n"), - sym->key, sym->file->key); - sym->tweaking = 1; - file_push (sym->file); - } - return true; -} - -/* Step through the output of the linker, in the file named FNAME, and - adjust the settings for each symbol encountered. */ - -static int -scan_linker_output (const char *fname) -{ - FILE *stream = fopen (fname, "r"); - char *line; - int skip_next_in_line = 0; - - while ((line = tfgets (stream)) != NULL) - { - char *p = line, *q; - symbol *sym; - demangled *dem = 0; - int end; - int ok = 0; - unsigned ix; - str s; - - /* On darwin9, we might have to skip " in " lines as well. */ - if (skip_next_in_line - && strstr (p, " in ")) - continue; - skip_next_in_line = 0; - - while (*p && ISSPACE ((unsigned char) *p)) - ++p; - - if (! *p) - continue; - - for (q = p; *q && ! ISSPACE ((unsigned char) *q); ++q) - ; - - /* Try the first word on the line. */ - if (*p == '.') - ++p; - if (!strncmp (p, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX))) - p += strlen (USER_LABEL_PREFIX); - - end = ! *q; - *q = 0; - sym = symbol_hash_lookup (p, false); - - /* Some SVR4 linkers produce messages like - ld: 0711-317 ERROR: Undefined symbol: .g__t3foo1Zi - */ - if (! sym && ! end && strstr (q + 1, "Undefined symbol: ")) - { - char *p = strrchr (q + 1, ' '); - p++; - if (*p == '.') - p++; - if (!strncmp (p, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX))) - p += strlen (USER_LABEL_PREFIX); - sym = symbol_hash_lookup (p, false); - } - - if (! sym && ! end) - /* Try a mangled name in quotes. */ - { - char *oldq = q + 1; - q = 0; - - /* On darwin9, we look for "foo" referenced from:\n\(.* in .*\n\)* */ - if (strcmp (oldq, "referenced from:") == 0) - { - /* We have to remember that we found a symbol to tweak. */ - ok = 1; - - /* We actually want to start from the first word on the - line. */ - oldq = p; - - /* Since the format is multiline, we have to skip - following lines with " in ". */ - skip_next_in_line = 1; - } - - /* First try `GNU style'. */ - p = strchr (oldq, '`'); - if (p) - p++, q = strchr (p, '\''); - /* Then try "double quotes". */ - else if (p = strchr (oldq, '"'), p) - p++, q = strchr (p, '"'); - /* Then try 'single quotes'. */ - else if (p = strchr (oldq, '\''), p) - p++, q = strchr (p, '\''); - else { - /* Then try entire line. */ - q = strchr (oldq, 0); - if (q != oldq) - p = (char *)oldq; - } - - if (p) - { - /* Don't let the strstr's below see the demangled name; we - might get spurious matches. */ - p[-1] = '\0'; - - /* powerpc64-linux references .foo when calling function foo. */ - if (*p == '.') - p++; - } - - /* We need to check for certain error keywords here, or we would - mistakenly use GNU ld's "In function `foo':" message. */ - if (q && (ok - || strstr (oldq, "ndefined") - || strstr (oldq, "nresolved") - || strstr (oldq, "nsatisfied") - || strstr (oldq, "ultiple"))) - { - *q = 0; - dem = demangled_hash_lookup (p, false); - if (!dem) - { - if (!strncmp (p, USER_LABEL_PREFIX, - strlen (USER_LABEL_PREFIX))) - p += strlen (USER_LABEL_PREFIX); - sym = symbol_hash_lookup (p, false); - } - } - } - - if (dem) - { - /* We found a demangled name. If this is the name of a - constructor or destructor, there can be several mangled names - that match it, so choose or unchoose all of them. If some are - chosen and some not, leave the later ones that don't match - alone for now; either this will cause the link to succeed, or - on the next attempt we will switch all of them the other way - and that will cause it to succeed. */ - int chosen = 0; - int len = dem->mangled.length (); - ok = true; - FOR_EACH_VEC_ELT (dem->mangled, ix, s) - { - sym = symbol_hash_lookup (s, false); - if (ix == 0) - chosen = sym->chosen; - else if (sym->chosen != chosen) - /* Mismatch. */ - continue; - /* Avoid an error about re-tweaking when we guess wrong in - the case of mismatch. */ - if (len > 1) - sym->tweaked = false; - ok = start_tweaking (sym); - } - } - else - ok = start_tweaking (sym); - - obstack_free (&temporary_obstack, temporary_firstobj); - - if (!ok) - { - fclose (stream); - return 0; - } - } - - fclose (stream); - return (file_stack != NULL); -} - -/* Entry point for tlink. Called from main in collect2.c. - - Iteratively try to provide definitions for all the unresolved symbols - mentioned in the linker error messages. - - LD_ARGV is an array of arguments for the linker. - OBJECT_LST is an array of object files that we may be able to recompile - to provide missing definitions. Currently ignored. */ - -void -do_tlink (char **ld_argv, char **object_lst ATTRIBUTE_UNUSED) -{ - int ret = tlink_execute ("ld", ld_argv, ldout, lderrout, - HAVE_GNU_LD && at_file_supplied); - - tlink_init (); - - if (ret) - { - int i = 0; - - /* Until collect does a better job of figuring out which are object - files, assume that everything on the command line could be. */ - if (read_repo_files (ld_argv)) - while (ret && i++ < MAX_ITERATIONS) - { - if (tlink_verbose >= 3) - { - dump_ld_file (ldout, stdout); - dump_ld_file (lderrout, stderr); - } - demangle_new_symbols (); - if (! scan_linker_output (ldout) - && ! scan_linker_output (lderrout)) - break; - if (! recompile_files ()) - break; - if (tlink_verbose) - fprintf (stderr, _("collect: relinking\n")); - ret = tlink_execute ("ld", ld_argv, ldout, lderrout, - HAVE_GNU_LD && at_file_supplied); - } - } - - dump_ld_file (ldout, stdout); - unlink (ldout); - dump_ld_file (lderrout, stderr); - unlink (lderrout); - if (ret) - { - error ("ld returned %d exit status", ret); - exit (ret); - } - else - { - /* We have just successfully produced an output file, so assume that we - may unlink it if need be for now on. */ - may_unlink_output_file = true; - } -} -- cgit v1.1 From 973159f219b154e79d10f95117932caf4b398819 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Fri, 6 Sep 2019 11:38:28 +0200 Subject: Improve documentation of for statement. 2019-09-06 Martin Liska * doc/match-and-simplify.texi: Separate tuples with ;. From-SVN: r275452 --- gcc/ChangeLog | 4 ++++ gcc/doc/match-and-simplify.texi | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 233072e..f4766bd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,9 @@ 2019-09-06 Martin Liska + * doc/match-and-simplify.texi: Separate tuples with ;. + +2019-09-06 Martin Liska + PR c++/91125 * Makefile.in: Remove tlink.o. * collect2.c (do_link): New function isolated diff --git a/gcc/doc/match-and-simplify.texi b/gcc/doc/match-and-simplify.texi index 760b703..943ff1a 100644 --- a/gcc/doc/match-and-simplify.texi +++ b/gcc/doc/match-and-simplify.texi @@ -293,8 +293,8 @@ nested and a @code{for} can have multiple operators to iterate. @end smallexample In this example the pattern will be repeated four times with -@code{opa, opb, opc} being @code{plus, minus, plus}, -@code{plus, minus, minus}, @code{minus, plus, plus}, +@code{opa, opb, opc} being @code{plus, minus, plus}; +@code{plus, minus, minus}; @code{minus, plus, plus}; @code{minus, plus, minus}. To avoid repeating operator lists in @code{for} you can name -- cgit v1.1 From 7d99a5b62c2672eff965fec12edac0a080d77257 Mon Sep 17 00:00:00 2001 From: Richard Earnshaw Date: Fri, 6 Sep 2019 09:58:14 +0000 Subject: [arm] Add missing predicated-short-it variants to cmp_and and cmp_ior patterns The cmp_and and cmp_ior patterns were missing a couple of short-it variants for thumb2, where the comparisons are all using registers some of which were HI_REGS. * config/arm/arm.md (cmp_and): Add short-it variant for thumb2 with high regs. (cmp_ior): Likewise. From-SVN: r275453 --- gcc/ChangeLog | 6 ++++++ gcc/config/arm/arm.md | 48 ++++++++++++++++++++++++++---------------------- 2 files changed, 32 insertions(+), 22 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f4766bd..65d9f43 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-09-06 Richard Earnshaw + + * config/arm/arm.md (cmp_and): Add short-it variant for thumb2 with + high regs. + (cmp_ior): Likewise. + 2019-09-06 Martin Liska * doc/match-and-simplify.texi: Separate tuples with ;. diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index e49e0d5..e236831 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -9143,15 +9143,15 @@ (compare (and:SI (match_operator 4 "arm_comparison_operator" - [(match_operand:SI 0 "s_register_operand" - "l,l,l,r,r,r,r,r,r") - (match_operand:SI 1 "arm_add_operand" - "lPy,lPy,lPy,rI,L,rI,L,rI,L")]) + [(match_operand:SI 0 "s_register_operand" + "l,l,l,r,r,r,r,r,r,r") + (match_operand:SI 1 "arm_add_operand" + "lPy,lPy,lPy,rI,L,r,rI,L,rI,L")]) (match_operator:SI 5 "arm_comparison_operator" - [(match_operand:SI 2 "s_register_operand" - "l,r,r,l,l,r,r,r,r") - (match_operand:SI 3 "arm_add_operand" - "lPy,rI,L,lPy,lPy,rI,rI,L,L")])) + [(match_operand:SI 2 "s_register_operand" + "l,r,r,l,l,r,r,r,r,r") + (match_operand:SI 3 "arm_add_operand" + "lPy,rI,L,lPy,lPy,r,rI,rI,L,L")])) (const_int 0)))] "TARGET_32BIT" "* @@ -9183,9 +9183,10 @@ \"it\\t%d5\", \"it\\t%d4\" }; - static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN, - CMP_CMP, CMN_CMP, CMP_CMP, - CMN_CMP, CMP_CMN, CMN_CMN}; + static const int cmp_idx[] = {CMP_CMP, CMP_CMP, CMP_CMN, + CMP_CMP, CMN_CMP, CMP_CMP, + CMP_CMP, CMN_CMP, CMP_CMN, + CMN_CMN}; int swap = comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])); @@ -9198,14 +9199,15 @@ }" [(set_attr "conds" "set") (set_attr "predicable" "no") - (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any") - (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no") + (set_attr "arch" "t2,t2,t2,t2,t2,t2,any,any,any,any") + (set_attr "enabled_for_short_it" "yes,no,no,no,no,yes,no,no,no,no") (set_attr_alternative "length" [(const_int 6) (const_int 8) (const_int 8) (const_int 8) (const_int 8) + (const_int 6) (if_then_else (eq_attr "is_thumb" "no") (const_int 8) (const_int 10)) @@ -9227,14 +9229,14 @@ (ior:SI (match_operator 4 "arm_comparison_operator" [(match_operand:SI 0 "s_register_operand" - "l,l,l,r,r,r,r,r,r") + "l,l,l,r,r,r,r,r,r,r") (match_operand:SI 1 "arm_add_operand" - "lPy,lPy,lPy,rI,L,rI,L,rI,L")]) + "lPy,lPy,lPy,rI,L,r,rI,L,rI,L")]) (match_operator:SI 5 "arm_comparison_operator" [(match_operand:SI 2 "s_register_operand" - "l,r,r,l,l,r,r,r,r") + "l,r,r,l,l,r,r,r,r,r") (match_operand:SI 3 "arm_add_operand" - "lPy,rI,L,lPy,lPy,rI,rI,L,L")])) + "lPy,rI,L,lPy,lPy,r,rI,rI,L,L")])) (const_int 0)))] "TARGET_32BIT" "* @@ -9266,9 +9268,10 @@ \"it\\t%D4\", \"it\\t%D5\" }; - static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN, - CMP_CMP, CMN_CMP, CMP_CMP, - CMN_CMP, CMP_CMN, CMN_CMN}; + static const int cmp_idx[] = {CMP_CMP, CMP_CMP, CMP_CMN, + CMP_CMP, CMN_CMP, CMP_CMP, + CMP_CMP, CMN_CMP, CMP_CMN, + CMN_CMN}; int swap = comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])); @@ -9281,14 +9284,15 @@ } " [(set_attr "conds" "set") - (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any") - (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no") + (set_attr "arch" "t2,t2,t2,t2,t2,t2,any,any,any,any") + (set_attr "enabled_for_short_it" "yes,no,no,no,no,yes,no,no,no,no") (set_attr_alternative "length" [(const_int 6) (const_int 8) (const_int 8) (const_int 8) (const_int 8) + (const_int 6) (if_then_else (eq_attr "is_thumb" "no") (const_int 8) (const_int 10)) -- cgit v1.1 From c0c2096fbada36fa26778bc02b32555150050d85 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Fri, 6 Sep 2019 11:22:09 +0000 Subject: [C++ PATCH] Reserve a decl_lang bit https://gcc.gnu.org/ml/gcc-patches/2019-09/msg00365.html Reserve TREE_LANG_FLAG_3 for modules. gcc/cp/ * cp-tree.h (DECL_CONSTRUCTION_VTABLE_P): Delete. (DECL_NON_TRIVIALLY_INITIALIZED_P): Move to TREE_LANG_FLAG_6. * class.c (build_ctor_vtbl_group): Don't set DECL_CONSTRUCTION_VTABLE_P. * decl2.c (determine_visibility_from_class): Don't check DECL_CONSTRUCTION_VTABLE_P anymore. From-SVN: r275455 --- gcc/cp/ChangeLog | 11 +++++++++++ gcc/cp/class.c | 2 +- gcc/cp/cp-tree.h | 12 +++--------- gcc/cp/decl2.c | 7 +------ 4 files changed, 16 insertions(+), 16 deletions(-) (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c1c7282..28285d9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2019-09-06 Nathan Sidwell + + Reserve TREE_LANG_FLAG_3 for modules. + gcc/cp/ + * cp-tree.h (DECL_CONSTRUCTION_VTABLE_P): Delete. + (DECL_NON_TRIVIALLY_INITIALIZED_P): Move to TREE_LANG_FLAG_6. + * class.c (build_ctor_vtbl_group): Don't set + DECL_CONSTRUCTION_VTABLE_P. + * decl2.c (determine_visibility_from_class): Don't check + DECL_CONSTRUCTION_VTABLE_P anymore. + 2019-09-06 Martin Liska PR c++/91125 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 47350c2..20cfd10 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -9175,7 +9175,7 @@ build_ctor_vtbl_group (tree binfo, tree t) constructing the addresses of secondary vtables in the construction vtable group. */ vtbl = build_vtable (t, id, ptr_type_node); - DECL_CONSTRUCTION_VTABLE_P (vtbl) = 1; + /* Don't export construction vtables from shared libraries. Even on targets that don't support hidden visibility, this tells can_refer_decl_in_current_unit_p not to assume that it's safe to diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index a045214..60e0846 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -448,12 +448,12 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; ICS_BAD_FLAG (in _CONV) FN_TRY_BLOCK_P (in TRY_BLOCK) BIND_EXPR_BODY_BLOCK (in BIND_EXPR) - DECL_NONTRIVIALLY_INITIALIZED_P (in VAR_DECL) CALL_EXPR_ORDERED_ARGS (in CALL_EXPR, AGGR_INIT_EXPR) DECLTYPE_FOR_REF_CAPTURE (in DECLTYPE_TYPE) CONSTRUCTOR_C99_COMPOUND_LITERAL (in CONSTRUCTOR) OVL_NESTED_P (in OVERLOAD) LAMBDA_EXPR_INSTANTIATED (in LAMBDA_EXPR) + Reserved for DECL_MODULE_EXPORT (in DECL_) 4: IDENTIFIER_MARKED (IDENTIFIER_NODEs) TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR, CALL_EXPR, or FIELD_DECL). @@ -466,8 +466,8 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; CALL_EXPR_REVERSE_ARGS (in CALL_EXPR, AGGR_INIT_EXPR) CONSTRUCTOR_PLACEHOLDER_BOUNDARY (in CONSTRUCTOR) 6: IDENTIFIER_REPO_CHOSEN (in IDENTIFIER_NODE) - DECL_CONSTRUCTION_VTABLE_P (in VAR_DECL) TYPE_MARKED_P (in _TYPE) + DECL_NON_TRIVIALLY_INITIALIZED_P (in VAR_DECL) RANGE_FOR_IVDEP (in RANGE_FOR_STMT) CALL_EXPR_OPERATOR_SYNTAX (in CALL_EXPR, AGGR_INIT_EXPR) CONSTRUCTOR_IS_DESIGNATED_INIT (in CONSTRUCTOR) @@ -3001,7 +3001,7 @@ struct GTY(()) lang_decl { /* Nonzero for a VAR_DECL iff an explicit initializer was provided or a non-trivial constructor is called. */ #define DECL_NONTRIVIALLY_INITIALIZED_P(NODE) \ - (TREE_LANG_FLAG_3 (VAR_DECL_CHECK (NODE))) + (TREE_LANG_FLAG_6 (VAR_DECL_CHECK (NODE))) /* Nonzero for a VAR_DECL that was initialized with a constant-expression. */ @@ -3270,12 +3270,6 @@ struct GTY(()) lang_decl { #define FUNCTION_RVALUE_QUALIFIED(NODE) \ TREE_LANG_FLAG_5 (FUNC_OR_METHOD_CHECK (NODE)) -/* Returns 1 iff VAR_DECL is a construction virtual table. - DECL_VTABLE_OR_VTT_P will be true in this case and must be checked - before using this macro. */ -#define DECL_CONSTRUCTION_VTABLE_P(NODE) \ - TREE_LANG_FLAG_6 (VAR_DECL_CHECK (NODE)) - /* 1 iff NODE is function-local, but for types. */ #define LOCAL_CLASS_P(NODE) \ (decl_function_context (TYPE_MAIN_DECL (NODE)) != NULL_TREE) diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index d4bb881..8f935e8 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2713,13 +2713,8 @@ determine_visibility_from_class (tree decl, tree class_type) /* Give the target a chance to override the visibility associated with DECL. */ if (VAR_P (decl) - && (DECL_TINFO_P (decl) - || (DECL_VTABLE_OR_VTT_P (decl) - /* Construction virtual tables are not exported because - they cannot be referred to from other object files; - their name is not standardized by the ABI. */ - && !DECL_CONSTRUCTION_VTABLE_P (decl))) && TREE_PUBLIC (decl) + && (DECL_TINFO_P (decl) || DECL_VTABLE_OR_VTT_P (decl)) && !DECL_REALLY_EXTERN (decl) && !CLASSTYPE_VISIBILITY_SPECIFIED (class_type)) targetm.cxx.determine_class_data_visibility (decl); -- cgit v1.1 From aff342a3c1808044323044506e0d034b55310bf1 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Fri, 6 Sep 2019 12:51:44 +0000 Subject: [PATCH] Deprecate -frepo option. https://gcc.gnu.org/ml/gcc-patches/2019-09/msg00379.html PR c++/91125 * cp-tree.h (IDENTIFIER_REPO_CHOSEN, DECL_REPO_AVAILABLE_P): Delete. (struct lang_decl_base): Remove repo_available_p. * decl.c (duplicate_decls): Don't copy DECL_REPO_AVAILABLE_P. From-SVN: r275456 --- gcc/cp/ChangeLog | 8 ++++++-- gcc/cp/cp-tree.h | 17 ++--------------- gcc/cp/decl.c | 1 - 3 files changed, 8 insertions(+), 18 deletions(-) (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 28285d9..48582ce 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,7 +1,11 @@ 2019-09-06 Nathan Sidwell - Reserve TREE_LANG_FLAG_3 for modules. - gcc/cp/ + PR c++/91125 + * cp-tree.h (IDENTIFIER_REPO_CHOSEN, DECL_REPO_AVAILABLE_P): Delete. + (struct lang_decl_base): Remove repo_available_p. + * decl.c (duplicate_decls): Don't copy DECL_REPO_AVAILABLE_P. + + (Reserve TREE_LANG_FLAG_3 for modules. * cp-tree.h (DECL_CONSTRUCTION_VTABLE_P): Delete. (DECL_NON_TRIVIALLY_INITIALIZED_P): Move to TREE_LANG_FLAG_6. * class.c (build_ctor_vtbl_group): Don't set diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 60e0846..95e5eda 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -465,8 +465,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; FUNCTION_RVALUE_QUALIFIED (in FUNCTION_TYPE, METHOD_TYPE) CALL_EXPR_REVERSE_ARGS (in CALL_EXPR, AGGR_INIT_EXPR) CONSTRUCTOR_PLACEHOLDER_BOUNDARY (in CONSTRUCTOR) - 6: IDENTIFIER_REPO_CHOSEN (in IDENTIFIER_NODE) - TYPE_MARKED_P (in _TYPE) + 6: TYPE_MARKED_P (in _TYPE) DECL_NON_TRIVIALLY_INITIALIZED_P (in VAR_DECL) RANGE_FOR_IVDEP (in RANGE_FOR_STMT) CALL_EXPR_OPERATOR_SYNTAX (in CALL_EXPR, AGGR_INIT_EXPR) @@ -1112,12 +1111,6 @@ enum cp_identifier_kind { #define IDENTIFIER_VIRTUAL_P(NODE) \ TREE_LANG_FLAG_5 (IDENTIFIER_NODE_CHECK (NODE)) -/* True iff NAME is the DECL_ASSEMBLER_NAME for an entity with vague - linkage which the prelinker has assigned to this translation - unit. */ -#define IDENTIFIER_REPO_CHOSEN(NAME) \ - (TREE_LANG_FLAG_6 (IDENTIFIER_NODE_CHECK (NAME))) - /* True if this identifier is a reserved word. C_RID_CODE (node) is then the RID_* value of the keyword. Value 1. */ #define IDENTIFIER_KEYWORD_P(NODE) \ @@ -2590,7 +2583,6 @@ struct GTY(()) lang_decl_base { unsigned use_template : 2; unsigned not_really_extern : 1; /* var or fn */ unsigned initialized_in_class : 1; /* var or fn */ - unsigned repo_available_p : 1; /* var or fn */ unsigned threadprivate_or_deleted_p : 1; /* var or fn */ unsigned anticipated_p : 1; /* fn, type or template */ /* anticipated_p reused as DECL_OMP_PRIVATIZED_MEMBER in var */ @@ -2601,7 +2593,7 @@ struct GTY(()) lang_decl_base { unsigned concept_p : 1; /* applies to vars and functions */ unsigned var_declared_inline_p : 1; /* var */ unsigned dependent_init_p : 1; /* var */ - /* 1 spare bit */ + /* 2 spare bits */ }; /* True for DECL codes which have template info and access. */ @@ -3162,11 +3154,6 @@ struct GTY(()) lang_decl { #define DECL_EXTERN_C_FUNCTION_P(NODE) \ (DECL_NON_THUNK_FUNCTION_P (NODE) && DECL_EXTERN_C_P (NODE)) -/* True iff DECL is an entity with vague linkage whose definition is - available in this translation unit. */ -#define DECL_REPO_AVAILABLE_P(NODE) \ - (DECL_LANG_SPECIFIC (NODE)->u.base.repo_available_p) - /* True if DECL is declared 'constexpr'. */ #define DECL_DECLARED_CONSTEXPR_P(DECL) \ DECL_LANG_FLAG_8 (VAR_OR_FUNCTION_DECL_CHECK (STRIP_TEMPLATE (DECL))) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 825e1e6..88e2c3b 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -2388,7 +2388,6 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) /* Don't really know how much of the language-specific values we should copy from old to new. */ DECL_IN_AGGR_P (newdecl) = DECL_IN_AGGR_P (olddecl); - DECL_REPO_AVAILABLE_P (newdecl) = DECL_REPO_AVAILABLE_P (olddecl); DECL_INITIALIZED_IN_CLASS_P (newdecl) |= DECL_INITIALIZED_IN_CLASS_P (olddecl); -- cgit v1.1 From 400b8274e6992c348a822a99ef0c38290aede386 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Fri, 6 Sep 2019 12:54:19 +0000 Subject: [preprocessor] Popping "" file names https://gcc.gnu.org/ml/gcc-patches/2019-08/msg02069.html New # semantics for popping to "" name. libcpp/ * directives.c (do_linemarker): Popping to "" name means get the name from the include stack.. From-SVN: r275457 --- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/c-c++-common/cpp/line-1.c | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 gcc/testsuite/c-c++-common/cpp/line-1.c (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9a544bc..b999a79 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-09-06 Nathan Sidwell + + * c-c++-common/cpp/line-1.c: New. + 2019-09-06 Martin Liska PR c++/91125 diff --git a/gcc/testsuite/c-c++-common/cpp/line-1.c b/gcc/testsuite/c-c++-common/cpp/line-1.c new file mode 100644 index 0000000..8e9c941 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/line-1.c @@ -0,0 +1,20 @@ +/* { dg-do preprocess } */ +/* { dg-additional-options -Wno-pedantic } */ + +main-1 __FILE__ + +# 7 "inner.h" 1 +inner-1 __FILE__ +# 9 "inside.h" 1 +inside-1 __FILE__ +# 11 "" 2 +inner-2 __FILE__ +#13 "" 2 +main-2 __FILE__ + + +/* { dg-final { scan-file line-1.i "main-1 \"\[^\n]*line-1.c\"\n" } } */ +/* { dg-final { scan-file line-1.i "main-2 \"\[^\n]*line-1.c\"\n" } } */ +/* { dg-final { scan-file line-1.i "inner-1 \"inner.h\"\n" } } */ +/* { dg-final { scan-file line-1.i "inner-2 \"inner.h\"\n" } } */ +/* { dg-final { scan-file line-1.i "inside-1 \"inside.h\"\n" } } */ -- cgit v1.1 From 94ea5c6a5102ebf77590e1f4583922dd474ff8de Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Fri, 6 Sep 2019 07:54:48 -0700 Subject: Fix testcase to not use LTO with -fvtable-verify. 2019-09-05 Caroline Tice PR testsuite/91670 * g++.dg/ubsan/pr59415.C: Disable LTO, since test uses -fvtable-verify, and the two options are no longer allowed together. From-SVN: r275460 --- gcc/testsuite/ChangeLog | 7 +++++++ gcc/testsuite/g++.dg/ubsan/pr59415.C | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b999a79..9de41ea 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2019-09-06 Caroline Tice + + PR testsuite/91670 + * g++.dg/ubsan/pr59415.C: Disable LTO, since test uses + -fvtable-verify, and the two options are no longer allowed + together. + 2019-09-06 Nathan Sidwell * c-c++-common/cpp/line-1.c: New. diff --git a/gcc/testsuite/g++.dg/ubsan/pr59415.C b/gcc/testsuite/g++.dg/ubsan/pr59415.C index 4c373f7..9016226 100644 --- a/gcc/testsuite/g++.dg/ubsan/pr59415.C +++ b/gcc/testsuite/g++.dg/ubsan/pr59415.C @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-fsanitize=null -Wall -fvtable-verify=std" } */ +/* { dg-options "-fsanitize=null -Wall -fvtable-verify=std -fno-lto" } */ void foo (void) -- cgit v1.1 From 613d4e784c23fbf5ae6e3132fd4d0150545681c1 Mon Sep 17 00:00:00 2001 From: David Edelsohn Date: Fri, 6 Sep 2019 15:24:28 +0000 Subject: Warray-bounds-4.C: Skip AIX. * g++.dg/warn/Warray-bounds-4.C: Skip AIX. * g++.dg/warn/Warray-bounds-8.C: Skip AIX. * g++.dg/opt/flifetime-dse2.C: XFAIL AIX. * g++.dg/opt/flifetime-dse4.C: XFAIL AIX. From-SVN: r275462 --- gcc/testsuite/ChangeLog | 7 +++++++ gcc/testsuite/g++.dg/opt/flifetime-dse2.C | 1 + gcc/testsuite/g++.dg/opt/flifetime-dse4.C | 1 + gcc/testsuite/g++.dg/warn/Warray-bounds-4.C | 1 + gcc/testsuite/g++.dg/warn/Warray-bounds-8.C | 3 ++- 5 files changed, 12 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9de41ea..f206218 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2019-09-06 David Edelsohn + + * g++.dg/warn/Warray-bounds-4.C: Skip AIX. + * g++.dg/warn/Warray-bounds-8.C: Skip AIX. + * g++.dg/opt/flifetime-dse2.C: XFAIL AIX. + * g++.dg/opt/flifetime-dse4.C: XFAIL AIX. + 2019-09-06 Caroline Tice PR testsuite/91670 diff --git a/gcc/testsuite/g++.dg/opt/flifetime-dse2.C b/gcc/testsuite/g++.dg/opt/flifetime-dse2.C index 16d9a74..5f78bc9 100644 --- a/gcc/testsuite/g++.dg/opt/flifetime-dse2.C +++ b/gcc/testsuite/g++.dg/opt/flifetime-dse2.C @@ -1,5 +1,6 @@ // { dg-options "-O3 -flifetime-dse" } // { dg-do run } +// { dg-xfail-run-if "AIX operator new" { powerpc-ibm-aix* } } typedef __SIZE_TYPE__ size_t; inline void * operator new (size_t, void *p) { return p; } diff --git a/gcc/testsuite/g++.dg/opt/flifetime-dse4.C b/gcc/testsuite/g++.dg/opt/flifetime-dse4.C index c72444a..4a6fe57 100644 --- a/gcc/testsuite/g++.dg/opt/flifetime-dse4.C +++ b/gcc/testsuite/g++.dg/opt/flifetime-dse4.C @@ -1,5 +1,6 @@ // { dg-options "-O3 -flifetime-dse=1" } // { dg-do run } +// { dg-xfail-run-if "AIX operator new" { powerpc-ibm-aix* } } typedef __SIZE_TYPE__ size_t; inline void * operator new (size_t, void *p) { return p; } diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-4.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-4.C index 319038a..a4c4383 100644 --- a/gcc/testsuite/g++.dg/warn/Warray-bounds-4.C +++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-4.C @@ -1,5 +1,6 @@ // { dg-do compile } // { dg-options "-O2 -Warray-bounds" } +// { dg-skip-if "" { *-*-aix* } } class String { diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-8.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-8.C index 850414e..69226fa 100644 --- a/gcc/testsuite/g++.dg/warn/Warray-bounds-8.C +++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-8.C @@ -3,7 +3,8 @@ See Wstringop-overflow-3.C for the same test that exercises the other warning. { dg-do compile } - { dg-options "-O2 -Wall -Wno-stringop-overflow" } */ + { dg-options "-O2 -Wall -Wno-stringop-overflow" } + { dg-skip-if "" { *-*-aix* } } */ void sink (void*); -- cgit v1.1 From 28d67c175f335ac01ddc8d659986a34b281b02e9 Mon Sep 17 00:00:00 2001 From: David Edelsohn Date: Fri, 6 Sep 2019 15:29:01 +0000 Subject: inf-compare-1.c: Skip AIX. * gcc.dg/torture/inf-compare-1.c: Skip AIX. * gcc.dg/torture/inf-compare-2.c: Skip AIX. * gcc.dg/torture/inf-compare-3.c: Skip AIX. * gcc.dg/torture/inf-compare-4.c: Skip AIX. * gcc.dg/torture/pr52451.c: Skip AIX. * gcc.dg/torture/pr68264.c: Skip AIX * gcc.dg/torture/pr91323.c: Skip AIX. From-SVN: r275464 --- gcc/testsuite/ChangeLog | 8 ++++++++ gcc/testsuite/gcc.dg/torture/inf-compare-1.c | 1 + gcc/testsuite/gcc.dg/torture/inf-compare-2.c | 1 + gcc/testsuite/gcc.dg/torture/inf-compare-3.c | 1 + gcc/testsuite/gcc.dg/torture/inf-compare-4.c | 1 + gcc/testsuite/gcc.dg/torture/pr52451.c | 1 + gcc/testsuite/gcc.dg/torture/pr68264.c | 1 + gcc/testsuite/gcc.dg/torture/pr91323.c | 1 + 8 files changed, 15 insertions(+) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f206218..ab4b2dc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,13 @@ 2019-09-06 David Edelsohn + * gcc.dg/torture/inf-compare-1.c: Skip AIX. + * gcc.dg/torture/inf-compare-2.c: Skip AIX. + * gcc.dg/torture/inf-compare-3.c: Skip AIX. + * gcc.dg/torture/inf-compare-4.c: Skip AIX. + * gcc.dg/torture/pr52451.c: Skip AIX. + * gcc.dg/torture/pr68264.c: Skip AIX + * gcc.dg/torture/pr91323.c: Skip AIX. + * g++.dg/warn/Warray-bounds-4.C: Skip AIX. * g++.dg/warn/Warray-bounds-8.C: Skip AIX. * g++.dg/opt/flifetime-dse2.C: XFAIL AIX. diff --git a/gcc/testsuite/gcc.dg/torture/inf-compare-1.c b/gcc/testsuite/gcc.dg/torture/inf-compare-1.c index a4b44d6..70f255e 100644 --- a/gcc/testsuite/gcc.dg/torture/inf-compare-1.c +++ b/gcc/testsuite/gcc.dg/torture/inf-compare-1.c @@ -2,6 +2,7 @@ /* remove the xfail for powerpc when pr58684 is fixed */ /* { dg-add-options ieee } */ /* { dg-require-effective-target fenv_exceptions } */ +/* { dg-skip-if "fenv" { powerpc-ibm-aix* } } */ #include diff --git a/gcc/testsuite/gcc.dg/torture/inf-compare-2.c b/gcc/testsuite/gcc.dg/torture/inf-compare-2.c index 8ee932c..011f992 100644 --- a/gcc/testsuite/gcc.dg/torture/inf-compare-2.c +++ b/gcc/testsuite/gcc.dg/torture/inf-compare-2.c @@ -2,6 +2,7 @@ /* remove the xfail for powerpc when pr58684 is fixed */ /* { dg-add-options ieee } */ /* { dg-require-effective-target fenv_exceptions } */ +/* { dg-skip-if "fenv" { powerpc-ibm-aix* } } */ #include diff --git a/gcc/testsuite/gcc.dg/torture/inf-compare-3.c b/gcc/testsuite/gcc.dg/torture/inf-compare-3.c index c8605ad..de5c478 100644 --- a/gcc/testsuite/gcc.dg/torture/inf-compare-3.c +++ b/gcc/testsuite/gcc.dg/torture/inf-compare-3.c @@ -2,6 +2,7 @@ /* remove the xfail for powerpc when pr58684 is fixed */ /* { dg-add-options ieee } */ /* { dg-require-effective-target fenv_exceptions } */ +/* { dg-skip-if "fenv" { powerpc-ibm-aix* } } */ #include diff --git a/gcc/testsuite/gcc.dg/torture/inf-compare-4.c b/gcc/testsuite/gcc.dg/torture/inf-compare-4.c index 55a0dfc..685562d 100644 --- a/gcc/testsuite/gcc.dg/torture/inf-compare-4.c +++ b/gcc/testsuite/gcc.dg/torture/inf-compare-4.c @@ -2,6 +2,7 @@ /* remove the xfail for powerpc when pr58684 is fixed */ /* { dg-add-options ieee } */ /* { dg-require-effective-target fenv_exceptions } */ +/* { dg-skip-if "fenv" { powerpc-ibm-aix* } } */ #include diff --git a/gcc/testsuite/gcc.dg/torture/pr52451.c b/gcc/testsuite/gcc.dg/torture/pr52451.c index 1a2ece9..3f1580d5 100644 --- a/gcc/testsuite/gcc.dg/torture/pr52451.c +++ b/gcc/testsuite/gcc.dg/torture/pr52451.c @@ -1,6 +1,7 @@ /* { dg-do run } */ /* { dg-add-options ieee } */ /* { dg-require-effective-target fenv_exceptions } */ +/* { dg-skip-if "fenv" { powerpc-ibm-aix* } } */ #include diff --git a/gcc/testsuite/gcc.dg/torture/pr68264.c b/gcc/testsuite/gcc.dg/torture/pr68264.c index 3557a5f..1a498f0 100644 --- a/gcc/testsuite/gcc.dg/torture/pr68264.c +++ b/gcc/testsuite/gcc.dg/torture/pr68264.c @@ -2,6 +2,7 @@ /* { dg-skip-if "PR68356 no math-errno on darwin" { "*-*-darwin*" } } */ /* { dg-add-options ieee } */ /* { dg-require-effective-target fenv_exceptions } */ +/* { dg-skip-if "fenv" { powerpc-ibm-aix* } } */ #include #include diff --git a/gcc/testsuite/gcc.dg/torture/pr91323.c b/gcc/testsuite/gcc.dg/torture/pr91323.c index ce0d7f3..1411fca 100644 --- a/gcc/testsuite/gcc.dg/torture/pr91323.c +++ b/gcc/testsuite/gcc.dg/torture/pr91323.c @@ -1,6 +1,7 @@ /* { dg-do run } */ /* { dg-add-options ieee } */ /* { dg-require-effective-target fenv_exceptions } */ +/* { dg-skip-if "fenv" { powerpc-ibm-aix* } } */ #include -- cgit v1.1 From 920ea3b8ba3164b61ac9490dfdfceb6936eda6dd Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 6 Sep 2019 19:33:41 +0200 Subject: function.c (assign_parm_find_data_types): Use RECORD_OR_UNION_TYPE_P before testing TYPE_TRANSPARENT_AGGR. * function.c (assign_parm_find_data_types): Use RECORD_OR_UNION_TYPE_P before testing TYPE_TRANSPARENT_AGGR. * calls.c (initialize_argument_information, load_register_parameters): Likewise. From-SVN: r275472 --- gcc/ChangeLog | 7 +++++++ gcc/calls.c | 7 ++----- gcc/function.c | 3 +-- 3 files changed, 10 insertions(+), 7 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 65d9f43..7d5a272 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2019-09-06 Jakub Jelinek + + * function.c (assign_parm_find_data_types): Use RECORD_OR_UNION_TYPE_P + before testing TYPE_TRANSPARENT_AGGR. + * calls.c (initialize_argument_information, load_register_parameters): + Likewise. + 2019-09-06 Richard Earnshaw * config/arm/arm.md (cmp_and): Add short-it variant for thumb2 with diff --git a/gcc/calls.c b/gcc/calls.c index e5086f4..51ad55f 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -1991,8 +1991,7 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, /* If TYPE is a transparent union or record, pass things the way we would pass the first field of the union or record. We have already verified that the modes are the same. */ - if ((TREE_CODE (type) == UNION_TYPE || TREE_CODE (type) == RECORD_TYPE) - && TYPE_TRANSPARENT_AGGR (type)) + if (RECORD_OR_UNION_TYPE_P (type) && TYPE_TRANSPARENT_AGGR (type)) type = TREE_TYPE (first_field (type)); /* Decide where to pass this arg. @@ -2772,9 +2771,7 @@ load_register_parameters (struct arg_data *args, int num_actuals, HOST_WIDE_INT const_size = 0; rtx_insn *before_arg = get_last_insn (); tree type = TREE_TYPE (args[i].tree_value); - if ((TREE_CODE (type) == UNION_TYPE - || TREE_CODE (type) == RECORD_TYPE) - && TYPE_TRANSPARENT_AGGR (type)) + if (RECORD_OR_UNION_TYPE_P (type) && TYPE_TRANSPARENT_AGGR (type)) type = TREE_TYPE (first_field (type)); /* Set non-negative if we must move a word at a time, even if just one word (e.g, partial == 4 && mode == DFmode). Set diff --git a/gcc/function.c b/gcc/function.c index 751d2de3..5351605 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -2443,8 +2443,7 @@ assign_parm_find_data_types (struct assign_parm_data_all *all, tree parm, /* If the parm is to be passed as a transparent union or record, use the type of the first field for the tests below. We have already verified that the modes are the same. */ - if ((TREE_CODE (data->arg.type) == UNION_TYPE - || TREE_CODE (data->arg.type) == RECORD_TYPE) + if (RECORD_OR_UNION_TYPE_P (data->arg.type) && TYPE_TRANSPARENT_AGGR (data->arg.type)) data->arg.type = TREE_TYPE (first_field (data->arg.type)); -- cgit v1.1 From aa8901e9bb0399d2c16f988ba2fe46eb0c0c5d13 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 6 Sep 2019 18:12:46 +0000 Subject: libgo: update to Go 1.13beta1 release Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/193497 From-SVN: r275473 --- gcc/go/gofrontend/MERGE | 2 +- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/go.test/test/fixedbugs/bug369.go | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index b334136..7b2d17e 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -ca0fdb4c7735a648b8f10f1248631adf9afb8454 +8f2b844acda70330f7c50b360f8c983d2676ecbb The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ab4b2dc..c910555 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-06 Ian Lance Taylor + + * go.test/test/fixedbugs/bug369.go: Update to match libgo update + to Go 1.13beta1. + 2019-09-06 David Edelsohn * gcc.dg/torture/inf-compare-1.c: Skip AIX. diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug369.go b/gcc/testsuite/go.test/test/fixedbugs/bug369.go index 6d52622..7c9583a 100644 --- a/gcc/testsuite/go.test/test/fixedbugs/bug369.go +++ b/gcc/testsuite/go.test/test/fixedbugs/bug369.go @@ -38,6 +38,7 @@ func BenchmarkSlowNonASCII(b *testing.B) { } func main() { + testing.Init() os.Args = []string{os.Args[0], "-test.benchtime=100ms"} flag.Parse() -- cgit v1.1 From 4e9ad7c9d8e0efbbee876b60c7bffd622072523f Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Fri, 6 Sep 2019 21:27:58 +0200 Subject: re PR target/91654 (Regressions of SPEC2017 rate caused by r274994) PR target/91654 * config/i386/x86-tune-costs.h (skylake_cost): Raise the cost of SSE->integer and integer->SSE moves from 2 to 6. (core_cost): Ditto. From-SVN: r275475 --- gcc/ChangeLog | 7 +++++++ gcc/config/i386/x86-tune-costs.h | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7d5a272..86e8ab6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2019-09-06 Uroš Bizjak + + PR target/91654 + * config/i386/x86-tune-costs.h (skylake_cost): Raise the + cost of SSE->integer and integer->SSE moves from 2 to 6. + (core_cost): Ditto. + 2019-09-06 Jakub Jelinek * function.c (assign_parm_find_data_types): Use RECORD_OR_UNION_TYPE_P diff --git a/gcc/config/i386/x86-tune-costs.h b/gcc/config/i386/x86-tune-costs.h index 3381b8b..00edece 100644 --- a/gcc/config/i386/x86-tune-costs.h +++ b/gcc/config/i386/x86-tune-costs.h @@ -1610,7 +1610,7 @@ struct processor_costs skylake_cost = { in 32,64,128,256 and 512-bit */ {8, 8, 8, 12, 24}, /* cost of storing SSE registers in 32,64,128,256 and 512-bit */ - 2, 2, /* SSE->integer and integer->SSE moves */ + 6, 6, /* SSE->integer and integer->SSE moves */ /* End of register allocator costs. */ }, @@ -2555,7 +2555,7 @@ struct processor_costs core_cost = { in 32,64,128,256 and 512-bit */ {6, 6, 6, 6, 12}, /* cost of storing SSE registers in 32,64,128,256 and 512-bit */ - 2, 2, /* SSE->integer and integer->SSE moves */ + 6, 6, /* SSE->integer and integer->SSE moves */ /* End of register allocator costs. */ }, -- cgit v1.1 From 9393ab749215b663de0575267301036f5e5bb9f3 Mon Sep 17 00:00:00 2001 From: Segher Boessenkool Date: Fri, 6 Sep 2019 21:42:38 +0200 Subject: rs6000: Delete UNSPEC_FRSP This isn't used since 2012. (It's a remnant of RIOS support). * config/rs6000/rs6000.c (rs6000_rtx_costs) : Delete. * config/rs6000/rs6000.md (unspec): Delete UNSPEC_FRSP. From-SVN: r275476 --- gcc/ChangeLog | 5 +++++ gcc/config/rs6000/rs6000.c | 12 ------------ gcc/config/rs6000/rs6000.md | 3 +-- 3 files changed, 6 insertions(+), 14 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 86e8ab6..045cc0c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-09-06 Segher Boessenkool + + * config/rs6000/rs6000.c (rs6000_rtx_costs) : Delete. + * config/rs6000/rs6000.md (unspec): Delete UNSPEC_FRSP. + 2019-09-06 Uroš Bizjak PR target/91654 diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index e792116..e044c6e 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -20907,18 +20907,6 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code, *total = rs6000_cost->fp; return false; - case UNSPEC: - switch (XINT (x, 1)) - { - case UNSPEC_FRSP: - *total = rs6000_cost->fp; - return true; - - default: - break; - } - break; - case CALL: case IF_THEN_ELSE: if (!speed) diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index b0aea23..7b39334 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -58,8 +58,7 @@ ;; (define_c_enum "unspec" - [UNSPEC_FRSP ; frsp for POWER machines - UNSPEC_PROBE_STACK ; probe stack memory reference + [UNSPEC_PROBE_STACK ; probe stack memory reference UNSPEC_TOCPTR ; address of a word pointing to the TOC UNSPEC_TOC ; address of the TOC (more-or-less) UNSPEC_TOCSLOT ; offset from r1 of toc pointer save slot -- cgit v1.1 From e83573abb388801561768ed373c8e43a0f005110 Mon Sep 17 00:00:00 2001 From: Segher Boessenkool Date: Fri, 6 Sep 2019 21:43:47 +0200 Subject: rs6000: Delete UNSPEC_MV_CR_OV. This isn't used since 2018. (It's a remnant of paired single support). * config/rs6000/rs6000.md (unspec): Delete UNSPEC_MV_CR_OV. From-SVN: r275477 --- gcc/ChangeLog | 4 ++++ gcc/config/rs6000/rs6000.md | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 045cc0c..91069bf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,9 @@ 2019-09-06 Segher Boessenkool + * config/rs6000/rs6000.md (unspec): Delete UNSPEC_MV_CR_OV. + +2019-09-06 Segher Boessenkool + * config/rs6000/rs6000.c (rs6000_rtx_costs) : Delete. * config/rs6000/rs6000.md (unspec): Delete UNSPEC_FRSP. diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 7b39334..f0b0bb4 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -63,7 +63,6 @@ UNSPEC_TOC ; address of the TOC (more-or-less) UNSPEC_TOCSLOT ; offset from r1 of toc pointer save slot UNSPEC_MOVSI_GOT - UNSPEC_MV_CR_OV ; move_from_CR_ov_bit UNSPEC_FCTIWZ UNSPEC_FRIM UNSPEC_FRIN -- cgit v1.1 From 2f4d895197e7b137f50624bef58c9b614bf081e5 Mon Sep 17 00:00:00 2001 From: Jim Wilson Date: Sat, 7 Sep 2019 00:09:21 +0000 Subject: RISC-V: Re-enable -msave-restore for shared libraries. This re-enables -msave-restore for shared libraries, and uses the t-slibgcc-libgcc file to get the save-restore routines included directly in shared libraries so that we don't need to indirect through the PLT to reach them, which doesn't work. gcc/ * config/riscv/riscv.c (riscv_option_override): Revert 2019-08-30 change. libgcc/ * config.host (riscv*-*-linux*): Add t-slibgcc-libgcc to tmake_file. (riscv*-*-freebsd*): Likewise. From-SVN: r275478 --- gcc/ChangeLog | 5 +++++ gcc/config/riscv/riscv.c | 10 ---------- 2 files changed, 5 insertions(+), 10 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 91069bf..46c1b50 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-09-06 Jim Wilson + + * config/riscv/riscv.c (riscv_option_override): Revert 2019-08-30 + change. + 2019-09-06 Segher Boessenkool * config/rs6000/rs6000.md (unspec): Delete UNSPEC_MV_CR_OV. diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c index 1e7528f..9b16a1e 100644 --- a/gcc/config/riscv/riscv.c +++ b/gcc/config/riscv/riscv.c @@ -4636,16 +4636,6 @@ riscv_option_override (void) error ("%<-mriscv-attribute%> RISC-V ELF attribute requires GNU as 2.32" " [%<-mriscv-attribute%>]"); #endif - - /* The save-restore routines use t0 which is clobbered by the plt header, - so we can't use them when building shared libraries. */ - if (TARGET_SAVE_RESTORE && flag_pic && TARGET_PLT) - { - target_flags &= ~MASK_SAVE_RESTORE; - if (target_flags_explicit & MASK_SAVE_RESTORE) - warning (0, "%<-msave-restore%> disabled; not supported with PLT " - "based shared libraries"); - } } /* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */ -- cgit v1.1 From 739748850246fb630bb76412bf288b5365d7b58c Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sat, 7 Sep 2019 00:16:46 +0000 Subject: Daily bump. From-SVN: r275482 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 445ed44..3182cee 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20190906 +20190907 -- cgit v1.1 From d405dc23021fee4b6e1cd30650e0168b29918f61 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Sat, 7 Sep 2019 04:38:58 +0000 Subject: arm.c (arm_block_set_aligned_non_vect): Use gen_unaligned_storedi for 4-byte aligned addresses. 2019-09-07 Bernd Edlinger * config/arm/arm.c (arm_block_set_aligned_non_vect): Use gen_unaligned_storedi for 4-byte aligned addresses. testsuite: 2019-09-07 Bernd Edlinger * gcc.target/arm/pr91684.c: New test. From-SVN: r275483 --- gcc/ChangeLog | 5 +++++ gcc/config/arm/arm.c | 5 ++++- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.target/arm/pr91684.c | 15 +++++++++++++++ 4 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/arm/pr91684.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 46c1b50..c6925e2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-09-07 Bernd Edlinger + + * config/arm/arm.c (arm_block_set_aligned_non_vect): Use + gen_unaligned_storedi for 4-byte aligned addresses. + 2019-09-06 Jim Wilson * config/riscv/riscv.c (riscv_option_override): Revert 2019-08-30 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index eb8bf13..8576431 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -30352,7 +30352,10 @@ arm_block_set_aligned_non_vect (rtx dstbase, { addr = plus_constant (Pmode, dst, i); mem = adjust_automodify_address (dstbase, DImode, addr, i); - emit_move_insn (mem, reg); + if (MEM_ALIGN (mem) >= 2 * BITS_PER_WORD) + emit_move_insn (mem, reg); + else + emit_insn (gen_unaligned_storedi (mem, reg)); } } else diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c910555..c2e23be 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-09-07 Bernd Edlinger + + * gcc.target/arm/pr91684.c: New test. + 2019-09-06 Ian Lance Taylor * go.test/test/fixedbugs/bug369.go: Update to match libgo update diff --git a/gcc/testsuite/gcc.target/arm/pr91684.c b/gcc/testsuite/gcc.target/arm/pr91684.c new file mode 100644 index 0000000..619c30f --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr91684.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target arm_ldrd_strd_ok } */ +/* { dg-options "-O3" } */ + +typedef struct { int a, b, c; } S; + +void g (S *s); +void bug1 (void) +{ + S s; + __builtin_memset (&s, 0, sizeof (S)); + g (&s); +} + +/* { dg-final { scan-assembler-times "strd" 1 } } */ -- cgit v1.1 From 8b2d8beb9fcbd9196b562b17a21c892ff062aba8 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Sat, 7 Sep 2019 05:11:16 +0000 Subject: add PR target/91684 to ChangeLog From-SVN: r275484 --- gcc/ChangeLog | 1 + gcc/testsuite/ChangeLog | 1 + 2 files changed, 2 insertions(+) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c6925e2..bf85829 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,6 @@ 2019-09-07 Bernd Edlinger + PR target/91684 * config/arm/arm.c (arm_block_set_aligned_non_vect): Use gen_unaligned_storedi for 4-byte aligned addresses. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c2e23be..9d2c3d2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,6 @@ 2019-09-07 Bernd Edlinger + PR target/91684 * gcc.target/arm/pr91684.c: New test. 2019-09-06 Ian Lance Taylor -- cgit v1.1 From 44a06a709565805d68994b65d871565a07ebf73e Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sat, 7 Sep 2019 11:52:01 +0200 Subject: re PR tree-optimization/91665 (ICE in build_vector_from_val, at tree.c:1904) PR tree-optimization/91665 * tree-vect-loop.c (vectorizable_reduction): Punt if base has type incompatible with the type of PHI result. * gcc.dg/vect/pr91665.c: New test. From-SVN: r275486 --- gcc/ChangeLog | 6 ++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/vect/pr91665.c | 15 +++++++++++++++ gcc/tree-vect-loop.c | 5 ++++- 4 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/vect/pr91665.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bf85829..83581ac4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-09-07 Jakub Jelinek + + PR tree-optimization/91665 + * tree-vect-loop.c (vectorizable_reduction): Punt if base has type + incompatible with the type of PHI result. + 2019-09-07 Bernd Edlinger PR target/91684 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9d2c3d2..a53887a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-07 Jakub Jelinek + + PR tree-optimization/91665 + * gcc.dg/vect/pr91665.c: New test. + 2019-09-07 Bernd Edlinger PR target/91684 diff --git a/gcc/testsuite/gcc.dg/vect/pr91665.c b/gcc/testsuite/gcc.dg/vect/pr91665.c new file mode 100644 index 0000000..6b69ea0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr91665.c @@ -0,0 +1,15 @@ +/* PR tree-optimization/91665 */ +/* { dg-do compile } */ +/* { dg-additional-options "-Ofast" } */ + +short int v; + +void +foo (short int x, short int y) +{ + short int *p = &v; + + x = 1; + while (x != 0) + x += ++y || (*p = x); +} diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index b0cbbac..8324492 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -6656,10 +6656,13 @@ vectorizable_reduction (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, gcc_assert (TREE_CODE (base) == INTEGER_CST && TREE_CODE (step) == INTEGER_CST); cond_reduc_val = NULL_TREE; + tree res = PHI_RESULT (STMT_VINFO_STMT (cond_stmt_vinfo)); + if (!types_compatible_p (TREE_TYPE (res), TREE_TYPE (base))) + ; /* Find a suitable value, for MAX_EXPR below base, for MIN_EXPR above base; punt if base is the minimum value of the type for MAX_EXPR or maximum value of the type for MIN_EXPR for now. */ - if (tree_int_cst_sgn (step) == -1) + else if (tree_int_cst_sgn (step) == -1) { cond_reduc_op_code = MIN_EXPR; if (tree_int_cst_sgn (base) == -1) -- cgit v1.1 From e950ddb04b946b0b38acd493972cdb8479de35e4 Mon Sep 17 00:00:00 2001 From: David Edelsohn Date: Sat, 7 Sep 2019 15:23:51 +0000 Subject: decomp2.C: Add TLS options. * g++.dg/cpp2a/decomp2.C: Add TLS options. * gcc.target/powerpc/pr88233.c: Limit to lp64. From-SVN: r275488 --- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/cpp2a/decomp2.C | 1 + gcc/testsuite/gcc.target/powerpc/pr88233.c | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a53887a..75dd5ac2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-07 David Edelsohn + + * g++.dg/cpp2a/decomp2.C: Add TLS options. + * gcc.target/powerpc/pr88233.c: Limit to lp64. + 2019-09-07 Jakub Jelinek PR tree-optimization/91665 diff --git a/gcc/testsuite/g++.dg/cpp2a/decomp2.C b/gcc/testsuite/g++.dg/cpp2a/decomp2.C index 9149d02..c2bfe46 100644 --- a/gcc/testsuite/g++.dg/cpp2a/decomp2.C +++ b/gcc/testsuite/g++.dg/cpp2a/decomp2.C @@ -2,6 +2,7 @@ // { dg-do run { target c++11 } } // { dg-options "" } // { dg-require-effective-target tls } +// { dg-add-options tls } namespace std { template struct tuple_size; diff --git a/gcc/testsuite/gcc.target/powerpc/pr88233.c b/gcc/testsuite/gcc.target/powerpc/pr88233.c index fa47b57..c16235e 100644 --- a/gcc/testsuite/gcc.target/powerpc/pr88233.c +++ b/gcc/testsuite/gcc.target/powerpc/pr88233.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target lp64 } } */ /* { dg-options "-O2 -mcpu=power8" } */ typedef struct { double a[2]; } A; -- cgit v1.1 From 70ca91f5d41a33543420cff11cd689716e3219e3 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Sat, 7 Sep 2019 18:26:26 +0000 Subject: pr91684.c: Use effective-target arm_prefer_ldrd_strd. 2019-09-07 Bernd Edlinger * gcc.target/arm/pr91684.c: Use effective-target arm_prefer_ldrd_strd. From-SVN: r275489 --- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.target/arm/pr91684.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 75dd5ac2..b3e1416 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-09-07 Bernd Edlinger + + * gcc.target/arm/pr91684.c: Use effective-target arm_prefer_ldrd_strd. + 2019-09-07 David Edelsohn * g++.dg/cpp2a/decomp2.C: Add TLS options. diff --git a/gcc/testsuite/gcc.target/arm/pr91684.c b/gcc/testsuite/gcc.target/arm/pr91684.c index 619c30f..d2d63bc 100644 --- a/gcc/testsuite/gcc.target/arm/pr91684.c +++ b/gcc/testsuite/gcc.target/arm/pr91684.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-require-effective-target arm_ldrd_strd_ok } */ +/* { dg-require-effective-target arm_prefer_ldrd_strd } */ /* { dg-options "-O3" } */ typedef struct { int a, b, c; } S; -- cgit v1.1 From 30b94f55204397fe6537422c6aad82b155f01fec Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sun, 8 Sep 2019 00:16:34 +0000 Subject: Daily bump. From-SVN: r275493 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 3182cee..c204a76 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20190907 +20190908 -- cgit v1.1 From 9976b31c66d9b9ec6dcc3005a2fb5ae1742aef6b Mon Sep 17 00:00:00 2001 From: Segher Boessenkool Date: Sun, 8 Sep 2019 22:58:18 +0200 Subject: genemit: Print file+line in the "Splitting with" message It's tiresome to have to look in insn-emit.c to see where some split came from, so let's print that info to the dump file as well. But don't print the full path, just the basename, for greater readability. * genemit.c (gen_split): Print the filename and line number where the splitter (or peephole2) was defined, to the dump file. From-SVN: r275497 --- gcc/ChangeLog | 5 +++++ gcc/genemit.c | 9 +++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 83581ac4..c39e0d4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-09-08 Segher Boessenkool + + * genemit.c (gen_split): Print the filename and line number where the + splitter (or peephole2) was defined, to the dump file. + 2019-09-07 Jakub Jelinek PR tree-optimization/91665 diff --git a/gcc/genemit.c b/gcc/genemit.c index 3ff8197..4d7011c 100644 --- a/gcc/genemit.c +++ b/gcc/genemit.c @@ -609,9 +609,14 @@ gen_split (md_rtx_info *info) if (GET_CODE (split) == DEFINE_PEEPHOLE2) output_peephole2_scratches (split); + const char *fn = info->loc.filename; + for (const char *p = fn; *p; p++) + if (*p == '/') + fn = p + 1; + printf (" if (dump_file)\n"); - printf (" fprintf (dump_file, \"Splitting with gen_%s_%d\\n\");\n", - name, info->index); + printf (" fprintf (dump_file, \"Splitting with gen_%s_%d (%s:%d)\\n\");\n", + name, info->index, fn, info->loc.lineno); printf (" start_sequence ();\n"); -- cgit v1.1 From 108d64adcad2e199da2d29cbfb35d617c9196f7c Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Mon, 9 Sep 2019 00:17:08 +0000 Subject: Daily bump. From-SVN: r275501 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index c204a76..4defdea 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20190908 +20190909 -- cgit v1.1 From 4bc8aadf033c7dbbbb16ba99e3260da0c0fd39bf Mon Sep 17 00:00:00 2001 From: "Jose E. Marchesi" Date: Mon, 9 Sep 2019 11:44:23 +0200 Subject: opt-functions.awk: fix comparison of limit, begin and end The function integer_range_info makes sure that, if provided, the initial value fills in the especified range. However, it is necessary to convert the values to a numerical context before comparing, to make sure awk is using arithmetical order and not lexicographical order. gcc/ChangeLog: * opt-functions.awk (integer_range_info): Make sure values are in numeric context before operating with them. From-SVN: r275503 --- gcc/ChangeLog | 5 +++++ gcc/opt-functions.awk | 7 ++++--- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c39e0d4..a8c3a2a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-09-09 Jose E. Marchesi + + * opt-functions.awk (integer_range_info): Make sure values are in + numeric context before operating with them. + 2019-09-08 Segher Boessenkool * genemit.c (gen_split): Print the filename and line number where the diff --git a/gcc/opt-functions.awk b/gcc/opt-functions.awk index 1190e6d..c1da80c 100644 --- a/gcc/opt-functions.awk +++ b/gcc/opt-functions.awk @@ -346,9 +346,10 @@ function search_var_name(name, opt_numbers, opts, flags, n_opts) function integer_range_info(range_option, init, option) { if (range_option != "") { - start = nth_arg(0, range_option); - end = nth_arg(1, range_option); - if (init != "" && init != "-1" && (init < start || init > end)) + ival = init + 0; + start = nth_arg(0, range_option) + 0; + end = nth_arg(1, range_option) + 0; + if (init != "" && init != "-1" && (ival < start || ival > end)) print "#error initial value " init " of '" option "' must be in range [" start "," end "]" return start ", " end } -- cgit v1.1 From e9b8025bb071f9980aa54c80e642dc855542fd1b Mon Sep 17 00:00:00 2001 From: "Jose E. Marchesi" Date: Mon, 9 Sep 2019 11:49:34 +0200 Subject: testsuite: annotate c-torture/compile tests with dg-require-stack-size This patch annotates tests that make use of a significant a mount of stack space. Embedded and other restricted targets may have problems compiling and running these tests. Note that the annotations are in many cases not exact. testsuite/ChangeLog: * gcc.c-torture/compile/20000609-1.c: Annotate with dg-require-stack-size. * gcc.c-torture/compile/20000804-1.c: Likewise. * gcc.c-torture/compile/20020304-1.c: Likewise. * gcc.c-torture/compile/20020604-1.c: Likewise. * gcc.c-torture/compile/20021015-1.c: Likewise. * gcc.c-torture/compile/20050303-1.c: Likewise. * gcc.c-torture/compile/20060421-1.c: Likewise. * gcc.c-torture/compile/20071207-1.c: Likewise. * gcc.c-torture/compile/20080903-1.c: Likewise. * gcc.c-torture/compile/20121027-1.c: Likewise. * gcc.c-torture/compile/20151204.c: Likewise. * gcc.c-torture/compile/920501-12.c: Likewise. * gcc.c-torture/compile/920501-4.c: Likewise. * gcc.c-torture/compile/920723-1.c: Likewise. * gcc.c-torture/compile/921202-1.c: Likewise. * gcc.c-torture/compile/931003-1.c: Likewise. * gcc.c-torture/compile/931004-1.c: Likewise. * gcc.c-torture/compile/950719-1.c: Likewise. * gcc.c-torture/compile/951222-1.c: Likewise. * gcc.c-torture/compile/990517-1.c: Likewise. * gcc.c-torture/compile/bcopy.c: Likewise. * gcc.c-torture/compile/pr23929.c: Likewise. * gcc.c-torture/compile/pr25310.c: Likewise. * gcc.c-torture/compile/pr34458.c: Likewise. * gcc.c-torture/compile/pr39937.c: Likewise. * gcc.c-torture/compile/pr41181.c: Likewise. * gcc.c-torture/compile/pr41634.c: Likewise. * gcc.c-torture/compile/pr43415.c: Likewise. * gcc.c-torture/compile/pr43417.c: Likewise. * gcc.c-torture/compile/pr44788.c: Likewise. * gcc.c-torture/compile/sound.c: Likewise. From-SVN: r275504 --- gcc/testsuite/ChangeLog | 35 ++++++++++++++++++++++++ gcc/testsuite/gcc.c-torture/compile/20000609-1.c | 2 ++ gcc/testsuite/gcc.c-torture/compile/20000804-1.c | 1 + gcc/testsuite/gcc.c-torture/compile/20020304-1.c | 2 ++ gcc/testsuite/gcc.c-torture/compile/20020604-1.c | 1 + gcc/testsuite/gcc.c-torture/compile/20021015-1.c | 1 + gcc/testsuite/gcc.c-torture/compile/20050303-1.c | 1 + gcc/testsuite/gcc.c-torture/compile/20060421-1.c | 2 ++ gcc/testsuite/gcc.c-torture/compile/20071207-1.c | 1 + gcc/testsuite/gcc.c-torture/compile/20080903-1.c | 2 ++ gcc/testsuite/gcc.c-torture/compile/20121027-1.c | 2 ++ gcc/testsuite/gcc.c-torture/compile/20151204.c | 1 + gcc/testsuite/gcc.c-torture/compile/920501-12.c | 1 + gcc/testsuite/gcc.c-torture/compile/920501-4.c | 1 + gcc/testsuite/gcc.c-torture/compile/920723-1.c | 1 + gcc/testsuite/gcc.c-torture/compile/921202-1.c | 2 ++ gcc/testsuite/gcc.c-torture/compile/931003-1.c | 2 ++ gcc/testsuite/gcc.c-torture/compile/931004-1.c | 2 ++ gcc/testsuite/gcc.c-torture/compile/950719-1.c | 2 ++ gcc/testsuite/gcc.c-torture/compile/951222-1.c | 2 ++ gcc/testsuite/gcc.c-torture/compile/990517-1.c | 3 ++ gcc/testsuite/gcc.c-torture/compile/bcopy.c | 1 + gcc/testsuite/gcc.c-torture/compile/pr23929.c | 1 + gcc/testsuite/gcc.c-torture/compile/pr25310.c | 1 + gcc/testsuite/gcc.c-torture/compile/pr34458.c | 1 + gcc/testsuite/gcc.c-torture/compile/pr39937.c | 2 ++ gcc/testsuite/gcc.c-torture/compile/pr41181.c | 2 ++ gcc/testsuite/gcc.c-torture/compile/pr41634.c | 2 ++ gcc/testsuite/gcc.c-torture/compile/pr43415.c | 2 ++ gcc/testsuite/gcc.c-torture/compile/pr43417.c | 2 ++ gcc/testsuite/gcc.c-torture/compile/pr44788.c | 2 ++ gcc/testsuite/gcc.c-torture/compile/sound.c | 1 + 32 files changed, 84 insertions(+) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b3e1416..0a8c405 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,38 @@ +2019-09-09 Jose E. Marchesi + + * gcc.c-torture/compile/20000609-1.c: Annotate with + dg-require-stack-size. + * gcc.c-torture/compile/20000804-1.c: Likewise. + * gcc.c-torture/compile/20020304-1.c: Likewise. + * gcc.c-torture/compile/20020604-1.c: Likewise. + * gcc.c-torture/compile/20021015-1.c: Likewise. + * gcc.c-torture/compile/20050303-1.c: Likewise. + * gcc.c-torture/compile/20060421-1.c: Likewise. + * gcc.c-torture/compile/20071207-1.c: Likewise. + * gcc.c-torture/compile/20080903-1.c: Likewise. + * gcc.c-torture/compile/20121027-1.c: Likewise. + * gcc.c-torture/compile/20151204.c: Likewise. + * gcc.c-torture/compile/920501-12.c: Likewise. + * gcc.c-torture/compile/920501-4.c: Likewise. + * gcc.c-torture/compile/920723-1.c: Likewise. + * gcc.c-torture/compile/921202-1.c: Likewise. + * gcc.c-torture/compile/931003-1.c: Likewise. + * gcc.c-torture/compile/931004-1.c: Likewise. + * gcc.c-torture/compile/950719-1.c: Likewise. + * gcc.c-torture/compile/951222-1.c: Likewise. + * gcc.c-torture/compile/990517-1.c: Likewise. + * gcc.c-torture/compile/bcopy.c: Likewise. + * gcc.c-torture/compile/pr23929.c: Likewise. + * gcc.c-torture/compile/pr25310.c: Likewise. + * gcc.c-torture/compile/pr34458.c: Likewise. + * gcc.c-torture/compile/pr39937.c: Likewise. + * gcc.c-torture/compile/pr41181.c: Likewise. + * gcc.c-torture/compile/pr41634.c: Likewise. + * gcc.c-torture/compile/pr43415.c: Likewise. + * gcc.c-torture/compile/pr43417.c: Likewise. + * gcc.c-torture/compile/pr44788.c: Likewise. + * gcc.c-torture/compile/sound.c: Likewise. + 2019-09-07 Bernd Edlinger * gcc.target/arm/pr91684.c: Use effective-target arm_prefer_ldrd_strd. diff --git a/gcc/testsuite/gcc.c-torture/compile/20000609-1.c b/gcc/testsuite/gcc.c-torture/compile/20000609-1.c index f03aa35..e41701c 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20000609-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20000609-1.c @@ -1,3 +1,5 @@ +/* { dg-require-stack-size "1024" } */ + int main () { char temp[1024] = "tempfile"; diff --git a/gcc/testsuite/gcc.c-torture/compile/20000804-1.c b/gcc/testsuite/gcc.c-torture/compile/20000804-1.c index 35464c2..550669b 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20000804-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20000804-1.c @@ -6,6 +6,7 @@ /* { dg-skip-if "Not enough 64-bit registers" { pdp11-*-* } { "-O0" } { "" } } */ /* { dg-xfail-if "Inconsistent constraint on asm" { csky-*-* } { "-O0" } { "" } } */ /* { dg-xfail-if "" { h8300-*-* } } */ +/* { dg-require-stack-size "99*4+16" } */ /* Copyright (C) 2000, 2003 Free Software Foundation */ __complex__ long long f () diff --git a/gcc/testsuite/gcc.c-torture/compile/20020304-1.c b/gcc/testsuite/gcc.c-torture/compile/20020304-1.c index 3940d5f..046c5d6 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20020304-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20020304-1.c @@ -4,6 +4,8 @@ Original bug report is c/5830 by Manuel Serrano . */ +/* { dg-require-stack-size "513" } */ + typedef union scmobj { struct pair { union scmobj *car; diff --git a/gcc/testsuite/gcc.c-torture/compile/20020604-1.c b/gcc/testsuite/gcc.c-torture/compile/20020604-1.c index d2e186a..4846f79 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20020604-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20020604-1.c @@ -1,6 +1,7 @@ /* { dg-do assemble } */ /* { dg-require-effective-target ptr32plus } */ /* { dg-xfail-if "The array too big" { "h8300-*-*" } { "-mno-h" "-mn" } { "" } } */ +/* { dg-require-stack-size "2048*4*4" } */ /* PR c/6957 This testcase ICEd at -O2 on IA-32, because diff --git a/gcc/testsuite/gcc.c-torture/compile/20021015-1.c b/gcc/testsuite/gcc.c-torture/compile/20021015-1.c index 789b8a8..9753876 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20021015-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20021015-1.c @@ -1,4 +1,5 @@ /* PR target/7370. */ +/* { dg-require-stack-size "4000 + 8" } */ int g (int *x, int *y); diff --git a/gcc/testsuite/gcc.c-torture/compile/20050303-1.c b/gcc/testsuite/gcc.c-torture/compile/20050303-1.c index 22154b3..0261acd 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20050303-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20050303-1.c @@ -1,5 +1,6 @@ /* { dg-require-effective-target int32plus } */ /* { dg-require-effective-target size32plus } */ +/* { dg-require-stack-size "128*1024" } */ void crc() { diff --git a/gcc/testsuite/gcc.c-torture/compile/20060421-1.c b/gcc/testsuite/gcc.c-torture/compile/20060421-1.c index 1bd4079..05396d3 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20060421-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20060421-1.c @@ -1,4 +1,6 @@ /* This test used to ICE on ARM with -mcpu=iwmmxt. */ +/* { dg-require-stack-size "249*8+1" } */ + void foo (void) { diff --git a/gcc/testsuite/gcc.c-torture/compile/20071207-1.c b/gcc/testsuite/gcc.c-torture/compile/20071207-1.c index 27b8716..fecf531 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20071207-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20071207-1.c @@ -1,4 +1,5 @@ /* PR tree-optimization/34371 */ +/* { dg-require-stack-size "1108" } */ /* Testcase by Martin Michlmayr */ void centerln (int width, int ch, char *s) diff --git a/gcc/testsuite/gcc.c-torture/compile/20080903-1.c b/gcc/testsuite/gcc.c-torture/compile/20080903-1.c index 180b926..d446ebf 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20080903-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20080903-1.c @@ -1,3 +1,5 @@ +/* { dg-require-stack-size "4096" } */ + struct bar { unsigned short length; }; int diff --git a/gcc/testsuite/gcc.c-torture/compile/20121027-1.c b/gcc/testsuite/gcc.c-torture/compile/20121027-1.c index 3d3ff31..7c92f3f 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20121027-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20121027-1.c @@ -1,3 +1,5 @@ +/* { dg-require-stack-size "1024+16" } */ + extern int nc; void f(void) { diff --git a/gcc/testsuite/gcc.c-torture/compile/20151204.c b/gcc/testsuite/gcc.c-torture/compile/20151204.c index e41f6c1..a6bac5d 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20151204.c +++ b/gcc/testsuite/gcc.c-torture/compile/20151204.c @@ -1,4 +1,5 @@ /* { dg-require-effective-target size20plus } */ +/* { dg-require-stack-size "32753*2" } */ typedef __SIZE_TYPE__ size_t; diff --git a/gcc/testsuite/gcc.c-torture/compile/920501-12.c b/gcc/testsuite/gcc.c-torture/compile/920501-12.c index 68892a6..089de4d 100644 --- a/gcc/testsuite/gcc.c-torture/compile/920501-12.c +++ b/gcc/testsuite/gcc.c-torture/compile/920501-12.c @@ -1,5 +1,6 @@ /* { dg-do assemble } */ /* { dg-skip-if "Array too big" { "pdp11-*-*" } { "-mint32" } } */ +/* { dg-require-stack-size "9999*4" } */ x(x){ return 3 + x;} a(x){int y[994]; return 3 + x;} diff --git a/gcc/testsuite/gcc.c-torture/compile/920501-4.c b/gcc/testsuite/gcc.c-torture/compile/920501-4.c index 10736ae..2ef54b5 100644 --- a/gcc/testsuite/gcc.c-torture/compile/920501-4.c +++ b/gcc/testsuite/gcc.c-torture/compile/920501-4.c @@ -1,6 +1,7 @@ /* { dg-do assemble } */ /* { dg-skip-if "ptxas times out" { nvptx-*-* } { "-O1" } { "" } } */ /* { dg-skip-if "Array too big" { "pdp11-*-*" } { "-mint32" } } */ +/* { dg-require-stack-size "8196*4" } */ foo () { diff --git a/gcc/testsuite/gcc.c-torture/compile/920723-1.c b/gcc/testsuite/gcc.c-torture/compile/920723-1.c index cd8710b..2d77875 100644 --- a/gcc/testsuite/gcc.c-torture/compile/920723-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/920723-1.c @@ -1,4 +1,5 @@ /* { dg-add-options stack_size } */ +/* { dg-require-stack-size "75*75*4" } */ #if defined(STACK_SIZE) && STACK_SIZE < 65536 # define GITT_SIZE 75 diff --git a/gcc/testsuite/gcc.c-torture/compile/921202-1.c b/gcc/testsuite/gcc.c-torture/compile/921202-1.c index 1287edc..d97ddf6 100644 --- a/gcc/testsuite/gcc.c-torture/compile/921202-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/921202-1.c @@ -1,3 +1,5 @@ +/* { dg-require-stack-size "2055*3*8" } */ + f () { long dx[2055]; diff --git a/gcc/testsuite/gcc.c-torture/compile/931003-1.c b/gcc/testsuite/gcc.c-torture/compile/931003-1.c index 922b143..637b9aa 100644 --- a/gcc/testsuite/gcc.c-torture/compile/931003-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/931003-1.c @@ -1,3 +1,5 @@ +/* { dg-require-stack-size "52*8" } */ + f (n, a) int n; double a[]; diff --git a/gcc/testsuite/gcc.c-torture/compile/931004-1.c b/gcc/testsuite/gcc.c-torture/compile/931004-1.c index 0e741fd..d5796ce 100644 --- a/gcc/testsuite/gcc.c-torture/compile/931004-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/931004-1.c @@ -1,3 +1,5 @@ +/* { dg-require-stack-size "4*4*2*80" } */ + #define A "This is a long test that tests the structure initialization" #define B A,A #define C B,B,B,B diff --git a/gcc/testsuite/gcc.c-torture/compile/950719-1.c b/gcc/testsuite/gcc.c-torture/compile/950719-1.c index d3277fa..e1ac117 100644 --- a/gcc/testsuite/gcc.c-torture/compile/950719-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/950719-1.c @@ -1,3 +1,5 @@ +/* { dg-require-stack-size "4092+4" } */ + typedef struct { int Header; diff --git a/gcc/testsuite/gcc.c-torture/compile/951222-1.c b/gcc/testsuite/gcc.c-torture/compile/951222-1.c index b8246f5..f1818e3 100644 --- a/gcc/testsuite/gcc.c-torture/compile/951222-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/951222-1.c @@ -1,3 +1,5 @@ +/* { dg-require-stack-size "10000+3*8" } */ + extern long long foo (); long long diff --git a/gcc/testsuite/gcc.c-torture/compile/990517-1.c b/gcc/testsuite/gcc.c-torture/compile/990517-1.c index c738d4b..afdd844 100644 --- a/gcc/testsuite/gcc.c-torture/compile/990517-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/990517-1.c @@ -1,4 +1,7 @@ /* Extracted from the sdm module in perl. */ + +/* { dg-require-stack-size "12*2+8+1024+8" } */ + typedef struct { char *dptr; int dsize; diff --git a/gcc/testsuite/gcc.c-torture/compile/bcopy.c b/gcc/testsuite/gcc.c-torture/compile/bcopy.c index 8108f29..fce95c84 100644 --- a/gcc/testsuite/gcc.c-torture/compile/bcopy.c +++ b/gcc/testsuite/gcc.c-torture/compile/bcopy.c @@ -1,4 +1,5 @@ /* { dg-add-options stack_size } */ +/* { dg-require-stack-size "[dg-effective-target-value stack_size]*2" } */ void bcopy1 (s, d, c) diff --git a/gcc/testsuite/gcc.c-torture/compile/pr23929.c b/gcc/testsuite/gcc.c-torture/compile/pr23929.c index 210bb585..2ec6584 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr23929.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr23929.c @@ -1,4 +1,5 @@ /* PR tree-optimization/23929 */ +/* { dg-require-stack-size "2048+8" } */ extern void bar (char *); diff --git a/gcc/testsuite/gcc.c-torture/compile/pr25310.c b/gcc/testsuite/gcc.c-torture/compile/pr25310.c index 54695e0..7bdd0c5 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr25310.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr25310.c @@ -1,4 +1,5 @@ /* { dg-skip-if "Array too big" { "pdp11-*-*" } { "-mint32" } } */ +/* { dg-require-stack-size "65536+20" } */ /* Prevent spurious test failures on 16-bit targets. */ #if __INT_MAX__ >= 2147483647L diff --git a/gcc/testsuite/gcc.c-torture/compile/pr34458.c b/gcc/testsuite/gcc.c-torture/compile/pr34458.c index 096cc0c..7715493 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr34458.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr34458.c @@ -1,4 +1,5 @@ /* Testcase by Martin Michlmayr */ +/* { dg-require-stack-size "1025*4" } */ typedef struct { diff --git a/gcc/testsuite/gcc.c-torture/compile/pr39937.c b/gcc/testsuite/gcc.c-torture/compile/pr39937.c index d023105..df28053 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr39937.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr39937.c @@ -1,3 +1,5 @@ +/* { dg-require-stack-size "4096" } */ + int foo (__const char *__restrict __s); static void read_anisou(char line[]) diff --git a/gcc/testsuite/gcc.c-torture/compile/pr41181.c b/gcc/testsuite/gcc.c-torture/compile/pr41181.c index f866249..4e12d37 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr41181.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr41181.c @@ -1,5 +1,7 @@ /* { dg-require-effective-target ptr32plus } */ /* { dg-skip-if "The array is too big" { "avr-*-*" "pdp11-*-*" } } */ +/* { dg-require-stack-size "250*250" } */ + char paths[1024]; static void x264_slicetype_path(char (*best_paths)[250], int n, int length) { diff --git a/gcc/testsuite/gcc.c-torture/compile/pr41634.c b/gcc/testsuite/gcc.c-torture/compile/pr41634.c index 976e463..afad6d2 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr41634.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr41634.c @@ -1,3 +1,5 @@ +/* { dg-require-stack-size "2*512 + 256" } */ + extern int _xgetw(); extern int foo(char*); diff --git a/gcc/testsuite/gcc.c-torture/compile/pr43415.c b/gcc/testsuite/gcc.c-torture/compile/pr43415.c index c00e1c4..66afe99 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr43415.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr43415.c @@ -1,3 +1,5 @@ +/* { dg-require-stack-size "256*8+4" } */ + int main() { unsigned long long table[256]; diff --git a/gcc/testsuite/gcc.c-torture/compile/pr43417.c b/gcc/testsuite/gcc.c-torture/compile/pr43417.c index 45bf053..5ae98be 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr43417.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr43417.c @@ -1,3 +1,5 @@ +/* { dg-require-stack-size "1004*4+2*8" } */ + int pid_count = 0; unsigned int getopt (int, const char**, const char*); diff --git a/gcc/testsuite/gcc.c-torture/compile/pr44788.c b/gcc/testsuite/gcc.c-torture/compile/pr44788.c index 99dc798..b570f65 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr44788.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr44788.c @@ -1,3 +1,5 @@ +/* { dg-require-stack-size "1060*4+4" } */ + void joint_decode(float* mlt_buffer1, int t) { int i; float decode_buffer[1060]; diff --git a/gcc/testsuite/gcc.c-torture/compile/sound.c b/gcc/testsuite/gcc.c-torture/compile/sound.c index be727e3..66e24a0 100644 --- a/gcc/testsuite/gcc.c-torture/compile/sound.c +++ b/gcc/testsuite/gcc.c-torture/compile/sound.c @@ -1,3 +1,4 @@ +/* { dg-require-stack-size "8192+4" } */ main () { -- cgit v1.1 From a5362c6aea5ea6b07803d8f9f6f783154e250ce4 Mon Sep 17 00:00:00 2001 From: "Jose E. Marchesi" Date: Mon, 9 Sep 2019 11:55:10 +0200 Subject: testsuite: new require effective target indirect_calls This patch adds a new dg_require_effective_target procedure to the testsuite infrastructure: indirect_calls. This new function tells whether a target supports calls to non-constant call targets. This patch also annotates the tests in the gcc.c-torture testuite that require support for indirect calls. gcc/ChangeLog: * doc/sourcebuild.texi (Effective-Target Keywords): Document indirect_calls. gcc/testsuite/ChangeLog: * lib/target-supports.exp (check_effective_target_indirect_calls): New proc. * gcc.c-torture/compile/20010102-1.c: Annotate with dg-require-effective-target indirect_calls. * gcc.c-torture/compile/20010107-1.c: Likewise. * gcc.c-torture/compile/20011109-1.c: Likewise. * gcc.c-torture/compile/20011218-1.c: Likewise. * gcc.c-torture/compile/20011229-1.c: Likewise. * gcc.c-torture/compile/20020129-1.c: Likewise. * gcc.c-torture/compile/20020320-1.c: Likewise. * gcc.c-torture/compile/20020706-1.c: Likewise. * gcc.c-torture/compile/20020706-2.c: Likewise. * gcc.c-torture/compile/20021205-1.c: Likewise. * gcc.c-torture/compile/20030921-1.c: Likewise. * gcc.c-torture/compile/20031023-1.c: Likewise. * gcc.c-torture/compile/20031023-2.c: Likewise. * gcc.c-torture/compile/20031023-3.c: Likewise. * gcc.c-torture/compile/20031023-4.c: Likewise. * gcc.c-torture/compile/20040614-1.c: Likewise. * gcc.c-torture/compile/20040909-1.c: Likewise. * gcc.c-torture/compile/20050122-1.c: Likewise. * gcc.c-torture/compile/20050202-1.c: Likewise. * gcc.c-torture/compile/20060208-1.c: Likewise. * gcc.c-torture/compile/20081108-1.c: Likewise. * gcc.c-torture/compile/20150327.c: Likewise. * gcc.c-torture/compile/920428-2.c: Likewise. * gcc.c-torture/compile/920928-5.c: Likewise. * gcc.c-torture/compile/930117-1.c: Likewise. * gcc.c-torture/compile/930607-1.c: Likewise. * gcc.c-torture/compile/991213-2.c: Likewise. * gcc.c-torture/compile/callind.c: Likewise. * gcc.c-torture/compile/calls-void.c: Likewise. * gcc.c-torture/compile/calls.c: Likewise. * gcc.c-torture/compile/pr21840.c: Likewise. * gcc.c-torture/compile/pr32139.c: Likewise. * gcc.c-torture/compile/pr35607.c: Likewise. * gcc.c-torture/compile/pr37433-1.c: Likewise. * gcc.c-torture/compile/pr37433.c: Likewise. * gcc.c-torture/compile/pr39941.c: Likewise. * gcc.c-torture/compile/pr40080.c: Likewise. * gcc.c-torture/compile/pr43635.c: Likewise. * gcc.c-torture/compile/pr43791.c: Likewise. * gcc.c-torture/compile/pr43845.c: Likewise. * gcc.c-torture/compile/pr44043.c: Likewise. * gcc.c-torture/compile/pr51694.c: Likewise. * gcc.c-torture/compile/pr77754-2.c: Likewise. * gcc.c-torture/compile/pr77754-3.c: Likewise. * gcc.c-torture/compile/pr77754-4.c: Likewise. * gcc.c-torture/compile/pr89663-2.c: Likewise. * gcc.c-torture/compile/pta-1.c: Likewise. * gcc.c-torture/compile/stack-check-1.c: Likewise. * gcc.dg/Walloc-size-larger-than-18.c: Likewise. From-SVN: r275505 --- gcc/ChangeLog | 5 ++ gcc/doc/sourcebuild.texi | 4 ++ gcc/testsuite/ChangeLog | 55 ++++++++++++++++++++++ gcc/testsuite/gcc.c-torture/compile/20010102-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/20010107-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/20011109-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/20011218-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/20011229-1.c | 3 ++ gcc/testsuite/gcc.c-torture/compile/20020129-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/20020320-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/20020706-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/20020706-2.c | 2 + gcc/testsuite/gcc.c-torture/compile/20021205-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/20030921-1.c | 1 + gcc/testsuite/gcc.c-torture/compile/20031023-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/20031023-2.c | 2 + gcc/testsuite/gcc.c-torture/compile/20031023-3.c | 2 + gcc/testsuite/gcc.c-torture/compile/20031023-4.c | 2 + gcc/testsuite/gcc.c-torture/compile/20040614-1.c | 1 + gcc/testsuite/gcc.c-torture/compile/20040909-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/20050122-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/20050202-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/20060208-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/20081108-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/20150327.c | 2 + gcc/testsuite/gcc.c-torture/compile/920428-2.c | 2 + gcc/testsuite/gcc.c-torture/compile/920928-5.c | 3 ++ gcc/testsuite/gcc.c-torture/compile/930117-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/930607-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/991213-2.c | 2 + gcc/testsuite/gcc.c-torture/compile/callind.c | 2 + gcc/testsuite/gcc.c-torture/compile/calls-void.c | 1 + gcc/testsuite/gcc.c-torture/compile/calls.c | 1 + gcc/testsuite/gcc.c-torture/compile/pr21840.c | 2 + gcc/testsuite/gcc.c-torture/compile/pr32139.c | 2 + gcc/testsuite/gcc.c-torture/compile/pr35607.c | 2 + gcc/testsuite/gcc.c-torture/compile/pr37433-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/pr37433.c | 2 + gcc/testsuite/gcc.c-torture/compile/pr39941.c | 2 + gcc/testsuite/gcc.c-torture/compile/pr40080.c | 2 + gcc/testsuite/gcc.c-torture/compile/pr43635.c | 2 + gcc/testsuite/gcc.c-torture/compile/pr43791.c | 2 + gcc/testsuite/gcc.c-torture/compile/pr43845.c | 2 + gcc/testsuite/gcc.c-torture/compile/pr44043.c | 2 + gcc/testsuite/gcc.c-torture/compile/pr51694.c | 2 + gcc/testsuite/gcc.c-torture/compile/pr77754-2.c | 1 + gcc/testsuite/gcc.c-torture/compile/pr77754-3.c | 1 + gcc/testsuite/gcc.c-torture/compile/pr77754-4.c | 1 + gcc/testsuite/gcc.c-torture/compile/pr89663-2.c | 1 + gcc/testsuite/gcc.c-torture/compile/pta-1.c | 2 + .../gcc.c-torture/compile/stack-check-1.c | 1 + gcc/testsuite/gcc.dg/Walloc-size-larger-than-18.c | 1 + gcc/testsuite/lib/target-supports.exp | 8 ++++ 53 files changed, 162 insertions(+) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a8c3a2a..cb28809 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2019-09-09 Jose E. Marchesi + * doc/sourcebuild.texi (Effective-Target Keywords): Document + indirect_calls. + +2019-09-09 Jose E. Marchesi + * opt-functions.awk (integer_range_info): Make sure values are in numeric context before operating with them. diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi index d713c08..e4180cc 100644 --- a/gcc/doc/sourcebuild.texi +++ b/gcc/doc/sourcebuild.texi @@ -2374,6 +2374,10 @@ Target supports @code{wchar_t} that is compatible with @code{char32_t}. @item comdat_group Target uses comdat groups. + +@item indirect_calls +Target supports indirect calls, i.e. calls where the target is not +constant. @end table @subsubsection Local to tests in @code{gcc.target/i386} diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0a8c405..9533da6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,60 @@ 2019-09-09 Jose E. Marchesi + * lib/target-supports.exp (check_effective_target_indirect_calls): + New proc. + * gcc.c-torture/compile/20010102-1.c: Annotate with + dg-require-effective-target indirect_calls. + * gcc.c-torture/compile/20010107-1.c: Likewise. + * gcc.c-torture/compile/20011109-1.c: Likewise. + * gcc.c-torture/compile/20011218-1.c: Likewise. + * gcc.c-torture/compile/20011229-1.c: Likewise. + * gcc.c-torture/compile/20020129-1.c: Likewise. + * gcc.c-torture/compile/20020320-1.c: Likewise. + * gcc.c-torture/compile/20020706-1.c: Likewise. + * gcc.c-torture/compile/20020706-2.c: Likewise. + * gcc.c-torture/compile/20021205-1.c: Likewise. + * gcc.c-torture/compile/20030921-1.c: Likewise. + * gcc.c-torture/compile/20031023-1.c: Likewise. + * gcc.c-torture/compile/20031023-2.c: Likewise. + * gcc.c-torture/compile/20031023-3.c: Likewise. + * gcc.c-torture/compile/20031023-4.c: Likewise. + * gcc.c-torture/compile/20040614-1.c: Likewise. + * gcc.c-torture/compile/20040909-1.c: Likewise. + * gcc.c-torture/compile/20050122-1.c: Likewise. + * gcc.c-torture/compile/20050202-1.c: Likewise. + * gcc.c-torture/compile/20060208-1.c: Likewise. + * gcc.c-torture/compile/20081108-1.c: Likewise. + * gcc.c-torture/compile/20150327.c: Likewise. + * gcc.c-torture/compile/920428-2.c: Likewise. + * gcc.c-torture/compile/920928-5.c: Likewise. + * gcc.c-torture/compile/930117-1.c: Likewise. + * gcc.c-torture/compile/930607-1.c: Likewise. + * gcc.c-torture/compile/991213-2.c: Likewise. + * gcc.c-torture/compile/callind.c: Likewise. + * gcc.c-torture/compile/calls-void.c: Likewise. + * gcc.c-torture/compile/calls.c: Likewise. + * gcc.c-torture/compile/pr21840.c: Likewise. + * gcc.c-torture/compile/pr32139.c: Likewise. + * gcc.c-torture/compile/pr35607.c: Likewise. + * gcc.c-torture/compile/pr37433-1.c: Likewise. + * gcc.c-torture/compile/pr37433.c: Likewise. + * gcc.c-torture/compile/pr39941.c: Likewise. + * gcc.c-torture/compile/pr40080.c: Likewise. + * gcc.c-torture/compile/pr43635.c: Likewise. + * gcc.c-torture/compile/pr43791.c: Likewise. + * gcc.c-torture/compile/pr43845.c: Likewise. + * gcc.c-torture/compile/pr44043.c: Likewise. + * gcc.c-torture/compile/pr51694.c: Likewise. + * gcc.c-torture/compile/pr77754-2.c: Likewise. + * gcc.c-torture/compile/pr77754-3.c: Likewise. + * gcc.c-torture/compile/pr77754-4.c: Likewise. + * gcc.c-torture/compile/pr89663-2.c: Likewise. + * gcc.c-torture/compile/pta-1.c: Likewise. + * gcc.c-torture/compile/stack-check-1.c: Likewise. + * gcc.dg/Walloc-size-larger-than-18.c: Likewise. + +2019-09-09 Jose E. Marchesi + * gcc.c-torture/compile/20000609-1.c: Annotate with dg-require-stack-size. * gcc.c-torture/compile/20000804-1.c: Likewise. diff --git a/gcc/testsuite/gcc.c-torture/compile/20010102-1.c b/gcc/testsuite/gcc.c-torture/compile/20010102-1.c index a409b56..3d9cc9e 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20010102-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20010102-1.c @@ -4,6 +4,8 @@ Copyright (C) 2001 Free Software Foundation. */ +/* { dg-require-effective-target indirect_calls } */ + # define PTR_INT_TYPE __PTRDIFF_TYPE__ struct _obstack_chunk diff --git a/gcc/testsuite/gcc.c-torture/compile/20010107-1.c b/gcc/testsuite/gcc.c-torture/compile/20010107-1.c index 222def4..22461a0 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20010107-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20010107-1.c @@ -1,3 +1,5 @@ +/* { dg-require-effective-target indirect_calls } */ + unsigned long x[4]; void foo(void) diff --git a/gcc/testsuite/gcc.c-torture/compile/20011109-1.c b/gcc/testsuite/gcc.c-torture/compile/20011109-1.c index f1987a74..1deba2a 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20011109-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20011109-1.c @@ -1,3 +1,5 @@ +/* { dg-require-effective-target indirect_calls } */ + typedef struct { short x[4]; } S; typedef struct { unsigned int a, b, c; S *d; } T; diff --git a/gcc/testsuite/gcc.c-torture/compile/20011218-1.c b/gcc/testsuite/gcc.c-torture/compile/20011218-1.c index bf63489..8db5b77 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20011218-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20011218-1.c @@ -2,6 +2,8 @@ for the indirect call was exposed too early and reload couldn't allocate it for multiplication and division. */ +/* { dg-require-effective-target indirect_calls } */ + struct S { int a, b; void (*f) (long, int); diff --git a/gcc/testsuite/gcc.c-torture/compile/20011229-1.c b/gcc/testsuite/gcc.c-torture/compile/20011229-1.c index 97b2655..99aeab7 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20011229-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20011229-1.c @@ -1,5 +1,8 @@ /* ICE: call insn does not satisfy its constraints, MMIX port. Origin: ghostscript-6.52, reduction from hp@bitrange.com. */ + +/* { dg-require-effective-target indirect_calls } */ + struct s0 { void (*init_color)(void *, void *); diff --git a/gcc/testsuite/gcc.c-torture/compile/20020129-1.c b/gcc/testsuite/gcc.c-torture/compile/20020129-1.c index 7b17ba4..c14ac07 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20020129-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20020129-1.c @@ -1,5 +1,7 @@ /* Test call to static variable. */ +/* { dg-require-effective-target indirect_calls } */ + typedef struct { long long a[10]; diff --git a/gcc/testsuite/gcc.c-torture/compile/20020320-1.c b/gcc/testsuite/gcc.c-torture/compile/20020320-1.c index 385c061..5b7a17a 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20020320-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20020320-1.c @@ -2,6 +2,8 @@ This testcase caused infinite loop in flow (several places), because flow assumes gen_jump generates simple_jump_p. */ +/* { dg-require-effective-target indirect_calls } */ + typedef void (*T) (void); extern T x[]; diff --git a/gcc/testsuite/gcc.c-torture/compile/20020706-1.c b/gcc/testsuite/gcc.c-torture/compile/20020706-1.c index c8811bc..9bbfc8a 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20020706-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20020706-1.c @@ -1,6 +1,8 @@ // Contributed by Alexandre Oliva // From Red Hat case 106165. +/* { dg-require-effective-target indirect_calls } */ + typedef struct s1 { unsigned short v1; diff --git a/gcc/testsuite/gcc.c-torture/compile/20020706-2.c b/gcc/testsuite/gcc.c-torture/compile/20020706-2.c index b84dda6..2391f20 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20020706-2.c +++ b/gcc/testsuite/gcc.c-torture/compile/20020706-2.c @@ -1,6 +1,8 @@ // Contributed by Alexandre Oliva // From Red Hat case 106165. +/* { dg-require-effective-target indirect_calls } */ + typedef unsigned short (FUNC_P) (void *, unsigned char *, unsigned short); void crashIt(int id, FUNC_P *func, unsigned char *funcparm) diff --git a/gcc/testsuite/gcc.c-torture/compile/20021205-1.c b/gcc/testsuite/gcc.c-torture/compile/20021205-1.c index 73648e9..27f4587 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20021205-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20021205-1.c @@ -1,3 +1,5 @@ +/* { dg-require-effective-target indirect_calls } */ + typedef struct x x; extern void *baz(char *); struct x { char * (*bar) (int); }; diff --git a/gcc/testsuite/gcc.c-torture/compile/20030921-1.c b/gcc/testsuite/gcc.c-torture/compile/20030921-1.c index 8199dc6..4bb3f46 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20030921-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20030921-1.c @@ -2,6 +2,7 @@ f is not being emitted. TREE_SYMBOL_REFERENCED was being set instead of calling mark_referenced. */ +/* { dg-require-effective-target indirect_calls } */ static void f(void); void g(void (*x) (void)){x();} diff --git a/gcc/testsuite/gcc.c-torture/compile/20031023-1.c b/gcc/testsuite/gcc.c-torture/compile/20031023-1.c index be83776..1ee1ff7 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20031023-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20031023-1.c @@ -1,5 +1,7 @@ /* Declaration of the frame size doesn't work on ptx. */ /* { dg-require-effective-target untyped_assembly } */ +/* { dg-require-effective-target indirect_calls } */ + #ifndef ASIZE # define ASIZE 0x10000000000UL #endif diff --git a/gcc/testsuite/gcc.c-torture/compile/20031023-2.c b/gcc/testsuite/gcc.c-torture/compile/20031023-2.c index 66d6645..5096516 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20031023-2.c +++ b/gcc/testsuite/gcc.c-torture/compile/20031023-2.c @@ -1,4 +1,6 @@ /* Declaration of the frame size doesn't work on ptx. */ /* { dg-require-effective-target untyped_assembly } */ +/* { dg-require-effective-target indirect_calls } */ + #define ASIZE 0x1000000000UL #include "20031023-1.c" diff --git a/gcc/testsuite/gcc.c-torture/compile/20031023-3.c b/gcc/testsuite/gcc.c-torture/compile/20031023-3.c index 5859634..1bb692f 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20031023-3.c +++ b/gcc/testsuite/gcc.c-torture/compile/20031023-3.c @@ -1,4 +1,6 @@ /* Declaration of the frame size doesn't work on ptx. */ /* { dg-require-effective-target untyped_assembly } */ +/* { dg-require-effective-target indirect_calls } */ + #define ASIZE 0x100000000UL #include "20031023-1.c" diff --git a/gcc/testsuite/gcc.c-torture/compile/20031023-4.c b/gcc/testsuite/gcc.c-torture/compile/20031023-4.c index 5c61f37..85c4dca 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20031023-4.c +++ b/gcc/testsuite/gcc.c-torture/compile/20031023-4.c @@ -1,2 +1,4 @@ +/* { dg-require-effective-target indirect_calls } */ + #define ASIZE 0x80000000UL #include "20031023-1.c" diff --git a/gcc/testsuite/gcc.c-torture/compile/20040614-1.c b/gcc/testsuite/gcc.c-torture/compile/20040614-1.c index b692ab5..c889bb2 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20040614-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20040614-1.c @@ -1,4 +1,5 @@ /* { dg-require-effective-target label_values } */ +/* { dg-require-effective-target indirect_calls } */ void f(int r1, int *fp) { diff --git a/gcc/testsuite/gcc.c-torture/compile/20040909-1.c b/gcc/testsuite/gcc.c-torture/compile/20040909-1.c index 8bbf901..0f66cb2 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20040909-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20040909-1.c @@ -1,3 +1,5 @@ +/* { dg-require-effective-target indirect_calls } */ + static __inline__ int one_utf8_to_utf16 () { } diff --git a/gcc/testsuite/gcc.c-torture/compile/20050122-1.c b/gcc/testsuite/gcc.c-torture/compile/20050122-1.c index a70907d..7bb7cee 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20050122-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20050122-1.c @@ -1,4 +1,6 @@ /* From PR 19484. */ +/* { dg-require-effective-target indirect_calls } */ + extern void foo (void) __attribute__((noreturn)); int n; diff --git a/gcc/testsuite/gcc.c-torture/compile/20050202-1.c b/gcc/testsuite/gcc.c-torture/compile/20050202-1.c index b3f8176..58ed54e 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20050202-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20050202-1.c @@ -1,4 +1,6 @@ /* From PR 19578. */ +/* { dg-require-effective-target indirect_calls } */ + extern void foo (void) __attribute__((noreturn)); void diff --git a/gcc/testsuite/gcc.c-torture/compile/20060208-1.c b/gcc/testsuite/gcc.c-torture/compile/20060208-1.c index 3881474..5025463 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20060208-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20060208-1.c @@ -1,5 +1,7 @@ /* PR middle-end/26092 */ +/* { dg-require-effective-target indirect_calls } */ /* { dg-skip-if "can't take address of malloc" { nvptx-*-* } } */ + typedef __SIZE_TYPE__ size_t; extern void *malloc (size_t); diff --git a/gcc/testsuite/gcc.c-torture/compile/20081108-1.c b/gcc/testsuite/gcc.c-torture/compile/20081108-1.c index 3209a90..a1f54e8 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20081108-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20081108-1.c @@ -1,3 +1,5 @@ +/* { dg-require-effective-target indirect_calls } */ + /* Test function call with function designator involving VLA side-effects does not lead to an ICE. */ diff --git a/gcc/testsuite/gcc.c-torture/compile/20150327.c b/gcc/testsuite/gcc.c-torture/compile/20150327.c index 373ea61..125b722 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20150327.c +++ b/gcc/testsuite/gcc.c-torture/compile/20150327.c @@ -1,3 +1,5 @@ +/* { dg-require-effective-target indirect_calls } */ + int a; int (*b)(), (*c)(); int fn1(int p1) { diff --git a/gcc/testsuite/gcc.c-torture/compile/920428-2.c b/gcc/testsuite/gcc.c-torture/compile/920428-2.c index f313b32..817fff0 100644 --- a/gcc/testsuite/gcc.c-torture/compile/920428-2.c +++ b/gcc/testsuite/gcc.c-torture/compile/920428-2.c @@ -1,3 +1,5 @@ +/* { dg-require-effective-target indirect_calls } */ + double sin(double x); double cos(double x); double tan(double x); diff --git a/gcc/testsuite/gcc.c-torture/compile/920928-5.c b/gcc/testsuite/gcc.c-torture/compile/920928-5.c index 8c975f0..b9f9dcb 100644 --- a/gcc/testsuite/gcc.c-torture/compile/920928-5.c +++ b/gcc/testsuite/gcc.c-torture/compile/920928-5.c @@ -1,4 +1,7 @@ /* REPRODUCED:CC1:SIGNAL MACHINE:m68k OPTIONS:-fpcc-struct-return */ + +/* { dg-require-effective-target indirect_calls } */ + struct b{}; f(struct b(*f)()) { diff --git a/gcc/testsuite/gcc.c-torture/compile/930117-1.c b/gcc/testsuite/gcc.c-torture/compile/930117-1.c index 83317cd..06466f5 100644 --- a/gcc/testsuite/gcc.c-torture/compile/930117-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/930117-1.c @@ -1,3 +1,5 @@ +/* { dg-require-effective-target indirect_calls } */ + f(x) { (*(void (*)())&x)(); diff --git a/gcc/testsuite/gcc.c-torture/compile/930607-1.c b/gcc/testsuite/gcc.c-torture/compile/930607-1.c index 97c94b2..360bbbc 100644 --- a/gcc/testsuite/gcc.c-torture/compile/930607-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/930607-1.c @@ -1,3 +1,5 @@ +/* { dg-require-effective-target indirect_calls } */ + typedef void f (); typedef f *pf; long long i; diff --git a/gcc/testsuite/gcc.c-torture/compile/991213-2.c b/gcc/testsuite/gcc.c-torture/compile/991213-2.c index 98385d5..dfbedf7d 100644 --- a/gcc/testsuite/gcc.c-torture/compile/991213-2.c +++ b/gcc/testsuite/gcc.c-torture/compile/991213-2.c @@ -1,3 +1,5 @@ +/* { dg-require-effective-target indirect_calls } */ + typedef long __kernel_time_t; typedef __kernel_time_t time_t; time2( diff --git a/gcc/testsuite/gcc.c-torture/compile/callind.c b/gcc/testsuite/gcc.c-torture/compile/callind.c index 5938d1b..893f4e7 100644 --- a/gcc/testsuite/gcc.c-torture/compile/callind.c +++ b/gcc/testsuite/gcc.c-torture/compile/callind.c @@ -1,3 +1,5 @@ +/* { dg-require-effective-target indirect_calls } */ + bar (foo, a) int (**foo) (); { diff --git a/gcc/testsuite/gcc.c-torture/compile/calls-void.c b/gcc/testsuite/gcc.c-torture/compile/calls-void.c index eeed4fd..7e6f56c 100644 --- a/gcc/testsuite/gcc.c-torture/compile/calls-void.c +++ b/gcc/testsuite/gcc.c-torture/compile/calls-void.c @@ -1,5 +1,6 @@ /* { dg-require-effective-target ptr32plus } */ /* { dg-require-effective-target untyped_assembly } */ +/* { dg-require-effective-target indirect_calls } */ typedef void (*T)(void); f1 () diff --git a/gcc/testsuite/gcc.c-torture/compile/calls.c b/gcc/testsuite/gcc.c-torture/compile/calls.c index ca07122a..48a3b7c 100644 --- a/gcc/testsuite/gcc.c-torture/compile/calls.c +++ b/gcc/testsuite/gcc.c-torture/compile/calls.c @@ -1,5 +1,6 @@ /* { dg-require-effective-target ptr32plus } */ /* { dg-require-effective-target untyped_assembly } */ +/* { dg-require-effective-target indirect_calls } */ typedef void *(*T)(void); f1 () diff --git a/gcc/testsuite/gcc.c-torture/compile/pr21840.c b/gcc/testsuite/gcc.c-torture/compile/pr21840.c index bec3d6b..f6f2a5d 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr21840.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr21840.c @@ -1,3 +1,5 @@ +/* { dg-require-effective-target indirect_calls } */ + void fn_show_state(void); typedef void (*fn_handler_fn)(void); static fn_handler_fn fn_handler[1]; diff --git a/gcc/testsuite/gcc.c-torture/compile/pr32139.c b/gcc/testsuite/gcc.c-torture/compile/pr32139.c index 7b8522f..3cc541c 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr32139.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr32139.c @@ -1,4 +1,6 @@ /* PR tree-optimization/32139 */ +/* { dg-require-effective-target indirect_calls } */ + int foo (void); int bar (void) __attribute__ ((const)); diff --git a/gcc/testsuite/gcc.c-torture/compile/pr35607.c b/gcc/testsuite/gcc.c-torture/compile/pr35607.c index 7f5aa7a..9debd46 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr35607.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr35607.c @@ -1,3 +1,5 @@ +/* { dg-require-effective-target indirect_calls } */ + extern void (*__fini_array_start []) (void); extern void (*__fini_array_end []) (void); void diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37433-1.c b/gcc/testsuite/gcc.c-torture/compile/pr37433-1.c index 322c167..48a57b6 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr37433-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr37433-1.c @@ -1,3 +1,5 @@ +/* { dg-require-effective-target indirect_calls } */ + void regex_subst(void) { const void *subst = ""; diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37433.c b/gcc/testsuite/gcc.c-torture/compile/pr37433.c index 0ba1179..95d168a 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr37433.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr37433.c @@ -1,3 +1,5 @@ +/* { dg-require-effective-target indirect_calls } */ + int regex_subst(void) { const void *subst = ""; diff --git a/gcc/testsuite/gcc.c-torture/compile/pr39941.c b/gcc/testsuite/gcc.c-torture/compile/pr39941.c index b620908..5cb3b05 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr39941.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr39941.c @@ -1,3 +1,5 @@ +/* { dg-require-effective-target indirect_calls } */ + typedef void (*entry_func) (void) __attribute__ ((noreturn)); extern entry_func entry_addr; static void bsd_boot_entry (void) diff --git a/gcc/testsuite/gcc.c-torture/compile/pr40080.c b/gcc/testsuite/gcc.c-torture/compile/pr40080.c index e36f142..37c5a91 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr40080.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr40080.c @@ -1,3 +1,5 @@ +/* { dg-require-effective-target indirect_calls } */ + extern void *ff(void*,int); struct lpgl { struct lpgl *next; }; diff --git a/gcc/testsuite/gcc.c-torture/compile/pr43635.c b/gcc/testsuite/gcc.c-torture/compile/pr43635.c index df826b6..3875f4e 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr43635.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr43635.c @@ -1,4 +1,6 @@ /* { dg-require-effective-target untyped_assembly } */ +/* { dg-require-effective-target indirect_calls } */ + extern void d (void); void (*foo (void)) (float) diff --git a/gcc/testsuite/gcc.c-torture/compile/pr43791.c b/gcc/testsuite/gcc.c-torture/compile/pr43791.c index 2b1d06f..710bf7e 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr43791.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr43791.c @@ -1,3 +1,5 @@ +/* { dg-require-effective-target indirect_calls } */ + int owner(); int clear(); diff --git a/gcc/testsuite/gcc.c-torture/compile/pr43845.c b/gcc/testsuite/gcc.c-torture/compile/pr43845.c index bdb45e7..83442de 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr43845.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr43845.c @@ -1,3 +1,5 @@ +/* { dg-require-effective-target indirect_calls } */ + typedef int __attribute__ ((const)) (*x264_pixel_cmp_t)(void); typedef struct { diff --git a/gcc/testsuite/gcc.c-torture/compile/pr44043.c b/gcc/testsuite/gcc.c-torture/compile/pr44043.c index 943501b..bd51089 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr44043.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr44043.c @@ -1,3 +1,5 @@ +/* { dg-require-effective-target indirect_calls } */ + typedef unsigned char __u8; typedef unsigned short __u16; typedef unsigned int __u32; diff --git a/gcc/testsuite/gcc.c-torture/compile/pr51694.c b/gcc/testsuite/gcc.c-torture/compile/pr51694.c index f5c1a40..c06bc21 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr51694.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr51694.c @@ -1,4 +1,6 @@ /* { dg-require-effective-target untyped_assembly } */ +/* { dg-require-effective-target indirect_calls } */ + void foo (x, fn) void (*fn) (); diff --git a/gcc/testsuite/gcc.c-torture/compile/pr77754-2.c b/gcc/testsuite/gcc.c-torture/compile/pr77754-2.c index d088961..d649d71 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr77754-2.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr77754-2.c @@ -1,4 +1,5 @@ // { dg-require-effective-target alloca } +// { dg-require-effective-target indirect_calls } /* PR c/77754 */ int fn3(); diff --git a/gcc/testsuite/gcc.c-torture/compile/pr77754-3.c b/gcc/testsuite/gcc.c-torture/compile/pr77754-3.c index fb25e23..51d7ca7 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr77754-3.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr77754-3.c @@ -1,4 +1,5 @@ // { dg-require-effective-target alloca } +// { dg-require-effective-target indirect_calls } /* PR c/77754 */ int fn3(); diff --git a/gcc/testsuite/gcc.c-torture/compile/pr77754-4.c b/gcc/testsuite/gcc.c-torture/compile/pr77754-4.c index 1c5c461..53216bb 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr77754-4.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr77754-4.c @@ -1,4 +1,5 @@ // { dg-require-effective-target alloca } +// { dg-require-effective-target indirect_calls } /* PR c/77754 */ int fn3(); diff --git a/gcc/testsuite/gcc.c-torture/compile/pr89663-2.c b/gcc/testsuite/gcc.c-torture/compile/pr89663-2.c index 052fe69..efac682 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr89663-2.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr89663-2.c @@ -1,4 +1,5 @@ /* PR middle-end/89663 */ +/* { dg-require-effective-target indirect_calls } */ int irint (double); long lrint (double); diff --git a/gcc/testsuite/gcc.c-torture/compile/pta-1.c b/gcc/testsuite/gcc.c-torture/compile/pta-1.c index 515e5ff..07dad8a 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pta-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/pta-1.c @@ -1,3 +1,5 @@ +/* { dg-require-effective-target indirect_calls } */ + typedef struct JSObject JSObject; typedef struct JSObjectMap *(*JSNewObjectMapOp) (JSObject *obj); typedef JSObject *(*JSGetMethodOp) (JSObject *obj); diff --git a/gcc/testsuite/gcc.c-torture/compile/stack-check-1.c b/gcc/testsuite/gcc.c-torture/compile/stack-check-1.c index 2a03f7c..c06f5a1 100644 --- a/gcc/testsuite/gcc.c-torture/compile/stack-check-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/stack-check-1.c @@ -1,3 +1,4 @@ +/* { dg-require-effective-target indirect_calls } */ /* { dg-require-effective-target untyped_assembly } */ /* { dg-require-stack-check "" } */ /* { dg-additional-options "-fstack-check" } */ diff --git a/gcc/testsuite/gcc.dg/Walloc-size-larger-than-18.c b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-18.c index b4aa167..7888cb1 100644 --- a/gcc/testsuite/gcc.dg/Walloc-size-larger-than-18.c +++ b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-18.c @@ -4,6 +4,7 @@ with zero or excessive size trigger either -Walloc-zero or -Walloc-size-larger-than warnings. { dg-do compile } + { dg-require-effective-target indirect_calls } { dg-options "-O2 -Wall -Walloc-zero -ftrack-macro-expansion=0" } */ #define ATTR(...) __attribute__ ((__VA_ARGS__)) diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index e32d424..4d03cc0 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -9502,3 +9502,11 @@ proc check_effective_target_mfentry { } { void foo (void) { } } "-mfentry"] } + +# Return 1 if this target supports indirect calls +proc check_effective_target_indirect_calls { } { + if { [istarget bpf-*-*] } { + return 0 + } + return 1 +} -- cgit v1.1 From 91dfef9610b8844c62dc7186a9aea9a6aca9805c Mon Sep 17 00:00:00 2001 From: "Jose E. Marchesi" Date: Mon, 9 Sep 2019 12:13:23 +0200 Subject: GCC port for eBPF This patch series introduces a port of GCC to eBPF, which is a virtual machine that resides in the Linux kernel. Initially intended for user-level packet capture and filtering, eBPF is nowadays generalized to serve as a general-purpose infrastructure also for non-networking purposes. The binutils support is already upstream. See https://sourceware.org/ml/binutils/2019-05/msg00306.html. ChangeLog: * MAINTAINERS: Add myself as the maintainer of the eBPF port. Remove myself from Write After Approval section. * configure.ac: Support for bpf-*-* targets. * configure: Regenerate. contrib/ChangeLog: * config-list.mk (LIST): Disable go in bpf-*-* targets. gcc/ChangeLog: * doc/invoke.texi (Option Summary): Cover eBPF. (eBPF Options): New section. * doc/extend.texi (BPF Built-in Functions): Likewise. (BPF Kernel Helpers): Likewise. * config.gcc: Support for bpf-*-* targets. * common/config/bpf/bpf-common.c: New file. * config/bpf/t-bpf: Likewise. * config/bpf/predicates.md: Likewise. * config/bpf/constraints.md: Likewise. * config/bpf/bpf.opt: Likewise. * config/bpf/bpf.md: Likewise. * config/bpf/bpf.h: Likewise. * config/bpf/bpf.c: Likewise. * config/bpf/bpf-protos.h: Likewise. * config/bpf/bpf-opts.h: Likewise. * config/bpf/bpf-helpers.h: Likewise. * config/bpf/bpf-helpers.def: Likewise. gcc/testsuite/ChangeLog: * gcc.dg/builtins-config.h: eBPF doesn't support C99 standard functions. * gcc.c-torture/compile/20101217-1.c: Add a function prototype for printf. * gcc.c-torture/compile/20000211-1.c: Skip if target bpf-*-*. * gcc.c-torture/compile/poor.c: Likewise. * gcc.c-torture/compile/pr25311.c: Likewise. * gcc.c-torture/compile/pr39928-1.c: Likewise. * gcc.c-torture/compile/pr70061.c: Likewise. * gcc.c-torture/compile/920501-7.c: Likewise. * gcc.c-torture/compile/20000403-1.c: Likewise. * gcc.c-torture/compile/20001226-1.c: Likewise. * gcc.c-torture/compile/20030903-1.c: Likewise. * gcc.c-torture/compile/20031125-1.c: Likewise. * gcc.c-torture/compile/20040101-1.c: Likewise. * gcc.c-torture/compile/20040317-2.c: Likewise. * gcc.c-torture/compile/20040726-1.c: Likewise. * gcc.c-torture/compile/20051216-1.c: Likewise. * gcc.c-torture/compile/900313-1.c: Likewise. * gcc.c-torture/compile/920625-1.c: Likewise. * gcc.c-torture/compile/930421-1.c: Likewise. * gcc.c-torture/compile/930623-1.c: Likewise. * gcc.c-torture/compile/961004-1.c: Likewise. * gcc.c-torture/compile/980504-1.c: Likewise. * gcc.c-torture/compile/980816-1.c: Likewise. * gcc.c-torture/compile/990625-1.c: Likewise. * gcc.c-torture/compile/DFcmp.c: Likewise. * gcc.c-torture/compile/HIcmp.c: Likewise. * gcc.c-torture/compile/HIset.c: Likewise. * gcc.c-torture/compile/QIcmp.c: Likewise. * gcc.c-torture/compile/QIset.c: Likewise. * gcc.c-torture/compile/SFset.c: Likewise. * gcc.c-torture/compile/SIcmp.c: Likewise. * gcc.c-torture/compile/SIset.c: Likewise. * gcc.c-torture/compile/UHIcmp.c: Likewise. * gcc.c-torture/compile/UQIcmp.c: Likewise. * gcc.c-torture/compile/USIcmp.c: Likewise. * gcc.c-torture/compile/consec.c: Likewise. * gcc.c-torture/compile/limits-fndefn.c: Likewise. * gcc.c-torture/compile/lll.c: Likewise. * gcc.c-torture/compile/parms.c: Likewise. * gcc.c-torture/compile/pass.c: Likewise. * gcc.c-torture/compile/pp.c: Likewise. * gcc.c-torture/compile/pr32399.c: Likewise. * gcc.c-torture/compile/pr34091.c: Likewise. * gcc.c-torture/compile/pr34688.c: Likewise. * gcc.c-torture/compile/pr37258.c: Likewise. * gcc.c-torture/compile/pr37327.c: Likewise. * gcc.c-torture/compile/pr37381.c: Likewise. * gcc.c-torture/compile/pr37669-2.c: Likewise. * gcc.c-torture/compile/pr37669.c: Likewise. * gcc.c-torture/compile/pr37742-3.c: Likewise. * gcc.c-torture/compile/pr44063.c: Likewise. * gcc.c-torture/compile/pr48596.c: Likewise. * gcc.c-torture/compile/pr51856.c: Likewise. * gcc.c-torture/compile/pr54428.c: Likewise. * gcc.c-torture/compile/pr54713-1.c: Likewise. * gcc.c-torture/compile/pr54713-2.c: Likewise. * gcc.c-torture/compile/pr54713-3.c: Likewise. * gcc.c-torture/compile/pr55921.c: Likewise. * gcc.c-torture/compile/pr70240.c: Likewise. * gcc.c-torture/compile/pr70355.c: Likewise. * gcc.c-torture/compile/pr82052.c: Likewise. * gcc.c-torture/compile/pr83487.c: Likewise. * gcc.c-torture/compile/pr86122.c: Likewise. * gcc.c-torture/compile/pret-arg.c: Likewise. * gcc.c-torture/compile/regs-arg-size.c: Likewise. * gcc.c-torture/compile/structret.c: Likewise. * gcc.c-torture/compile/uuarg.c: Likewise. * gcc.dg/20001009-1.c: Likewise. * gcc.dg/20020418-1.c: Likewise. * gcc.dg/20020426-2.c: Likewise. * gcc.dg/20020430-1.c: Likewise. * gcc.dg/20040306-1.c: Likewise. * gcc.dg/20040622-2.c: Likewise. * gcc.dg/20050603-2.c: Likewise. * gcc.dg/20050629-1.c: Likewise. * gcc.dg/20061026.c: Likewise. * gcc.dg/Warray-bounds-3.c: Likewise. * gcc.dg/Warray-bounds-30.c: Likewise. * gcc.dg/Wframe-larger-than-2.c: Likewise. * gcc.dg/Wframe-larger-than.c: Likewise. * gcc.dg/Wrestrict-11.c: Likewise. * gcc.c-torture/compile/20000804-1.c: Likewise. * lib/target-supports.exp (check_effective_target_trampolines): Adapt to eBPF. (check_effective_target_indirect_jumps): Likewise. (check_effective_target_nonlocal_goto): Likewise. (check_effective_target_global_constructor): Likewise. (check_effective_target_return_address): Likewise. * gcc.target/bpf/bpf.exp: New file. * gcc.target/bpf/builtin-load.c: Likewise. * cc.target/bpf/constant-calls.c: Likewise. * gcc.target/bpf/diag-funargs.c: Likewise. * gcc.target/bpf/diag-funargs-2.c: Likewise. * gcc.target/bpf/diag-funargs-3.c: Likewise. * gcc.target/bpf/diag-indcalls.c: Likewise. * gcc.target/bpf/helper-bind.c: Likewise. * gcc.target/bpf/helper-bpf-redirect.c: Likewise. * gcc.target/bpf/helper-clone-redirect.c: Likewise. * gcc.target/bpf/helper-csum-diff.c: Likewise. * gcc.target/bpf/helper-csum-update.c: Likewise. * gcc.target/bpf/helper-current-task-under-cgroup.c: Likewise. * gcc.target/bpf/helper-fib-lookup.c: Likewise. * gcc.target/bpf/helper-get-cgroup-classid.c: Likewise. * gcc.target/bpf/helper-get-current-cgroup-id.c: Likewise. * gcc.target/bpf/helper-get-current-comm.c: Likewise. * gcc.target/bpf/helper-get-current-pid-tgid.c: Likewise. * gcc.target/bpf/helper-get-current-task.c: Likewise. * gcc.target/bpf/helper-get-current-uid-gid.c: Likewise. * gcc.target/bpf/helper-get-hash-recalc.c: Likewise. * gcc.target/bpf/helper-get-listener-sock.c: Likewise. * gcc.target/bpf/helper-get-local-storage.c: Likewise. * gcc.target/bpf/helper-get-numa-node-id.c: Likewise. * gcc.target/bpf/helper-get-prandom-u32.c: Likewise. * gcc.target/bpf/helper-get-route-realm.c: Likewise. * gcc.target/bpf/helper-get-smp-processor-id.c: Likewise. * gcc.target/bpf/helper-get-socket-cookie.c: Likewise. * gcc.target/bpf/helper-get-socket-uid.c: Likewise. * gcc.target/bpf/helper-getsockopt.c: Likewise. * gcc.target/bpf/helper-get-stack.c: Likewise. * gcc.target/bpf/helper-get-stackid.c: Likewise. * gcc.target/bpf/helper-ktime-get-ns.c: Likewise. * gcc.target/bpf/helper-l3-csum-replace.c: Likewise. * gcc.target/bpf/helper-l4-csum-replace.c: Likewise. * gcc.target/bpf/helper-lwt-push-encap.c: Likewise. * gcc.target/bpf/helper-lwt-seg6-action.c: Likewise. * gcc.target/bpf/helper-lwt-seg6-adjust-srh.c: Likewise. * gcc.target/bpf/helper-lwt-seg6-store-bytes.c: Likewise. * gcc.target/bpf/helper-map-delete-elem.c: Likewise. * gcc.target/bpf/helper-map-lookup-elem.c: Likewise. * gcc.target/bpf/helper-map-peek-elem.c: Likewise. * gcc.target/bpf/helper-map-pop-elem.c: Likewise. * gcc.target/bpf/helper-map-push-elem.c: Likewise. * gcc.target/bpf/helper-map-update-elem.c: Likewise. * gcc.target/bpf/helper-msg-apply-bytes.c: Likewise. * gcc.target/bpf/helper-msg-cork-bytes.c: Likewise. * gcc.target/bpf/helper-msg-pop-data.c: Likewise. * gcc.target/bpf/helper-msg-pull-data.c: Likewise. * gcc.target/bpf/helper-msg-push-data.c: Likewise. * gcc.target/bpf/helper-msg-redirect-hash.c: Likewise. * gcc.target/bpf/helper-msg-redirect-map.c: Likewise. * gcc.target/bpf/helper-override-return.c: Likewise. * gcc.target/bpf/helper-perf-event-output.c: Likewise. * gcc.target/bpf/helper-perf-event-read.c: Likewise. * gcc.target/bpf/helper-perf-event-read-value.c: Likewise. * gcc.target/bpf/helper-perf-prog-read-value.c: Likewise. * gcc.target/bpf/helper-probe-read.c: Likewise. * gcc.target/bpf/helper-probe-read-str.c: Likewise. * gcc.target/bpf/helper-probe-write-user.c: Likewise. * gcc.target/bpf/helper-rc-keydown.c: Likewise. * gcc.target/bpf/helper-rc-pointer-rel.c: Likewise. * gcc.target/bpf/helper-rc-repeat.c: Likewise. * gcc.target/bpf/helper-redirect-map.c: Likewise. * gcc.target/bpf/helper-set-hash.c: Likewise. * gcc.target/bpf/helper-set-hash-invalid.c: Likewise. * gcc.target/bpf/helper-setsockopt.c: Likewise. * gcc.target/bpf/helper-skb-adjust-room.c: Likewise. * gcc.target/bpf/helper-skb-cgroup-id.c: Likewise. * gcc.target/bpf/helper-skb-change-head.c: Likewise. * gcc.target/bpf/helper-skb-change-proto.c: Likewise. * gcc.target/bpf/helper-skb-change-tail.c: Likewise. * gcc.target/bpf/helper-skb-change-type.c: Likewise. * gcc.target/bpf/helper-skb-ecn-set-ce.c: Likewise. * gcc.target/bpf/helper-skb-get-tunnel-key.c: Likewise. * gcc.target/bpf/helper-skb-get-tunnel-opt.c: Likewise. * gcc.target/bpf/helper-skb-get-xfrm-state.c: Likewise. * gcc.target/bpf/helper-skb-load-bytes.c: Likewise. * gcc.target/bpf/helper-skb-load-bytes-relative.c: Likewise. * gcc.target/bpf/helper-skb-pull-data.c: Likewise. * gcc.target/bpf/helper-skb-set-tunnel-key.c: Likewise. * gcc.target/bpf/helper-skb-set-tunnel-opt.c: Likewise. * gcc.target/bpf/helper-skb-store-bytes.c: Likewise. * gcc.target/bpf/helper-skb-under-cgroup.c: Likewise. * gcc.target/bpf/helper-skb-vlan-pop.c: Likewise. * gcc.target/bpf/helper-skb-vlan-push.c: Likewise. * gcc.target/bpf/helper-skc-lookup-tcp.c: Likewise. * gcc.target/bpf/helper-sk-fullsock.c: Likewise. * gcc.target/bpf/helper-sk-lookup-tcp.c: Likewise. * gcc.target/bpf/helper-sk-lookup-upd.c: Likewise. * gcc.target/bpf/helper-sk-redirect-hash.c: Likewise. * gcc.target/bpf/helper-sk-redirect-map.c: Likewise. * gcc.target/bpf/helper-sk-release.c: Likewise. * gcc.target/bpf/helper-sk-select-reuseport.c: Likewise. * gcc.target/bpf/helper-sk-storage-delete.c: Likewise. * gcc.target/bpf/helper-sk-storage-get.c: Likewise. * gcc.target/bpf/helper-sock-hash-update.c: Likewise. * gcc.target/bpf/helper-sock-map-update.c: Likewise. * gcc.target/bpf/helper-sock-ops-cb-flags-set.c: Likewise. * gcc.target/bpf/helper-spin-lock.c: Likewise. * gcc.target/bpf/helper-spin-unlock.c: Likewise. * gcc.target/bpf/helper-strtol.c: Likewise. * gcc.target/bpf/helper-strtoul.c: Likewise. * gcc.target/bpf/helper-sysctl-get-current-value.c: Likewise. * gcc.target/bpf/helper-sysctl-get-name.c: Likewise. * gcc.target/bpf/helper-sysctl-get-new-value.c: Likewise. * gcc.target/bpf/helper-sysctl-set-new-value.c: Likewise. * gcc.target/bpf/helper-tail-call.c: Likewise. * gcc.target/bpf/helper-tcp-check-syncookie.c: Likewise. * gcc.target/bpf/helper-tcp-sock.c: Likewise. * gcc.target/bpf/helper-trace-printk.c: Likewise. * gcc.target/bpf/helper-xdp-adjust-head.c: Likewise. * gcc.target/bpf/helper-xdp-adjust-meta.c: Likewise. * gcc.target/bpf/helper-xdp-adjust-tail.c: Likewise. * gcc.target/bpf/skb-ancestor-cgroup-id.c: Likewise. * gcc.target/bpf/sync-fetch-and-add.c: Likewise. libgcc/ChangeLog: * config.host: Set cpu_type for bpf-*-* targets. * config/bpf/t-bpf: Likewise. * config/bpf/crtn.S: Likewise. * config/bpf/crti.S: New file. From-SVN: r275506 --- gcc/ChangeLog | 23 + gcc/common/config/bpf/bpf-common.c | 55 ++ gcc/config.gcc | 9 + gcc/config/bpf/bpf-helpers.def | 194 +++++ gcc/config/bpf/bpf-helpers.h | 327 +++++++ gcc/config/bpf/bpf-opts.h | 56 ++ gcc/config/bpf/bpf-protos.h | 33 + gcc/config/bpf/bpf.c | 948 +++++++++++++++++++++ gcc/config/bpf/bpf.h | 539 ++++++++++++ gcc/config/bpf/bpf.md | 497 +++++++++++ gcc/config/bpf/bpf.opt | 123 +++ gcc/config/bpf/constraints.md | 32 + gcc/config/bpf/predicates.md | 64 ++ gcc/config/bpf/t-bpf | 0 gcc/doc/extend.texi | 171 ++++ gcc/doc/invoke.texi | 37 + gcc/testsuite/ChangeLog | 215 +++++ gcc/testsuite/gcc.c-torture/compile/20000211-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/20000403-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/20000804-1.c | 1 + gcc/testsuite/gcc.c-torture/compile/20001226-1.c | 1 + gcc/testsuite/gcc.c-torture/compile/20030903-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/20031125-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/20040101-1.c | 1 + gcc/testsuite/gcc.c-torture/compile/20040317-2.c | 2 + gcc/testsuite/gcc.c-torture/compile/20040726-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/20051216-1.c | 1 + gcc/testsuite/gcc.c-torture/compile/20101217-1.c | 4 +- gcc/testsuite/gcc.c-torture/compile/900313-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/920501-7.c | 1 + gcc/testsuite/gcc.c-torture/compile/920625-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/930421-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/930623-1.c | 1 + gcc/testsuite/gcc.c-torture/compile/961004-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/980504-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/980816-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/990625-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/DFcmp.c | 2 + gcc/testsuite/gcc.c-torture/compile/HIcmp.c | 2 + gcc/testsuite/gcc.c-torture/compile/HIset.c | 2 + gcc/testsuite/gcc.c-torture/compile/QIcmp.c | 2 + gcc/testsuite/gcc.c-torture/compile/QIset.c | 2 + gcc/testsuite/gcc.c-torture/compile/SFset.c | 1 + gcc/testsuite/gcc.c-torture/compile/SIcmp.c | 2 + gcc/testsuite/gcc.c-torture/compile/SIset.c | 2 + gcc/testsuite/gcc.c-torture/compile/UHIcmp.c | 2 + gcc/testsuite/gcc.c-torture/compile/UQIcmp.c | 2 + gcc/testsuite/gcc.c-torture/compile/USIcmp.c | 2 + gcc/testsuite/gcc.c-torture/compile/consec.c | 2 + .../gcc.c-torture/compile/limits-fndefn.c | 1 + gcc/testsuite/gcc.c-torture/compile/lll.c | 1 + gcc/testsuite/gcc.c-torture/compile/parms.c | 1 + gcc/testsuite/gcc.c-torture/compile/pass.c | 2 + gcc/testsuite/gcc.c-torture/compile/poor.c | 2 + gcc/testsuite/gcc.c-torture/compile/pp.c | 2 + gcc/testsuite/gcc.c-torture/compile/pr25311.c | 1 + gcc/testsuite/gcc.c-torture/compile/pr32399.c | 2 + gcc/testsuite/gcc.c-torture/compile/pr34091.c | 2 + gcc/testsuite/gcc.c-torture/compile/pr34688.c | 2 + gcc/testsuite/gcc.c-torture/compile/pr37258.c | 2 + gcc/testsuite/gcc.c-torture/compile/pr37327.c | 2 + gcc/testsuite/gcc.c-torture/compile/pr37381.c | 2 + gcc/testsuite/gcc.c-torture/compile/pr37669-2.c | 1 + gcc/testsuite/gcc.c-torture/compile/pr37669.c | 1 + gcc/testsuite/gcc.c-torture/compile/pr37742-3.c | 2 + gcc/testsuite/gcc.c-torture/compile/pr39928-1.c | 2 + gcc/testsuite/gcc.c-torture/compile/pr44063.c | 2 + gcc/testsuite/gcc.c-torture/compile/pr48596.c | 2 + gcc/testsuite/gcc.c-torture/compile/pr51856.c | 2 + gcc/testsuite/gcc.c-torture/compile/pr54428.c | 1 + gcc/testsuite/gcc.c-torture/compile/pr54713-1.c | 1 + gcc/testsuite/gcc.c-torture/compile/pr54713-2.c | 1 + gcc/testsuite/gcc.c-torture/compile/pr54713-3.c | 1 + gcc/testsuite/gcc.c-torture/compile/pr55921.c | 1 + gcc/testsuite/gcc.c-torture/compile/pr70061.c | 2 + gcc/testsuite/gcc.c-torture/compile/pr70240.c | 2 + gcc/testsuite/gcc.c-torture/compile/pr70355.c | 2 + gcc/testsuite/gcc.c-torture/compile/pr82052.c | 2 + gcc/testsuite/gcc.c-torture/compile/pr83487.c | 1 + gcc/testsuite/gcc.c-torture/compile/pr86122.c | 1 + gcc/testsuite/gcc.c-torture/compile/pret-arg.c | 2 + .../gcc.c-torture/compile/regs-arg-size.c | 2 + gcc/testsuite/gcc.c-torture/compile/structret.c | 2 + gcc/testsuite/gcc.c-torture/compile/uuarg.c | 2 + gcc/testsuite/gcc.dg/20001009-1.c | 1 + gcc/testsuite/gcc.dg/20020418-1.c | 1 + gcc/testsuite/gcc.dg/20020426-2.c | 1 + gcc/testsuite/gcc.dg/20020430-1.c | 1 + gcc/testsuite/gcc.dg/20040306-1.c | 2 +- gcc/testsuite/gcc.dg/20040622-2.c | 1 + gcc/testsuite/gcc.dg/20050603-2.c | 1 + gcc/testsuite/gcc.dg/20050629-1.c | 1 + gcc/testsuite/gcc.dg/20061026.c | 1 + gcc/testsuite/gcc.dg/Warray-bounds-3.c | 1 + gcc/testsuite/gcc.dg/Warray-bounds-30.c | 3 +- gcc/testsuite/gcc.dg/Wframe-larger-than-2.c | 3 +- gcc/testsuite/gcc.dg/Wframe-larger-than.c | 1 + gcc/testsuite/gcc.dg/Wrestrict-11.c | 3 +- gcc/testsuite/gcc.dg/builtins-config.h | 4 +- gcc/testsuite/gcc.target/bpf/bpf.exp | 41 + gcc/testsuite/gcc.target/bpf/builtin-load.c | 20 + gcc/testsuite/gcc.target/bpf/constant-calls.c | 20 + gcc/testsuite/gcc.target/bpf/diag-funargs-2.c | 26 + gcc/testsuite/gcc.target/bpf/diag-funargs-3.c | 26 + gcc/testsuite/gcc.target/bpf/diag-funargs.c | 15 + gcc/testsuite/gcc.target/bpf/diag-indcalls.c | 11 + gcc/testsuite/gcc.target/bpf/helper-bind.c | 15 + gcc/testsuite/gcc.target/bpf/helper-bpf-redirect.c | 15 + .../gcc.target/bpf/helper-clone-redirect.c | 16 + gcc/testsuite/gcc.target/bpf/helper-csum-diff.c | 16 + gcc/testsuite/gcc.target/bpf/helper-csum-update.c | 15 + .../bpf/helper-current-task-under-cgroup.c | 15 + gcc/testsuite/gcc.target/bpf/helper-fib-lookup.c | 16 + .../gcc.target/bpf/helper-get-cgroup-classid.c | 14 + .../gcc.target/bpf/helper-get-current-cgroup-id.c | 13 + .../gcc.target/bpf/helper-get-current-comm.c | 15 + .../gcc.target/bpf/helper-get-current-pid-tgid.c | 13 + .../gcc.target/bpf/helper-get-current-task.c | 13 + .../gcc.target/bpf/helper-get-current-uid-gid.c | 13 + .../gcc.target/bpf/helper-get-hash-recalc.c | 14 + .../gcc.target/bpf/helper-get-listener-sock.c | 13 + .../gcc.target/bpf/helper-get-local-storage.c | 14 + .../gcc.target/bpf/helper-get-numa-node-id.c | 13 + .../gcc.target/bpf/helper-get-prandom-u32.c | 13 + .../gcc.target/bpf/helper-get-route-realm.c | 14 + .../gcc.target/bpf/helper-get-smp-processor-id.c | 13 + .../gcc.target/bpf/helper-get-socket-cookie.c | 14 + .../gcc.target/bpf/helper-get-socket-uid.c | 14 + gcc/testsuite/gcc.target/bpf/helper-get-stack.c | 16 + gcc/testsuite/gcc.target/bpf/helper-get-stackid.c | 15 + gcc/testsuite/gcc.target/bpf/helper-getsockopt.c | 17 + gcc/testsuite/gcc.target/bpf/helper-ktime-get-ns.c | 12 + .../gcc.target/bpf/helper-l3-csum-replace.c | 16 + .../gcc.target/bpf/helper-l4-csum-replace.c | 16 + .../gcc.target/bpf/helper-lwt-push-encap.c | 15 + .../gcc.target/bpf/helper-lwt-seg6-action.c | 16 + .../gcc.target/bpf/helper-lwt-seg6-adjust-srh.c | 16 + .../gcc.target/bpf/helper-lwt-seg6-store-bytes.c | 16 + .../gcc.target/bpf/helper-map-delete-elem.c | 14 + .../gcc.target/bpf/helper-map-lookup-elem.c | 12 + .../gcc.target/bpf/helper-map-peek-elem.c | 14 + gcc/testsuite/gcc.target/bpf/helper-map-pop-elem.c | 14 + .../gcc.target/bpf/helper-map-push-elem.c | 16 + .../gcc.target/bpf/helper-map-update-elem.c | 16 + .../gcc.target/bpf/helper-msg-apply-bytes.c | 15 + .../gcc.target/bpf/helper-msg-cork-bytes.c | 15 + gcc/testsuite/gcc.target/bpf/helper-msg-pop-data.c | 16 + .../gcc.target/bpf/helper-msg-pull-data.c | 16 + .../gcc.target/bpf/helper-msg-push-data.c | 16 + .../gcc.target/bpf/helper-msg-redirect-hash.c | 16 + .../gcc.target/bpf/helper-msg-redirect-map.c | 17 + .../gcc.target/bpf/helper-override-return.c | 15 + .../gcc.target/bpf/helper-perf-event-output.c | 17 + .../gcc.target/bpf/helper-perf-event-read-value.c | 16 + .../gcc.target/bpf/helper-perf-event-read.c | 15 + .../gcc.target/bpf/helper-perf-prog-read-value.c | 15 + .../gcc.target/bpf/helper-probe-read-str.c | 16 + gcc/testsuite/gcc.target/bpf/helper-probe-read.c | 15 + .../gcc.target/bpf/helper-probe-write-user.c | 15 + gcc/testsuite/gcc.target/bpf/helper-rc-keydown.c | 17 + .../gcc.target/bpf/helper-rc-pointer-rel.c | 15 + gcc/testsuite/gcc.target/bpf/helper-rc-repeat.c | 14 + gcc/testsuite/gcc.target/bpf/helper-redirect-map.c | 16 + .../gcc.target/bpf/helper-set-hash-invalid.c | 13 + gcc/testsuite/gcc.target/bpf/helper-set-hash.c | 15 + gcc/testsuite/gcc.target/bpf/helper-setsockopt.c | 19 + gcc/testsuite/gcc.target/bpf/helper-sk-fullsock.c | 13 + .../gcc.target/bpf/helper-sk-lookup-tcp.c | 19 + .../gcc.target/bpf/helper-sk-lookup-upd.c | 19 + .../gcc.target/bpf/helper-sk-redirect-hash.c | 16 + .../gcc.target/bpf/helper-sk-redirect-map.c | 16 + gcc/testsuite/gcc.target/bpf/helper-sk-release.c | 14 + .../gcc.target/bpf/helper-sk-select-reuseport.c | 16 + .../gcc.target/bpf/helper-sk-storage-delete.c | 14 + .../gcc.target/bpf/helper-sk-storage-get.c | 16 + .../gcc.target/bpf/helper-skb-adjust-room.c | 17 + .../gcc.target/bpf/helper-skb-cgroup-id.c | 14 + .../gcc.target/bpf/helper-skb-change-head.c | 16 + .../gcc.target/bpf/helper-skb-change-proto.c | 16 + .../gcc.target/bpf/helper-skb-change-tail.c | 16 + .../gcc.target/bpf/helper-skb-change-type.c | 15 + .../gcc.target/bpf/helper-skb-ecn-set-ce.c | 14 + .../gcc.target/bpf/helper-skb-get-tunnel-key.c | 16 + .../gcc.target/bpf/helper-skb-get-tunnel-opt.c | 16 + .../gcc.target/bpf/helper-skb-get-xfrm-state.c | 17 + .../bpf/helper-skb-load-bytes-relative.c | 17 + .../gcc.target/bpf/helper-skb-load-bytes.c | 15 + .../gcc.target/bpf/helper-skb-pull-data.c | 15 + .../gcc.target/bpf/helper-skb-set-tunnel-key.c | 16 + .../gcc.target/bpf/helper-skb-set-tunnel-opt.c | 16 + .../gcc.target/bpf/helper-skb-store-bytes.c | 18 + .../gcc.target/bpf/helper-skb-under-cgroup.c | 15 + gcc/testsuite/gcc.target/bpf/helper-skb-vlan-pop.c | 14 + .../gcc.target/bpf/helper-skb-vlan-push.c | 16 + .../gcc.target/bpf/helper-skc-lookup-tcp.c | 17 + .../gcc.target/bpf/helper-sock-hash-update.c | 16 + .../gcc.target/bpf/helper-sock-map-update.c | 16 + .../gcc.target/bpf/helper-sock-ops-cb-flags-set.c | 16 + gcc/testsuite/gcc.target/bpf/helper-spin-lock.c | 13 + gcc/testsuite/gcc.target/bpf/helper-spin-unlock.c | 13 + gcc/testsuite/gcc.target/bpf/helper-strtol.c | 18 + gcc/testsuite/gcc.target/bpf/helper-strtoul.c | 18 + .../bpf/helper-sysctl-get-current-value.c | 17 + .../gcc.target/bpf/helper-sysctl-get-name.c | 18 + .../gcc.target/bpf/helper-sysctl-get-new-value.c | 17 + .../gcc.target/bpf/helper-sysctl-set-new-value.c | 17 + gcc/testsuite/gcc.target/bpf/helper-tail-call.c | 14 + .../gcc.target/bpf/helper-tcp-check-syncookie.c | 17 + gcc/testsuite/gcc.target/bpf/helper-tcp-sock.c | 13 + gcc/testsuite/gcc.target/bpf/helper-trace-printk.c | 13 + .../gcc.target/bpf/helper-xdp-adjust-head.c | 15 + .../gcc.target/bpf/helper-xdp-adjust-meta.c | 15 + .../gcc.target/bpf/helper-xdp-adjust-tail.c | 15 + .../gcc.target/bpf/skb-ancestor-cgroup-id.c | 16 + gcc/testsuite/gcc.target/bpf/sync-fetch-and-add.c | 14 + gcc/testsuite/lib/target-supports.exp | 18 +- 216 files changed, 5294 insertions(+), 13 deletions(-) create mode 100644 gcc/common/config/bpf/bpf-common.c create mode 100644 gcc/config/bpf/bpf-helpers.def create mode 100644 gcc/config/bpf/bpf-helpers.h create mode 100644 gcc/config/bpf/bpf-opts.h create mode 100644 gcc/config/bpf/bpf-protos.h create mode 100644 gcc/config/bpf/bpf.c create mode 100644 gcc/config/bpf/bpf.h create mode 100644 gcc/config/bpf/bpf.md create mode 100644 gcc/config/bpf/bpf.opt create mode 100644 gcc/config/bpf/constraints.md create mode 100644 gcc/config/bpf/predicates.md create mode 100644 gcc/config/bpf/t-bpf create mode 100644 gcc/testsuite/gcc.target/bpf/bpf.exp create mode 100644 gcc/testsuite/gcc.target/bpf/builtin-load.c create mode 100644 gcc/testsuite/gcc.target/bpf/constant-calls.c create mode 100644 gcc/testsuite/gcc.target/bpf/diag-funargs-2.c create mode 100644 gcc/testsuite/gcc.target/bpf/diag-funargs-3.c create mode 100644 gcc/testsuite/gcc.target/bpf/diag-funargs.c create mode 100644 gcc/testsuite/gcc.target/bpf/diag-indcalls.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-bind.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-bpf-redirect.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-clone-redirect.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-csum-diff.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-csum-update.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-current-task-under-cgroup.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-fib-lookup.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-cgroup-classid.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-current-cgroup-id.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-current-comm.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-current-pid-tgid.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-current-task.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-current-uid-gid.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-hash-recalc.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-listener-sock.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-local-storage.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-numa-node-id.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-prandom-u32.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-route-realm.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-smp-processor-id.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-socket-cookie.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-socket-uid.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-stack.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-stackid.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-getsockopt.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-ktime-get-ns.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-l3-csum-replace.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-l4-csum-replace.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-lwt-push-encap.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-action.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-adjust-srh.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-store-bytes.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-map-delete-elem.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-map-lookup-elem.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-map-peek-elem.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-map-pop-elem.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-map-push-elem.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-map-update-elem.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-msg-apply-bytes.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-msg-cork-bytes.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-msg-pop-data.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-msg-pull-data.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-msg-push-data.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-msg-redirect-hash.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-msg-redirect-map.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-override-return.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-perf-event-output.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-perf-event-read-value.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-perf-event-read.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-perf-prog-read-value.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-probe-read-str.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-probe-read.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-probe-write-user.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-rc-keydown.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-rc-pointer-rel.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-rc-repeat.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-redirect-map.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-set-hash-invalid.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-set-hash.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-setsockopt.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sk-fullsock.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sk-lookup-tcp.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sk-lookup-upd.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sk-redirect-hash.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sk-redirect-map.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sk-release.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sk-select-reuseport.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sk-storage-delete.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sk-storage-get.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-adjust-room.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-cgroup-id.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-change-head.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-change-proto.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-change-tail.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-change-type.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-ecn-set-ce.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-key.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-opt.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-get-xfrm-state.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes-relative.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-pull-data.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-key.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-opt.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-store-bytes.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-under-cgroup.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-vlan-pop.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-vlan-push.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skc-lookup-tcp.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sock-hash-update.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sock-map-update.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sock-ops-cb-flags-set.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-spin-lock.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-spin-unlock.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-strtol.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-strtoul.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sysctl-get-current-value.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sysctl-get-name.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sysctl-get-new-value.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sysctl-set-new-value.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-tail-call.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-tcp-check-syncookie.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-tcp-sock.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-trace-printk.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-head.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-meta.c create mode 100644 gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-tail.c create mode 100644 gcc/testsuite/gcc.target/bpf/skb-ancestor-cgroup-id.c create mode 100644 gcc/testsuite/gcc.target/bpf/sync-fetch-and-add.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cb28809..34b2f62 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,28 @@ 2019-09-09 Jose E. Marchesi + * doc/invoke.texi (Option Summary): Cover eBPF. + (eBPF Options): New section. + * doc/extend.texi (BPF Built-in Functions): Likewise. + (BPF Kernel Helpers): Likewise. + +2019-09-09 Jose E. Marchesi + + * config.gcc: Support for bpf-*-* targets. + * common/config/bpf/bpf-common.c: New file. + * config/bpf/t-bpf: Likewise. + * config/bpf/predicates.md: Likewise. + * config/bpf/constraints.md: Likewise. + * config/bpf/bpf.opt: Likewise. + * config/bpf/bpf.md: Likewise. + * config/bpf/bpf.h: Likewise. + * config/bpf/bpf.c: Likewise. + * config/bpf/bpf-protos.h: Likewise. + * config/bpf/bpf-opts.h: Likewise. + * config/bpf/bpf-helpers.h: Likewise. + * config/bpf/bpf-helpers.def: Likewise. + +2019-09-09 Jose E. Marchesi + * doc/sourcebuild.texi (Effective-Target Keywords): Document indirect_calls. diff --git a/gcc/common/config/bpf/bpf-common.c b/gcc/common/config/bpf/bpf-common.c new file mode 100644 index 0000000..0d04f21 --- /dev/null +++ b/gcc/common/config/bpf/bpf-common.c @@ -0,0 +1,55 @@ +/* Common hooks for eBPF. + Copyright (C) 2019 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" +#include "config/bpf/bpf-protos.h" + +#undef TARGET_DEFAULT_TARGET_FLAGS +#define TARGET_DEFAULT_TARGET_FLAGS 0 + +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ +static const struct default_options bpf_option_optimization_table[] = + { + /* Enable -funroll-all-loops by default. */ + { OPT_LEVELS_ALL, OPT_funroll_all_loops, NULL, 1 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE bpf_option_optimization_table + +/* Implement TARGET_OPTION_DEFAULT_PARAMS. */ + +static void +bpf_option_default_params (void) +{ + /* XXX large-stack-frame = 512 bytes */ + /* XXX max-unrolled-insns */ + /* XXX max-unroll-times */ +} + +#undef TARGET_OPTION_DEFAULT_PARAMS +#define TARGET_OPTION_DEFAULT_PARAMS bpf_option_default_params + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/config.gcc b/gcc/config.gcc index 94a3608..0eba7ca 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -360,6 +360,9 @@ avr-*-*) bfin*-*) cpu_type=bfin ;; +bpf-*-*) + cpu_type=bpf + ;; crisv32-*) cpu_type=cris ;; @@ -1308,6 +1311,12 @@ bfin*-*) use_collect2=no use_gcc_stdint=wrap ;; +bpf-*-*) + tmake_file="${tmake_file} bpf/t-bpf" + use_collect2=no + extra_headers="bpf-helpers.h" + use_gcc_stdint=provide + ;; cr16-*-elf) tm_file="elfos.h ${tm_file} newlib-stdint.h" tmake_file="${tmake_file} cr16/t-cr16 " diff --git a/gcc/config/bpf/bpf-helpers.def b/gcc/config/bpf/bpf-helpers.def new file mode 100644 index 0000000..cd06402 --- /dev/null +++ b/gcc/config/bpf/bpf-helpers.def @@ -0,0 +1,194 @@ +/* Kernel helpers database. + Copyright (C) 2019 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +/* This file contains the definition of the kernel helpers that are + available to eBPF programs. + + The primary source for information on kernel helpers is the + linux/include/uapi/linux/bpf.h file in the Linux source tree. + Please keep this database in sync. + + The first column is the first kernel version featuring the helper + function. This should be an enumerate from bpf_kernel_version, + defined in bpf-opts.h. Note that the backend assumes that helpers + never get deprecated in the kernel. If that eventually happens, + then we will need to use a bitmask here instead of an enumerate. + + The second column is the constant-name for the helper. + The third column is the program-name of the helper. + + The fourth column is a list of names describing the types of the + values returned and accepted by the helper, in one of these forms: + + TYPES (type1, type2, ..., 0) + VTYPES (type1, type2, ..., 0) + + VTYPES should be used should the helper accept a variable number of + arguments, TYPES otherwise. The valid type names are: + + `vt' for void. + `it' for signed int. + `ut' for unsigned int. + `pt' for void*. + `cpt' for const void*. + `st' for short int. + `ust' for unsigned short int. + `cst' for const char *. + `ullt' for unsigned long long. + `llt' for long long. + `u32t' for uint32. + `u64t' for uint64. + + In types descriptions, the firt entry corresponds to the value + returned by the helper. Subsequent names correspond to the helper + arguments. Finally, a 0 should close the list. + + VERY IMPORTANT: the helper entries should be listed in the same + order than in the definition of __BPF_FUNC_MAPPER in + linux/include/uapi/linux/bpf.h! */ + +DEF_HELPER (LINUX_V4_0, MAP_LOOKUP_ELEM, map_lookup_elem, TYPES (pt, pt, pt, 0)) +DEF_HELPER (LINUX_V4_0, MAP_UPDATE_ELEM, map_update_elem, TYPES (it, pt, pt, pt, ullt, 0)) +DEF_HELPER (LINUX_V4_0, MAP_DELETE_ELEM, map_delete_elem, TYPES (it, pt, pt, 0)) +DEF_HELPER (LINUX_V4_1, PROBE_READ, probe_read, TYPES (it, pt, ut, cpt, 0)) +DEF_HELPER (LINUX_V4_1, KTIME_GET_NS, ktime_get_ns, TYPES (ullt, 0)) +DEF_HELPER (LINUX_V4_1, TRACE_PRINTK, trace_printk, VTYPES (it, cst, it, 0)) +DEF_HELPER (LINUX_V4_1, GET_PRANDOM_U32, get_prandom_u32, TYPES (ullt, 0)) +DEF_HELPER (LINUX_V4_1, GET_SMP_PROCESSOR_ID, get_smp_processor_id, TYPES (ullt, 0)) +DEF_HELPER (LINUX_V4_1, SKB_STORE_BYTES, skb_store_bytes, TYPES (it, pt, it, pt, it, it, 0)) +DEF_HELPER (LINUX_V4_1, L3_CSUM_REPLACE, l3_csum_replace, TYPES (it, pt, it, it ,it ,it, 0)) +DEF_HELPER (LINUX_V4_1, L4_CSUM_REPLACE, l4_csum_replace, TYPES (it, pt, it, it, it, it, 0)) +DEF_HELPER (LINUX_V4_2, TAIL_CALL, tail_call, TYPES (vt, pt, pt, it, 0)) +DEF_HELPER (LINUX_V4_2, CLONE_REDIRECT, clone_redirect, TYPES (it, pt, it, it, 0)) +DEF_HELPER (LINUX_V4_2, GET_CURRENT_PID_TGID, get_current_pid_tgid, TYPES (ullt, 0)) +DEF_HELPER (LINUX_V4_2, GET_CURRENT_UID_GID, get_current_uid_gid, TYPES (ullt, 0)) +DEF_HELPER (LINUX_V4_2, GET_CURRENT_COMM, get_current_comm, TYPES (it, pt, it, 0)) +DEF_HELPER (LINUX_V4_3, GET_CGROUP_CLASSID, get_cgroup_classid, TYPES (it, pt, 0)) +DEF_HELPER (LINUX_V4_3, SKB_VLAN_PUSH, skb_vlan_push, TYPES (it, pt, st, ust, 0)) +DEF_HELPER (LINUX_V4_3, SKB_VLAN_POP, skb_vlan_pop, TYPES (it, pt, 0)) +DEF_HELPER (LINUX_V4_3, SKB_GET_TUNNEL_KEY, skb_get_tunnel_key, TYPES (it, pt, pt, it, it, 0)) +DEF_HELPER (LINUX_V4_3, SKB_SET_TUNNEL_KEY, skb_set_tunnel_key, TYPES (it, pt, pt, it, it, 0)) +DEF_HELPER (LINUX_V4_3, PERF_EVENT_READ, perf_event_read, TYPES (ullt, pt, ullt, 0)) +DEF_HELPER (LINUX_V4_4, REDIRECT, redirect, TYPES (it, it, it, 0)) +DEF_HELPER (LINUX_V4_4, GET_ROUTE_REALM, get_route_realm, TYPES (ut, pt, 0)) +DEF_HELPER (LINUX_V4_4, PERF_EVENT_OUTPUT, perf_event_output, \ + TYPES (it, pt, pt, ullt, pt, it, 0)) +DEF_HELPER (LINUX_V4_5, SKB_LOAD_BYTES, skb_load_bytes, TYPES (it, pt, it, pt, it, 0)) +DEF_HELPER (LINUX_V4_6, GET_STACKID, get_stackid, TYPES (it, pt, pt, it, 0)) +DEF_HELPER (LINUX_V4_6, CSUM_DIFF, csum_diff, TYPES (it, pt, it, pt, it, it, 0)) +DEF_HELPER (LINUX_V4_6, SKB_GET_TUNNEL_OPT, skb_get_tunnel_opt, TYPES (it, pt, pt, it, 0)) +DEF_HELPER (LINUX_V4_6, SKB_SET_TUNNEL_OPT, skb_set_tunnel_opt, TYPES (it, pt, pt, it, 0)) +DEF_HELPER (LINUX_V4_8, SKB_CHANGE_PROTO, skb_change_proto, TYPES (it, pt, st, u64t, 0)) +DEF_HELPER (LINUX_V4_8, SKB_CHANGE_TYPE, skb_change_type, TYPES (it, pt, u32t, 0)) +DEF_HELPER (LINUX_V4_8, SKB_UNDER_CGROUP, skb_under_cgroup, TYPES (it, pt, pt, it, 0)) +DEF_HELPER (LINUX_V4_8, GET_HASH_RECALC, get_hash_recalc, TYPES (ut, pt, 0)) +DEF_HELPER (LINUX_V4_8, GET_CURRENT_TASK, get_current_task, TYPES (ullt, 0)) +DEF_HELPER (LINUX_V4_8, PROBE_WRITE_USER, probe_write_user, TYPES (it, pt, cpt, ut, 0)) +DEF_HELPER (LINUX_V4_9, CURRENT_TASK_UNDER_CGROUP, current_task_under_cgroup, \ + TYPES (it, pt, it, 0)) +DEF_HELPER (LINUX_V4_9, SKB_CHANGE_TAIL, skb_change_tail, TYPES (it, pt, ut, u64t, 0)) +DEF_HELPER (LINUX_V4_9, SKB_PULL_DATA, skb_pull_data, TYPES (it, pt, it, 0)) +DEF_HELPER (LINUX_V4_9, CSUM_UPDATE, csum_update, TYPES (llt, pt, u32t, 0)) +DEF_HELPER (LINUX_V4_9, SET_HASH_INVALID, set_hash_invalid, TYPES (vt, pt, 0)) +DEF_HELPER (LINUX_V4_10, GET_NUMA_NODE_ID, get_numa_node_id, TYPES (it, 0)) +DEF_HELPER (LINUX_V4_10, SKB_CHANGE_HEAD, skb_change_head, TYPES (it, pt, it, it, 0)) +DEF_HELPER (LINUX_V4_10, XDP_ADJUST_HEAD, xdp_adjust_head, TYPES (it, pt, it, 0)) +DEF_HELPER (LINUX_V4_11, PROBE_READ_STR, probe_read_str, TYPES (it, pt, u32t, cpt, 0)) +DEF_HELPER (LINUX_V4_12, GET_SOCKET_COOKIE, get_socket_cookie, TYPES (it, pt, 0)) +DEF_HELPER (LINUX_V4_12, GET_SOCKET_UID, get_socket_uid, TYPES (ut, pt, 0)) +DEF_HELPER (LINUX_V4_13, SET_HASH, set_hash, TYPES (ut, pt, u32t, 0)) +DEF_HELPER (LINUX_V4_13, SETSOCKOPT, setsockopt, TYPES (it, pt, it, it, pt, it, 0)) +DEF_HELPER (LINUX_V4_13, SKB_ADJUST_ROOM, skb_adjust_room, TYPES (it, pt, st, u32t, ullt, 0)) +DEF_HELPER (LINUX_V4_14, REDIRECT_MAP, redirect_map, TYPES (it, pt, it, it, 0)) +DEF_HELPER (LINUX_V4_14, SK_REDIRECT_MAP, sk_redirect_map, TYPES (it, pt, pt, it, it, 0)) +DEF_HELPER (LINUX_V4_14, SOCK_MAP_UPDATE, sock_map_update, TYPES (it, pt, pt, pt, ullt, 0)) +DEF_HELPER (LINUX_V4_15, XDP_ADJUST_META, xdp_adjust_meta, TYPES (it, pt, it, 0)) +DEF_HELPER (LINUX_V4_15, PERF_EVENT_READ_VALUE, perf_event_read_value, + TYPES (it, pt, ullt, pt, ut, 0)) +DEF_HELPER (LINUX_V4_15, PERF_PROG_READ_VALUE, perf_prog_read_value, + TYPES (it, pt, pt, ut, 0)) +DEF_HELPER (LINUX_V4_15, GETSOCKOPT, getsockopt, TYPES (it, pt, it, it, pt, it, 0)) + +DEF_HELPER (LINUX_V4_16, OVERRIDE_RETURN, override_return, TYPES (it, pt, ult, 0)) +DEF_HELPER (LINUX_V4_16, SOCK_OPS_CB_FLAGS_SET, sock_ops_cb_flags_set, TYPES (it, pt, it, 0)) +DEF_HELPER (LINUX_V4_17, MSG_REDIRECT_MAP, msg_redirect_map, TYPES (it, pt, pt, it, it, 0)) +DEF_HELPER (LINUX_V4_17, MSG_APPLY_BYTES, msg_apply_bytes, TYPES (it, pt, it, 0)) +DEF_HELPER (LINUX_V4_17, MSG_CORK_BYTES, msg_cork_bytes, TYPES (it, pt, it, 0)) +DEF_HELPER (LINUX_V4_17, MSG_PULL_DATA, msg_pull_data, TYPES (it, pt, it, it, it, 0)) +DEF_HELPER (LINUX_V4_17, BIND, bind, TYPES (it, pt, pt, it, 0)) +DEF_HELPER (LINUX_V4_18, XDP_ADJUST_TAIL, xdp_adjust_tail, TYPES (it, pt, it, 0)) +DEF_HELPER (LINUX_V4_18, SKB_GET_XFRM_STATE, + skb_get_xfrm_state, TYPES (it, pt, it, pt, it, it, 0)) +DEF_HELPER (LINUX_V4_18, GET_STACK, get_stack, TYPES (it, pt, pt, it, it, 0)) +DEF_HELPER (LINUX_V4_18, SKB_LOAD_BYTES_RELATIVE, skb_load_bytes_relative, + TYPES (it, pt, it, pt, it, ut, 0)) +DEF_HELPER (LINUX_V4_18, FIB_LOOKUP, fib_lookup, TYPES (it, pt, pt, it, ut, 0)) +DEF_HELPER (LINUX_V4_18, SOCK_HASH_UPDATE, sock_hash_update, TYPES (it, pt, pt, pt, ullt, 0)) +DEF_HELPER (LINUX_V4_18, MSG_REDIRECT_HASH, msg_redirect_hash, TYPES (it, pt, pt, pt, it, 0)) +DEF_HELPER (LINUX_V4_18, SK_REDIRECT_HASH, sk_redirect_hash, TYPES (it, pt, pt, pt, it, 0)) +DEF_HELPER (LINUX_V4_18, LWT_PUSH_ENCAP, lwt_push_encap, TYPES (it, pt, ut, pt, ut, 0)) +DEF_HELPER (LINUX_V4_18, LWT_SEG6_STORE_BYTES, lwt_seg6_store_bytes, + TYPES (it, pt, ut, pt, ut, 0)) +DEF_HELPER (LINUX_V4_18, LWT_SEG6_ADJUST_SRH, lwt_seg6_adjust_srh, TYPES (it, pt, ut, ut, 0)) +DEF_HELPER (LINUX_V4_18, LWT_SEG6_ACTION, lwt_seg6_action, TYPES (it, pt, ut, pt, ut, 0)) +DEF_HELPER (LINUX_V4_18, RC_REPEAT, rc_repeat, TYPES (it, pt, 0)) +DEF_HELPER (LINUX_V4_18, RC_KEYDOWN, rc_keydown, TYPES (it, pt, ut, ullt, ut, 0)) +DEF_HELPER (LINUX_V4_18, SKB_CGROUP_ID, skb_cgroup_id, TYPES (ullt, pt, 0)) +DEF_HELPER (LINUX_V4_18, GET_CURRENT_CGROUP_ID, get_current_cgroup_id, TYPES (ullt, 0)) +DEF_HELPER (LINUX_V4_19, GET_LOCAL_STORAGE, get_local_storage, TYPES (pt, pt, ullt, 0)) +DEF_HELPER (LINUX_V4_19, SK_SELECT_REUSEPORT, sk_select_reuseport, + TYPES (it, pt, pt, pt, ut, 0)) +DEF_HELPER (LINUX_V4_19, SKB_ANCESTOR_CGROUP_ID, skb_ancestor_cgroup_id, + TYPES (ullt, pt, it, 0)) +DEF_HELPER (LINUX_V4_20, SK_LOOKUP_TCP, sk_lookup_tcp, TYPES (pt, pt, pt, it, ullt, ullt, 0)) +DEF_HELPER (LINUX_V4_20, SK_LOOKUP_UDP, sk_lookup_udp, TYPES (pt, pt, pt, it, ullt, ullt, 0)) +DEF_HELPER (LINUX_V4_20, SK_RELEASE, sk_release, TYPES (it, pt, 0)) +DEF_HELPER (LINUX_V4_20, MAP_PUSH_ELEM, map_push_elem, TYPES (it, pt, pt, ullt, 0)) +DEF_HELPER (LINUX_V4_20, MAP_POP_ELEM, map_pop_elem, TYPES (it, pt, pt, 0)) +DEF_HELPER (LINUX_V4_20, MAP_PEEK_ELEM, map_peek_elem, TYPES (it, pt, pt, 0)) +DEF_HELPER (LINUX_V4_20, MSG_PUSH_DATA, msg_push_data, TYPES (it, pt, it, it, it, 0)) +DEF_HELPER (LINUX_V5_0, MSG_POP_DATA, msg_pop_data, TYPES (it, pt, it, it, it, 0)) +DEF_HELPER (LINUX_V5_0, RC_POINTER_REL, rc_pointer_rel, TYPES (it, pt, it, it, 0)) +DEF_HELPER (LINUX_V5_1, SPIN_LOCK, spin_lock, TYPES (vt, pt, 0)) +DEF_HELPER (LINUX_V5_1, SPIN_UNLOCK, spin_unlock, TYPES (vt, pt, 0)) +DEF_HELPER (LINUX_V5_1, SK_FULLSOCK, sk_fullsock, TYPES (pt, pt, 0)) +DEF_HELPER (LINUX_V5_1, TCP_SOCK, tcp_sock, TYPES (pt, pt, 0)) +DEF_HELPER (LINUX_V5_1, SKB_ECN_SET_CE, skb_ecn_set_ce, TYPES (it, pt, 0)) +DEF_HELPER (LINUX_V5_1, GET_LISTENER_SOCK, get_listener_sock, TYPES (pt, pt, 0)) +DEF_HELPER (LINUX_V5_2, SKC_LOOKUP_TCP, skc_lookup_tcp, + TYPES (pt, pt, pt, u32t, u64t, u64t, 0)) +DEF_HELPER (LINUX_V5_2, TCP_CHECK_SYNCOOKIE, tcp_check_syncookie, + TYPES (it, pt, pt, u32t, pt, u32t, 0)) +DEF_HELPER (LINUX_V5_2, SYSCTL_GET_NAME, sysctl_get_name, TYPES (it, pt, pt, ullt, u64t, 0)) +DEF_HELPER (LINUX_V5_2, SYSCTL_GET_CURRENT_VALUE, sysctl_get_current_value, + TYPES (it, pt, pt, ullt, 0)) +DEF_HELPER (LINUX_V5_2, SYSCTL_GET_NEW_VALUE, sysctl_get_new_value, + TYPES (it, pt, pt, ullt, 0)) +DEF_HELPER (LINUX_V5_2, SYSCTL_SET_NEW_VALUE, sysctl_set_new_value, + TYPES (it, pt, pt, ullt, 0)) +DEF_HELPER (LINUX_V5_2, STRTOL, strtol, TYPES (it, cst, ullt, u64t, pt, 0)) +DEF_HELPER (LINUX_V5_2, STRTOUL, strtoul, TYPES (it, pt, ullt, u64t, pt, 0)) +DEF_HELPER (LINUX_V5_2, SK_STORAGE_GET, sk_storage_get, TYPES (pt, pt, pt, pt, u64t, 0)) +DEF_HELPER (LINUX_V5_2, SK_STORAGE_DELETE, sk_storage_delete, TYPES (it, pt, pt, 0)) + +/* +Local variables: +mode:c +End: +*/ diff --git a/gcc/config/bpf/bpf-helpers.h b/gcc/config/bpf/bpf-helpers.h new file mode 100644 index 0000000..1427543 --- /dev/null +++ b/gcc/config/bpf/bpf-helpers.h @@ -0,0 +1,327 @@ +/* Copyright (C) 2019 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + +/* The purpose of this file is to provide a compatiblity layer with + the Linux kernel bpf_helpers.h header that is located in + linux/tools/testing/selftests/bpf/bpf_helpers.h. That file is + currently llvm-specific. */ + +#ifndef __BPF_HELPERS_H +#define __BPF_HELPERS_H + +#define SEC(NAME) __attribute__((section(NAME), used)) + +/* Flags used in some kernel helpers. */ + +#define BPF_ANY 0 +#define BPF_NOEXIST 1 +#define BPF_EXIST 2 + +#define BPF_F_LOCK 4 +#define BPF_F_NO_COMMON_LRU (1U << 1) +#define BPF_F_NUMA_NODE (1U << 2) + +/* Functions to call kernel helpers. We provide the "standard" bpf_* + names as synonyms of the corresponding GCC builtins. In some + cases, where non-void pointers are passed to the helper, inline + functions are used to achieve proper type checking. */ + +#ifndef KERNEL_VERSION +# define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) +#endif + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,0,0) + +#define bpf_map_lookup_elem __builtin_bpf_helper_map_lookup_elem +#define bpf_map_update_elem __builtin_bpf_helper_map_update_elem +#define bpf_map_delete_elem __builtin_bpf_helper_map_delete_elem + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,1,0) + +#define bpf_probe_read __builtin_bpf_helper_probe_read +#define bpf_ktime_get_ns __builtin_bpf_helper_ktime_get_ns +#define bpf_trace_printk __builtin_bpf_helper_trace_printk +#define bpf_get_prandom_u32 __builtin_bpf_helper_get_prandom_u32 +#define bpf_get_smp_processor_id __builtin_bpf_helper_get_smp_processor_id +#define bpf_skb_store_bytes __builtin_bpf_helper_skb_store_bytes +#define bpf_l3_csum_replace __builtin_bpf_helper_l3_csum_replace +#define bpf_l4_csum_replace __builtin_bpf_helper_l4_csum_replace + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,2,0) + +#define bpf_tail_call __builtin_bpf_helper_tail_call +#define bpf_clone_redirect __builtin_bpf_helper_clone_redirect +#define bpf_get_current_pid_tgid __builtin_bpf_helper_get_current_pid_tgid +#define bpf_get_current_uid_gid __builtin_bpf_helper_get_current_uid_gid +#define bpf_get_current_comm __builtin_bpf_helper_get_current_comm + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,3,0) + +#define bpf_get_cgroup_classid __builtin_bpf_helper_get_cgroup_classid +#define bpf_skb_vlan_push __builtin_bpf_helper_skb_vlan_push +#define bpf_skb_vlan_pop __builtin_bpf_helper_skb_vlan_pop +#define bpf_skb_get_tunnel_key __builtin_bpf_helper_skb_get_tunnel_key +#define bpf_skb_set_tunnel_key __builtin_bpf_helper_skb_set_tunnel_key +#define bpf_perf_event_read __builtin_bpf_helper_perf_event_read + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,4,0) + +#define bpf_redirect __builtin_bpf_helper_redirect +#define bpf_get_route_realm __builtin_bpf_helper_get_route_realm +#define bpf_perf_event_output __builtin_bpf_helper_perf_event_output + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,5,0) + +#define bpf_skb_load_bytes __builtin_bpf_helper_skb_load_bytes + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,6,0) + +#define bpf_get_stackid __builtin_bpf_helper_get_stackid +#define bpf_csum_diff __builtin_bpf_helper_csum_diff +#define bpf_skb_get_tunnel_opt __builtin_bpf_helper_skb_get_tunnel_opt +#define bpf_skb_set_tunnel_opt __builtin_bpf_helper_skb_set_tunnel_opt + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,8,0) + +#define bpf_skb_change_proto __builtin_bpf_helper_skb_change_proto +#define bpf_skb_change_type __builtin_bpf_helper_skb_change_type +#define bpf_skb_under_cgroup __builtin_bpf_helper_skb_under_cgroup +#define bpf_get_hash_recalc __builtin_bpf_helper_get_hash_recalc +#define bpf_get_current_task __builtin_bpf_helper_get_current_task +#define bpf_probe_write_user __builtin_bpf_helper_probe_write_user + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,9,0) + +#define bpf_current_task_under_cgroup __builtin_bpf_helper_current_task_under_cgroup +#define bpf_skb_change_tail __builtin_bpf_helper_skb_change_tail +#define bpf_skb_pull_data __builtin_bpf_helper_skb_pull_data +#define bpf_csum_update __builtin_bpf_helper_csum_update +#define bpf_set_hash_invalid __builtin_bpf_helper_set_hash_invalid + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,10,0) + +#define bpf_get_numa_node_id __builtin_bpf_helper_get_numa_node_id +#define bpf_skb_change_head __builtin_bpf_helper_skb_change_head +#define bpf_xdp_adjust_head __builtin_bpf_helper_xdp_adjust_head + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,11,0) + +#define bpf_probe_read_str __builtin_bpf_helper_probe_read_str + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,12,0) + +#define bpf_get_socket_cookie __builtin_bpf_helper_get_socket_cookie +#define bpf_get_socket_uid __builtin_bpf_helper_get_socket_uid + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,13,0) + +#define bpf_set_hash __builtin_bpf_helper_set_hash +#define bpf_setsockopt __builtin_bpf_helper_setsockopt +#define bpf_skb_adjust_room __builtin_bpf_helper_skb_adjust_room + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,14,0) + +#define bpf_redirect_map __builtin_bpf_helper_redirect_map +#define bpf_sk_redirect_map __builtin_bpf_helper_sk_redirect_map +#define bpf_sock_map_update __builtin_bpf_helper_sock_map_update + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,15,0) + +#define bpf_perf_event_read_value __builtin_bpf_helper_perf_event_read_value +#define bpf_perf_prog_read_value __builtin_bpf_helper_perf_prog_read_value +#define bpf_getsockopt __builtin_bpf_helper_getsockopt +#define bpf_xdp_adjust_meta __builtin_bpf_helper_xdp_adjust_meta + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,16,0) + +#define bpf_override_return __builtin_bpf_helper_override_return +#define bpf_sock_ops_cb_flags_set __builtin_bpf_helper_sock_ops_cb_flags_set + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,17,0) + +#define bpf_msg_redirect_map __builtin_bpf_helper_msg_redirect_map +#define bpf_msg_apply_bytes __builtin_bpf_helper_msg_apply_bytes +#define bpf_msg_cork_bytes __builtin_bpf_helper_msg_cork_bytes +#define bpf_pull_data __builtin_bpf_helper_pull_data +#define bpf_bind __builtin_bpf_helper_bpf_bind + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,18,0) + +#define bpf_xdp_adjust_tail __builtin_bpf_helper_xdp_adjust_tail +#define bpf_skb_get_xfrm_state __builtin_bpf_helper_skb_get_xfrm_state +#define bpf_get_stack __builtin_bpf_helper_get_stack +#define bpf_skb_load_bytes_relative __builtin_bpf_helper_skb_load_bytes_relative +#define bpf_sock_hash_update __builtin_bpf_helper_sock_hash_update +#define bpf_msg_redirect_hash __builtin_bpf_helper_msg_redirect_hash +#define bpf_sk_redirect_hash __builtin_bpf_helper_sk_redirect_hash +#define bpf_lwt_push_encap __builtin_bpf_helper_lwt_push_encap +#define bpf_lwt_seg6_store_bytes __builtin_bpf_helper_lwt_seg6_store_bytes +#define bpf_lwt_seg6_adjust_srh __builtin_bpf_helper_lwt_seg6_adjust_srh +#define bpf_lwt_seg6_action __builtin_bpf_helper_lwt_seg6_action +#define bpf_rc_repeat __builtin_bpf_helper_rc_repeat +#define bpf_rc_keydown __builtin_bpf_helper_rc_keydown +#define bpf_skb_cgroup_id __builtin_bpf_helper_skb_cgroup_id +#define bpf_get_current_cgroup_id __builtin_bpf_helper_get_current_cgroup_id + +static inline int +bpf_fib_lookup (void *ctx, struct bpf_fib_lookup *param, int plen, + unsigned int flags) +{ + return __builtin_bpf_helper_fib_lookup (ctx, (void *) param, plen, flags); +} + + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,19,0) + +#define bpf_get_local_storage __builtin_bpf_helper_get_local_storage +#define bpf_sk_select_reuseport __builtin_bpf_helper_sk_select_reuseport +#define bpf_skb_ancestor_cgroup_id __builtin_bpf_helper_skb_ancestor_cgroup_id + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (4,20,0) + +#define bpf_sk_release __builtin_bpf_helper_sk_release +#define bpf_map_push_elem __builtin_bpf_helper_map_push_elem +#define bpf_map_pop_elem __builtin_bpf_helper_map_pop_elem +#define bpf_map_peek_elem __builtin_bpf_helper_map_peek_elem +#define bpf_msg_push_data __builtin_bpf_helper_msg_push_data + +static inline struct bpf_sock * +bpf_sk_lookup_tcp (void *ctx, struct bpf_sock_tuple *tuple, + int size, unsigned long long netns_id, + unsigned long long flags) +{ + return + (struct bpf_sock *) __builtin_bpf_helper_sk_lookup_tcp (ctx, + (void *) tuple, + size, + netns_id, flags); +} + +static inline struct bpf_sock * +bpf_sk_lookup_udp (void *ctx, struct bpf_sock_tuple *tuple, + int size, unsigned long long netns_id, + unsigned long long flags) +{ + return + (struct bpf_sock *) __builtin_bpf_helper_sk_lookup_udp (ctx, + (void *) tuple, + size, + netns_id, flags); +} + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (5,0,0) + +#define bpf_msg_pop_data __builtin_bpf_helper_pop_data +#define bpf_rc_pointer_rel __builtin_bpf_helper_rc_pointer_rel + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (5,1,0) + +#define bpf_spin_lock __builtin_bpf_helper_spin_lock +#define bpf_spin_unlock __builtin_bpf_helper_spin_unlock +#define bpf_skb_ecn_set_ce __builtin_bpf_helper_skb_ecn_set_ce + +static inline struct bpf_sock * +bpf_sk_fullsock (struct bpf_sock *sk) +{ + return + (struct bpf_sock *) __builtin_bpf_helper_sk_fullsock ((void *) sk); +} + +static inline struct bpf_sock * +bpf_tcp_sock (struct bpf_sock *sk) +{ + return + (struct bpf_sock *) __builtin_bpf_helper_tcp_sock ((void *) sk); +} + +static inline struct bpf_sock * +bpf_get_listener_sock (struct bpf_sock *sk) +{ + return + (struct bpf_sock *) __builtin_bpf_helper_get_listener_sock ((void *) sk); +} + +#if __BPF_KERNEL_VERSION_CODE__ >= KERNEL_VERSION (5,2,0) + + +#endif /* 5.2 */ +#endif /* 5.1 */ +#endif /* 5.0 */ +#endif /* 4.20 */ +#endif /* 4.19 */ +#endif /* 4.18 */ +#endif /* 4.17 */ +#endif /* 4.16 */ +#endif /* 4.15 */ +#endif /* 4.14 */ +#endif /* 4.13 */ +#endif /* 4.12 */ +#endif /* 4.11 */ +#endif /* 4.10 */ +#endif /* 4.9 */ +#endif /* 4.8 */ +#endif /* 4.6 */ +#endif /* 4.5 */ +#endif /* 4.4 */ +#endif /* 4.3 */ +#endif /* 4.2 */ +#endif /* 4.1 */ +#endif /* 4.0 */ + +/* Functions to emit BPF_LD_ABS and BPF_LD_IND instructions. We + provide the "standard" names as synonyms of the corresponding GCC + builtins. Note how the SKB argument is ignored. */ + +static inline long long +load_byte (void *skb __attribute__ ((unused)), + unsigned long long off) +{ + return __builtin_bpf_load_byte (off); +} + +static inline long long +load_half (void *skb __attribute__ ((unused)), + unsigned long long off) +{ + return __builtin_bpf_load_half (off); +} + +static inline long long +load_word (void *skb __attribute__ ((unused)), + unsigned long long off) +{ + return __builtin_bpf_load_word (off); +} + +struct bpf_map_def +{ + unsigned int type; + unsigned int key_size; + unsigned int value_size; + unsigned int max_entries; + unsigned int map_flags; + unsigned int inner_map_idx; + unsigned int numa_node; +}; + +#endif /* ! __BPF_HELPERS_H */ diff --git a/gcc/config/bpf/bpf-opts.h b/gcc/config/bpf/bpf-opts.h new file mode 100644 index 0000000..9f210a1 --- /dev/null +++ b/gcc/config/bpf/bpf-opts.h @@ -0,0 +1,56 @@ +/* Definitions for option handling for eBPF. + Copyright (C) 2019 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +#ifndef BPF_OPTS_H +#define BPF_OPTS_H + +/* Supported versions of the Linux kernel. */ +enum bpf_kernel_version +{ + /* Linux 4.x */ + LINUX_V4_0, + LINUX_V4_1, + LINUX_V4_2, + LINUX_V4_3, + LINUX_V4_4, + LINUX_V4_5, + LINUX_V4_6, + LINUX_V4_7, + LINUX_V4_8, + LINUX_V4_9, + LINUX_V4_10, + LINUX_V4_11, + LINUX_V4_12, + LINUX_V4_13, + LINUX_V4_14, + LINUX_V4_15, + LINUX_V4_16, + LINUX_V4_17, + LINUX_V4_18, + LINUX_V4_19, + LINUX_V4_20, + /* Linux 5.x */ + LINUX_V5_0, + LINUX_V5_1, + LINUX_V5_2, + LINUX_LATEST = LINUX_V5_2, + LINUX_NATIVE, +}; + +#endif /* ! BPF_OPTS_H */ diff --git a/gcc/config/bpf/bpf-protos.h b/gcc/config/bpf/bpf-protos.h new file mode 100644 index 0000000..3a835f4 --- /dev/null +++ b/gcc/config/bpf/bpf-protos.h @@ -0,0 +1,33 @@ +/* Definition of eBPF target for GNU compiler. + Copyright (C) 2019 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_BPF_PROTOS_H +#define GCC_BPF_PROTOS_H + +/* Routines implemented in bpf.c. */ + +extern HOST_WIDE_INT bpf_initial_elimination_offset (int, int); +extern const char *bpf_output_call (rtx); +extern void bpf_target_macros (cpp_reader *); +extern void bpf_print_operand (FILE *, rtx, int); +extern void bpf_print_operand_address (FILE *, rtx); +extern void bpf_expand_prologue (void); +extern void bpf_expand_epilogue (void); + +#endif /* ! GCC_BPF_PROTOS_H */ diff --git a/gcc/config/bpf/bpf.c b/gcc/config/bpf/bpf.c new file mode 100644 index 0000000..8b2a592 --- /dev/null +++ b/gcc/config/bpf/bpf.c @@ -0,0 +1,948 @@ +/* Subroutines used for code generation for eBPF. + Copyright (C) 2019 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#define IN_TARGET_CODE 1 + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "rtl.h" +#include "regs.h" +#include "insn-config.h" +#include "insn-attr.h" +#include "recog.h" +#include "output.h" +#include "alias.h" +#include "tree.h" +#include "stringpool.h" +#include "attribs.h" +#include "varasm.h" +#include "stor-layout.h" +#include "calls.h" +#include "function.h" +#include "explow.h" +#include "memmodel.h" +#include "emit-rtl.h" +#include "reload.h" +#include "tm_p.h" +#include "target.h" +#include "target-def.h" +#include "basic-block.h" +#include "expr.h" +#include "optabs.h" +#include "bitmap.h" +#include "df.h" +#include "c-family/c-common.h" +#include "diagnostic.h" +#include "builtins.h" +#include "predict.h" +#include "langhooks.h" + +/* Per-function machine data. */ +struct GTY(()) machine_function +{ + /* Number of bytes saved on the stack for local variables. */ + int local_vars_size; + + /* Number of bytes saved on the stack for callee-saved + registers. */ + int callee_saved_reg_size; +}; + +/* Data structures for the eBPF specific built-ins. */ + +/* Maximum number of arguments taken by a builtin function, plus + one. */ +#define BPF_BUILTIN_MAX_ARGS 5 + +enum bpf_builtins +{ + BPF_BUILTIN_UNUSED = 0, + /* Built-ins for kernel helpers. */ +#define DEF_HELPER(V,D,N,T) BPF_BUILTIN_HELPER_##D, +# include "bpf-helpers.def" +#undef DEF_HELPER + BPF_BUILTIN_HELPER_MAX, + /* Built-ins for non-generic loads and stores. */ + BPF_BUILTIN_LOAD_BYTE = BPF_BUILTIN_HELPER_MAX, + BPF_BUILTIN_LOAD_HALF, + BPF_BUILTIN_LOAD_WORD, + BPF_BUILTIN_MAX, +}; + +/* This table is indexed by an enum bpf_builtin. */ +static const char *bpf_helper_names[] = +{ + NULL, +#define DEF_HELPER(V,D,N,T) #N, +# include "bpf-helpers.def" +#undef DEF_HELPER + NULL, + NULL, + NULL, + NULL +}; + +/* Return the builtin code corresponding to the kernel helper builtin + __builtin_NAME, or 0 if the name doesn't correspond to a kernel + helper builtin. */ + +static inline int +bpf_helper_code (const char *name) +{ + int i; + + for (i = 1; i < BPF_BUILTIN_HELPER_MAX; ++i) + if (strcmp (name, bpf_helper_names[i]) == 0) + return i; + + return 0; +} + +static GTY (()) tree bpf_builtins[(int) BPF_BUILTIN_MAX]; + +/* Initialize the per-function machine status. */ + +static struct machine_function * +bpf_init_machine_status (void) +{ + /* Note this initializes all fields to 0, which is just OK for + us. */ + return ggc_cleared_alloc (); +} + +/* Override options and do some other initialization. */ + +static void +bpf_option_override (void) +{ + /* Set the initializer for the per-function status structure. */ + init_machine_status = bpf_init_machine_status; +} + +#undef TARGET_OPTION_OVERRIDE +#define TARGET_OPTION_OVERRIDE bpf_option_override + +/* Define target-specific CPP macros. This function in used in the + definition of TARGET_CPU_CPP_BUILTINS in bpf.h */ + +#define builtin_define(TXT) cpp_define (pfile, TXT) + +void +bpf_target_macros (cpp_reader *pfile) +{ + builtin_define ("__BPF__"); + + if (TARGET_BIG_ENDIAN) + builtin_define ("__BPF_BIG_ENDIAN__"); + else + builtin_define ("__BPF_LITTLE_ENDIAN__"); + + /* Define BPF_KERNEL_VERSION_CODE */ + { + const char *version_code; + char *kernel_version_code; + + switch (bpf_kernel) + { + case LINUX_V4_0: version_code = "0x40000"; break; + case LINUX_V4_1: version_code = "0x40100"; break; + case LINUX_V4_2: version_code = "0x40200"; break; + case LINUX_V4_3: version_code = "0x40300"; break; + case LINUX_V4_4: version_code = "0x40400"; break; + case LINUX_V4_5: version_code = "0x40500"; break; + case LINUX_V4_6: version_code = "0x40600"; break; + case LINUX_V4_7: version_code = "0x40700"; break; + case LINUX_V4_8: version_code = "0x40800"; break; + case LINUX_V4_9: version_code = "0x40900"; break; + case LINUX_V4_10: version_code = "0x40a00"; break; + case LINUX_V4_11: version_code = "0x40b00"; break; + case LINUX_V4_12: version_code = "0x40c00"; break; + case LINUX_V4_13: version_code = "0x40d00"; break; + case LINUX_V4_14: version_code = "0x40e00"; break; + case LINUX_V4_15: version_code = "0x40f00"; break; + case LINUX_V4_16: version_code = "0x41000"; break; + case LINUX_V4_17: version_code = "0x42000"; break; + case LINUX_V4_18: version_code = "0x43000"; break; + case LINUX_V4_19: version_code = "0x44000"; break; + case LINUX_V4_20: version_code = "0x45000"; break; + case LINUX_V5_0: version_code = "0x50000"; break; + case LINUX_V5_1: version_code = "0x50100"; break; + case LINUX_V5_2: version_code = "0x50200"; break; + default: + gcc_unreachable (); + } + + kernel_version_code = ACONCAT (("__BPF_KERNEL_VERSION_CODE__=", + version_code, NULL)); + builtin_define (kernel_version_code); + } +} + +/* Output assembly directives to switch to section NAME. The section + should have attributes as specified by FLAGS, which is a bit mask + of the 'SECTION_*' flags defined in 'output.h'. If DECL is + non-NULL, it is the 'VAR_DECL' or 'FUNCTION_DECL' with which this + section is associated. */ + +static void +bpf_asm_named_section (const char *name, + unsigned int flags ATTRIBUTE_UNUSED, + tree decl ATTRIBUTE_UNUSED) +{ + fprintf (asm_out_file, "\t.section\t%s\n", name); +} + +#undef TARGET_ASM_NAMED_SECTION +#define TARGET_ASM_NAMED_SECTION bpf_asm_named_section + +/* Return an RTX representing the place where a function returns or + receives a value of data type RET_TYPE, a tree node representing a + data type. */ + +static rtx +bpf_function_value (const_tree ret_type, + const_tree fntype_or_decl, + bool outgoing ATTRIBUTE_UNUSED) +{ + enum machine_mode mode; + int unsignedp; + + mode = TYPE_MODE (ret_type); + if (INTEGRAL_TYPE_P (ret_type)) + mode = promote_function_mode (ret_type, mode, &unsignedp, + fntype_or_decl, 1); + + return gen_rtx_REG (mode, BPF_R0); +} + +#undef TARGET_FUNCTION_VALUE +#define TARGET_FUNCTION_VALUE bpf_function_value + +/* Return true if REGNO is the number of a hard register in which the + values of called function may come back. */ + +static bool +bpf_function_value_regno_p (const unsigned int regno) +{ + return (regno == BPF_R0); +} + +#undef TARGET_FUNCTION_VALUE_REGNO_P +#define TARGET_FUNCTION_VALUE_REGNO_P bpf_function_value_regno_p + +/* Compute the size of the function's stack frame, including the local + area and the register-save area. */ + +static void +bpf_compute_frame_layout (void) +{ + int stack_alignment = STACK_BOUNDARY / BITS_PER_UNIT; + int padding_locals, regno; + + /* Set the space used in the stack by local variables. This is + rounded up to respect the minimum stack alignment. */ + cfun->machine->local_vars_size = get_frame_size (); + + padding_locals = cfun->machine->local_vars_size % stack_alignment; + if (padding_locals) + padding_locals = stack_alignment - padding_locals; + + cfun->machine->local_vars_size += padding_locals; + + /* Set the space used in the stack by callee-saved used registers in + the current function. There is no need to round up, since the + registers are all 8 bytes wide. */ + for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) + if ((!fixed_regs[regno] + && df_regs_ever_live_p (regno) + && !call_used_regs[regno]) + || (cfun->calls_alloca + && regno == STACK_POINTER_REGNUM)) + cfun->machine->callee_saved_reg_size += 8; + + /* Check that the total size of the frame doesn't exceed the limit + imposed by eBPF. */ + if ((cfun->machine->local_vars_size + + cfun->machine->callee_saved_reg_size) > bpf_frame_limit) + { + static int stack_limit_exceeded = 0; + + if (!stack_limit_exceeded) + error ("eBPF stack limit exceeded"); + stack_limit_exceeded = 1; + } +} + +#undef TARGET_COMPUTE_FRAME_LAYOUT +#define TARGET_COMPUTE_FRAME_LAYOUT bpf_compute_frame_layout + +/* Expand to the instructions in a function prologue. This function + is called when expanding the 'prologue' pattern in bpf.md. */ + +void +bpf_expand_prologue (void) +{ + int regno, fp_offset; + rtx insn; + HOST_WIDE_INT size; + + size = (cfun->machine->local_vars_size + + cfun->machine->callee_saved_reg_size); + fp_offset = -cfun->machine->local_vars_size; + + /* Save callee-saved hard registes. The register-save-area starts + right after the local variables. */ + for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) + { + if ((!fixed_regs[regno] + && df_regs_ever_live_p (regno) + && !call_used_regs[regno]) + || (cfun->calls_alloca + && regno == STACK_POINTER_REGNUM)) + { + rtx mem; + + if (!IN_RANGE (fp_offset, -1 - 0x7fff, 0x7fff)) + /* This has been already reported as an error in + bpf_compute_frame_layout. */ + break; + else + { + mem = gen_frame_mem (DImode, + plus_constant (DImode, + hard_frame_pointer_rtx, + fp_offset - 8)); + insn = emit_move_insn (mem, gen_rtx_REG (DImode, regno)); + RTX_FRAME_RELATED_P (insn) = 1; + fp_offset -= 8; + } + } + } + + /* Set the stack pointer, if the function allocates space + dynamically. Note that the value of %sp should be directly + derived from %fp, for the kernel verifier to track it as a stack + accessor. */ + if (cfun->calls_alloca) + { + insn = emit_move_insn (stack_pointer_rtx, + hard_frame_pointer_rtx); + RTX_FRAME_RELATED_P (insn) = 1; + + if (size > 0) + { + insn = emit_insn (gen_rtx_SET (stack_pointer_rtx, + gen_rtx_PLUS (Pmode, + stack_pointer_rtx, + GEN_INT (-size)))); + RTX_FRAME_RELATED_P (insn) = 1; + } + } +} + +/* Expand to the instructions in a function epilogue. This function + is called when expanding the 'epilogue' pattern in bpf.md. */ + +void +bpf_expand_epilogue (void) +{ + int regno, fp_offset; + rtx insn; + + fp_offset = -cfun->machine->local_vars_size; + + /* Restore callee-saved hard registes from the stack. */ + for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) + { + if ((!fixed_regs[regno] + && df_regs_ever_live_p (regno) + && !call_used_regs[regno]) + || (cfun->calls_alloca + && regno == STACK_POINTER_REGNUM)) + { + rtx mem; + + if (!IN_RANGE (fp_offset, -1 - 0x7fff, 0x7fff)) + /* This has been already reported as an error in + bpf_compute_frame_layout. */ + break; + else + { + mem = gen_frame_mem (DImode, + plus_constant (DImode, + hard_frame_pointer_rtx, + fp_offset - 8)); + insn = emit_move_insn (gen_rtx_REG (DImode, regno), mem); + RTX_FRAME_RELATED_P (insn) = 1; + fp_offset -= 8; + } + } + } + + emit_jump_insn (gen_exit ()); +} + +/* Return the initial difference between the specified pair of + registers. The registers that can figure in FROM, and TO, are + specified by ELIMINABLE_REGS in bpf.h. + + This function is used in the definition of + INITIAL_ELIMINATION_OFFSET in bpf.h */ + +HOST_WIDE_INT +bpf_initial_elimination_offset (int from, int to) +{ + HOST_WIDE_INT ret; + + if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM) + ret = (cfun->machine->local_vars_size + + cfun->machine->callee_saved_reg_size); + else if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM) + ret = 0; + else + gcc_unreachable (); + + return ret; +} + +/* Return the number of consecutive hard registers, starting at + register number REGNO, required to hold a value of mode MODE. */ + +static unsigned int +bpf_hard_regno_nregs (unsigned int regno ATTRIBUTE_UNUSED, + enum machine_mode mode) +{ + return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD); +} + +#undef TARGET_HARD_REGNO_NREGS +#define TARGET_HARD_REGNO_NREGS bpf_hard_regno_nregs + +/* Return true if it is permissible to store a value of mode MODE in + hard register number REGNO, or in several registers starting with + that one. */ + +static bool +bpf_hard_regno_mode_ok (unsigned int regno ATTRIBUTE_UNUSED, + enum machine_mode mode) +{ + switch (mode) + { + case E_SImode: + case E_DImode: + case E_HImode: + case E_QImode: + case E_TImode: + case E_SFmode: + case E_DFmode: + return true; + default: + return false; + } +} + +#undef TARGET_HARD_REGNO_MODE_OK +#define TARGET_HARD_REGNO_MODE_OK bpf_hard_regno_mode_ok + +/* Return true if a function must have and use a frame pointer. */ + +static bool +bpf_frame_pointer_required (void) +{ + /* We do not have a stack pointer, so we absolutely depend on the + frame-pointer in order to access the stack... and fishes walk and + pigs fly glglgl */ + return true; +} + +#undef TARGET_FRAME_POINTER_REQUIRED +#define TARGET_FRAME_POINTER_REQUIRED bpf_frame_pointer_required + +/* Return `true' if the given RTX X is a valid base for an indirect + memory access. STRICT has the same meaning than in + bpf_legitimate_address_p. */ + +static inline bool +bpf_address_base_p (rtx x, bool strict) +{ + return (GET_CODE (x) == REG + && (REGNO (x) < 11 + || (!strict && REGNO (x) >= FIRST_PSEUDO_REGISTER))); +} + +/* Return true if X (a RTX) is a legitimate memory address on the + target machine for a memory operand of mode MODE. */ + +static bool +bpf_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED, + rtx x, + bool strict) +{ + switch (GET_CODE (x)) + { + case REG: + return bpf_address_base_p (x, strict); + + case PLUS: + { + /* Accept (PLUS ADDR_BASE CONST_INT), provided CONST_INT fits + in a signed 16-bit. + + Note that LABEL_REF and SYMBOL_REF are not allowed in + REG+IMM addresses, because it is almost certain they will + overload the offset field. */ + + rtx x0 = XEXP (x, 0); + rtx x1 = XEXP (x, 1); + + if (bpf_address_base_p (x0, strict) && GET_CODE (x1) == CONST_INT) + return IN_RANGE (INTVAL (x1), -1 - 0x7fff, 0x7fff); + + break; + } + default: + break; + } + + return false; +} + +#undef TARGET_LEGITIMATE_ADDRESS_P +#define TARGET_LEGITIMATE_ADDRESS_P bpf_legitimate_address_p + +/* Describe the relative costs of RTL expressions. Return true when + all subexpressions of X have been processed, and false when + `rtx_cost' should recurse. */ + +static bool +bpf_rtx_costs (rtx x ATTRIBUTE_UNUSED, + enum machine_mode mode ATTRIBUTE_UNUSED, + int outer_code ATTRIBUTE_UNUSED, + int opno ATTRIBUTE_UNUSED, + int *total ATTRIBUTE_UNUSED, + bool speed ATTRIBUTE_UNUSED) +{ + /* To be written. */ + return false; +} + +#undef TARGET_RTX_COSTS +#define TARGET_RTX_COSTS bpf_rtx_costs + +/* Return true if an argument at the position indicated by CUM should + be passed by reference. If the hook returns true, a copy of that + argument is made in memory and a pointer to the argument is passed + instead of the argument itself. */ + +static bool +bpf_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, + const function_arg_info &arg) +{ + unsigned num_bytes = arg.type_size_in_bytes (); + + /* Pass aggregates and values bigger than 5 words by reference. + Everything else is passed by copy. */ + return (arg.aggregate_type_p () || (num_bytes > 8*5)); +} + +#undef TARGET_PASS_BY_REFERENCE +#define TARGET_PASS_BY_REFERENCE bpf_pass_by_reference + +/* Return a RTX indicating whether a function argument is passed in a + register and if so, which register. */ + +static rtx +bpf_function_arg (cumulative_args_t ca, const function_arg_info &arg) +{ + CUMULATIVE_ARGS *cum = get_cumulative_args (ca); + + if (*cum < 5) + return gen_rtx_REG (arg.mode, *cum + 1); + else + /* An error will be emitted for this in + bpf_function_arg_advance. */ + return NULL_RTX; +} + +#undef TARGET_FUNCTION_ARG +#define TARGET_FUNCTION_ARG bpf_function_arg + +/* Update the summarizer variable pointed by CA to advance past an + argument in the argument list. */ + +static void +bpf_function_arg_advance (cumulative_args_t ca, + const function_arg_info &arg) +{ + CUMULATIVE_ARGS *cum = get_cumulative_args (ca); + unsigned num_bytes = arg.type_size_in_bytes (); + unsigned num_words = CEIL (num_bytes, UNITS_PER_WORD); + + if (*cum <= 5 && *cum + num_words > 5) + error ("too many function arguments for eBPF"); + + *cum += num_words; +} + +#undef TARGET_FUNCTION_ARG_ADVANCE +#define TARGET_FUNCTION_ARG_ADVANCE bpf_function_arg_advance + +/* Output the assembly code for a constructor. Since eBPF doesn't + support indirect calls, constructors are not supported. */ + +static void +bpf_output_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED) +{ + tree decl = SYMBOL_REF_DECL (symbol); + + if (decl) + sorry_at (DECL_SOURCE_LOCATION (decl), + "no constructors"); + else + sorry ("no constructors"); +} + +#undef TARGET_ASM_CONSTRUCTOR +#define TARGET_ASM_CONSTRUCTOR bpf_output_constructor + +/* Output the assembly code for a destructor. Since eBPF doesn't + support indirect calls, destructors are not supported. */ + +static void +bpf_output_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED) +{ + tree decl = SYMBOL_REF_DECL (symbol); + + if (decl) + sorry_at (DECL_SOURCE_LOCATION (decl), + "no destructors"); + else + sorry ("no destructors"); +} + +#undef TARGET_ASM_DESTRUCTOR +#define TARGET_ASM_DESTRUCTOR bpf_output_destructor + +/* Return the appropriate instruction to CALL to a function. TARGET + is an RTX denoting the address of the called function. + + The main purposes of this function are: + - To reject indirect CALL instructions, which are not supported by + eBPF. + - To recognize calls to kernel helper functions and emit the + corresponding CALL N instruction. + + This function is called from the expansion of the 'call' pattern in + bpf.md. */ + +const char * +bpf_output_call (rtx target) +{ + rtx xops[1]; + + switch (GET_CODE (target)) + { + case CONST_INT: + output_asm_insn ("call\t%0", &target); + break; + case SYMBOL_REF: + { + const char *function_name = XSTR (target, 0); + int code; + + if (strncmp (function_name, "__builtin_bpf_helper_", 21) == 0 + && ((code = bpf_helper_code (function_name + 21)) != 0)) + { + xops[0] = GEN_INT (code); + output_asm_insn ("call\t%0", xops); + } + else + output_asm_insn ("call\t%0", &target); + + break; + } + default: + error ("indirect call in function, which are not supported by eBPF"); + output_asm_insn ("call 0", NULL); + break; + } + + return ""; +} + +/* Print an instruction operand. This function is called in the macro + PRINT_OPERAND defined in bpf.h */ + +void +bpf_print_operand (FILE *file, rtx op, int code ATTRIBUTE_UNUSED) +{ + switch (GET_CODE (op)) + { + case REG: + fprintf (file, "%s", reg_names[REGNO (op)]); + break; + case MEM: + output_address (GET_MODE (op), XEXP (op, 0)); + break; + case CONST_DOUBLE: + if (CONST_DOUBLE_HIGH (op)) + fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX, + CONST_DOUBLE_HIGH (op), CONST_DOUBLE_LOW (op)); + else if (CONST_DOUBLE_LOW (op) < 0) + fprintf (file, HOST_WIDE_INT_PRINT_HEX, CONST_DOUBLE_LOW (op)); + else + fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (op)); + break; + default: + output_addr_const (file, op); + } +} + +/* Print an operand which is an address. This function should handle + any legit address, as accepted by bpf_legitimate_address_p, and + also addresses that are valid in CALL instructions. + + This function is called in the PRINT_OPERAND_ADDRESS macro defined + in bpf.h */ + +void +bpf_print_operand_address (FILE *file, rtx addr) +{ + switch (GET_CODE (addr)) + { + case REG: + fprintf (file, "[%s+0]", reg_names[REGNO (addr)]); + break; + case PLUS: + { + rtx op0 = XEXP (addr, 0); + rtx op1 = XEXP (addr, 1); + + if (GET_CODE (op0) == REG && GET_CODE (op1) == CONST_INT) + { + fprintf (file, "[%s+", reg_names[REGNO (op0)]); + output_addr_const (file, op1); + fputs ("]", file); + } + else + fatal_insn ("invalid address in operand", addr); + break; + } + case MEM: + /* Fallthrough. */ + case LABEL_REF: + /* Fallthrough. */ + fatal_insn ("unsupported operand", addr); + break; + default: + output_addr_const (file, addr); + break; + } +} + +/* Add a BPF builtin function with NAME, CODE and TYPE. Return + the function decl or NULL_TREE if the builtin was not added. */ + +static tree +def_builtin (const char *name, enum bpf_builtins code, tree type) +{ + tree t + = add_builtin_function (name, type, code, BUILT_IN_MD, NULL, NULL_TREE); + + bpf_builtins[code] = t; + return t; +} + +/* Define machine-specific built-in functions. */ + +static void +bpf_init_builtins (void) +{ + /* Built-ins for calling kernel helpers. */ + + tree pt = build_pointer_type (void_type_node); + tree const_void_type + = build_qualified_type (void_type_node, TYPE_QUAL_CONST); + tree cpt = build_pointer_type (const_void_type); + tree st = short_integer_type_node; + tree ust = uint16_type_node; + tree it = integer_type_node; + tree ut = unsigned_type_node; + tree const_char_type + = build_qualified_type (char_type_node, TYPE_QUAL_CONST); + tree cst = build_pointer_type (const_char_type); + tree vt = void_type_node; + tree ult = long_unsigned_type_node; + tree u32t = uint32_type_node; + tree u64t = uint64_type_node; + tree llt = long_long_integer_type_node; + tree ullt = long_long_unsigned_type_node; + +#define TYPES build_function_type_list +#define VTYPES build_varargs_function_type_list +#define DEF_HELPER(V,D,N,T) \ + do \ + { \ + if (bpf_kernel >= (V)) \ + def_builtin ("__builtin_bpf_helper_" #N, \ + BPF_BUILTIN_HELPER_##D, \ + T); \ + } while (0); +# include "bpf-helpers.def" +#undef TYPES +#undef VTYPES +#undef DEF_HELPER + + /* Built-ins for BPF_LD_ABS and BPF_LD_IND instructions. */ + + def_builtin ("__builtin_bpf_load_byte", BPF_BUILTIN_LOAD_BYTE, + build_function_type_list (ullt, ullt, 0)); + def_builtin ("__builtin_bpf_load_half", BPF_BUILTIN_LOAD_HALF, + build_function_type_list (ullt, ullt, 0)); + def_builtin ("__builtin_bpf_load_word", BPF_BUILTIN_LOAD_WORD, + build_function_type_list (ullt, ullt, 0)); +} + +#undef TARGET_INIT_BUILTINS +#define TARGET_INIT_BUILTINS bpf_init_builtins + +/* Expand a call to a BPF-specific built-in function that was set up + with bpf_init_builtins. */ + +static rtx +bpf_expand_builtin (tree exp, rtx target, + rtx subtarget ATTRIBUTE_UNUSED, + machine_mode mode ATTRIBUTE_UNUSED, + int ignore) +{ + tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); + int code = DECL_MD_FUNCTION_CODE (fndecl); + + if (code >= 1 && code < BPF_BUILTIN_HELPER_MAX) + { + /* This is a builtin to call a kernel helper function. + + For these builtins, we just expand the function call normally + with expand_call like we would do for a libcall. The function + bpf_output_call below will then do The Right Thing (TM), + recognizing the name of the called __builtin_helper_* symbol + and emitting the corresponding CALL N instruction whenever + necessary. */ + + return expand_call (exp, target, ignore); + } + else if (code == BPF_BUILTIN_LOAD_BYTE + || code == BPF_BUILTIN_LOAD_HALF + || code == BPF_BUILTIN_LOAD_WORD) + { + /* Expand an indirect load from the sk_buff in the context. + There is just one argument to the builtin, which is the + offset. + + We try first to expand a ldabs* instruction. In case this + fails, we try a ldind* instruction. */ + + enum insn_code abs_icode + = (code == BPF_BUILTIN_LOAD_BYTE ? CODE_FOR_ldabsb + : code == BPF_BUILTIN_LOAD_HALF ? CODE_FOR_ldabsh + : CODE_FOR_ldabsw); + + enum insn_code ind_icode + = (code == BPF_BUILTIN_LOAD_BYTE ? CODE_FOR_ldindb + : code == BPF_BUILTIN_LOAD_HALF ? CODE_FOR_ldindh + : CODE_FOR_ldindw); + + tree offset_arg = CALL_EXPR_ARG (exp, 0); + struct expand_operand ops[2]; + + create_input_operand (&ops[0], expand_normal (offset_arg), + TYPE_MODE (TREE_TYPE (offset_arg))); + create_input_operand (&ops[1], const0_rtx, SImode); + + if (!maybe_expand_insn (abs_icode, 2, ops) + && !maybe_expand_insn (ind_icode, 2, ops)) + { + error ("invalid argument to built-in function"); + return gen_rtx_REG (ops[0].mode, BPF_R0); + } + + /* The result of the load is in R0. */ + return gen_rtx_REG (ops[0].mode, BPF_R0); + } + + gcc_unreachable (); +} + +#undef TARGET_EXPAND_BUILTIN +#define TARGET_EXPAND_BUILTIN bpf_expand_builtin + +/* Initialize target-specific function library calls. This is mainly + used to call library-provided soft-fp operations, since eBPF + doesn't support floating-point in "hardware". */ + +static void +bpf_init_libfuncs (void) +{ + set_conv_libfunc (sext_optab, DFmode, SFmode, + "__bpf_extendsfdf2"); + set_conv_libfunc (trunc_optab, SFmode, DFmode, + "__bpf_truncdfsf2"); + set_conv_libfunc (sfix_optab, SImode, DFmode, + "__bpf_fix_truncdfsi"); + set_conv_libfunc (sfloat_optab, DFmode, SImode, + "__bpf_floatsidf"); + set_conv_libfunc (ufloat_optab, DFmode, SImode, + "__bpf_floatunsidf"); +} + +#undef TARGET_INIT_LIBFUNCS +#define TARGET_INIT_LIBFUNCS bpf_init_libfuncs + +/* Define the mechanism that will be used for describing frame unwind + information to the debugger. In eBPF it is not possible to unwind + frames. */ + +static enum unwind_info_type +bpf_debug_unwind_info () +{ + return UI_NONE; +} + +#undef TARGET_DEBUG_UNWIND_INFO +#define TARGET_DEBUG_UNWIND_INFO bpf_debug_unwind_info + +/* Output assembly directives to assemble data of various sized and + alignments. */ + +#undef TARGET_ASM_BYTE_OP +#define TARGET_ASM_BYTE_OP "\t.byte\t" +#undef TARGET_ASM_ALIGNED_HI_OP +#define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" +#undef TARGET_ASM_ALIGNED_SI_OP +#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t" +#undef TARGET_ASM_ALIGNED_DI_OP +#define TARGET_ASM_ALIGNED_DI_OP "\t.dword\t" + +/* Finally, build the GCC target. */ + +struct gcc_target targetm = TARGET_INITIALIZER; + +#include "gt-bpf.h" diff --git a/gcc/config/bpf/bpf.h b/gcc/config/bpf/bpf.h new file mode 100644 index 0000000..70ad818 --- /dev/null +++ b/gcc/config/bpf/bpf.h @@ -0,0 +1,539 @@ +/* Definition of the eBPF target for GCC. + Copyright (C) 2019 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +#ifndef GCC_BPF_H +#define GCC_BPF_H + +/**** Controlling the Compilation Driver. */ + +#define ASM_SPEC "%{mbig-endian:-EB} %{!mbig-endian:-EL}" +#define LINK_SPEC "%{mbig-endian:-EB} %{!mbig-endian:-EL}" +#define LIB_SPEC "" +#define STARTFILE_SPEC "" + +/**** Run-time Target Specification. */ + +#define TARGET_CPU_CPP_BUILTINS() bpf_target_macros (pfile) + +/**** Storage Layout. */ + +/* Endianness and word size. */ +#define BITS_BIG_ENDIAN 0 +#define BYTES_BIG_ENDIAN (TARGET_BIG_ENDIAN) +#define WORDS_BIG_ENDIAN (TARGET_BIG_ENDIAN) +#define BITS_PER_WORD 64 +#define UNITS_PER_WORD 8 + +/* When storing an integer whose size is less than 64-bit in a + register, promote it to a DImode. */ +#define PROMOTE_MODE(M, UNSIGNEDP, TYPE) \ + do \ + { \ + if (GET_MODE_CLASS (M) == MODE_INT \ + && GET_MODE_SIZE (M) < 8) \ + M = DImode; \ + } while (0) + +/* Biggest alignment supported by the object file format of this + machine. In this case this is ELF. Use the same definition than + in elfos.h */ +#define MAX_OFILE_ALIGNMENT (((unsigned int) 1 << 28) * 8) + +/* Align argument parameters on the stack to 64-bit, at a minimum. */ +#define PARM_BOUNDARY 64 + +/* The hardware enforces that the stack pointer should be aligned to + 64-bit at any time. */ +#define STACK_BOUNDARY 64 + +/* Function entry points are aligned to 128 bits. */ +#define FUNCTION_BOUNDARY 128 + +/* Maximum alignment required by data of any type. */ +#define BIGGEST_ALIGNMENT 64 + +/* The best alignment to use in cases where we have a choice. */ +#define FASTEST_ALIGNMENT 64 + +/* Use a fast alignment when storing arrays of chars in a local. */ +#define LOCAL_ALIGNMENT(TYPE, ALIGN) \ + (TREE_CODE (TYPE) == ARRAY_TYPE \ + && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \ + && (ALIGN) < FASTEST_ALIGNMENT ? FASTEST_ALIGNMENT : (ALIGN)) + +/* The load and store instructions won't work if the data is not in + it's expected alignment. */ +#define STRICT_ALIGNMENT 1 + +/* We use Pmode as the mode of the size increment operand in an + `allocate_stack' pattern. */ +#define STACK_SIZE_MODE Pmode + +/**** Layout of Source Language Data Types. */ + +#define INT_TYPE_SIZE 32 +#define SHORT_TYPE_SIZE 16 +#define LONG_TYPE_SIZE 64 +#define LONG_LONG_TYPE_SIZE 64 +#define CHAR_TYPE_SIZE 8 +#define FLOAT_TYPE_SIZE 32 +#define DOUBLE_TYPE_SIZE 64 +#define LONG_DOUBLE_TYPE_SIZE 64 + +#define INTPTR_TYPE "long int" +#define UINTPTR_TYPE "long unsigned int" +#define SIZE_TYPE "long unsigned int" +#define PTRDIFF_TYPE "long int" + +#define SIG_ATOMIC_TYPE "char" + +#define INT8_TYPE "char" +#define INT16_TYPE "short int" +#define INT32_TYPE "int" +#define INT64_TYPE "long int" +#define UINT8_TYPE "unsigned char" +#define UINT16_TYPE "short unsigned int" +#define UINT32_TYPE "unsigned int" +#define UINT64_TYPE "long unsigned int" + +#define INT_LEAST8_TYPE INT8_TYPE +#define INT_LEAST16_TYPE INT16_TYPE +#define INT_LEAST32_TYPE INT32_TYPE +#define INT_LEAST64_TYPE INT64_TYPE +#define UINT_LEAST8_TYPE UINT8_TYPE +#define UINT_LEAST16_TYPE UINT16_TYPE +#define UINT_LEAST32_TYPE UINT32_TYPE +#define UINT_LEAST64_TYPE UINT64_TYPE + +#define INT_FAST8_TYPE INT8_TYPE +#define INT_FAST16_TYPE INT16_TYPE +#define INT_FAST32_TYPE INT32_TYPE +#define INT_FAST64_TYPE INT64_TYPE +#define UINT_FAST8_TYPE UINT8_TYPE +#define UINT_FAST16_TYPE UINT16_TYPE +#define UINT_FAST32_TYPE UINT32_TYPE +#define UINT_FAST64_TYPE UINT64_TYPE + +/* `char' is signed by default, like in x86. */ +#define DEFAULT_SIGNED_CHAR 1 + +/* `wchar_t' is a signed 32-bit type. The second constant is used by + cpp, which can't use WCHAR_TYPE. */ +#define WCHAR_TYPE "int" +#define WCHAR_TYPE_SIZE 32 + +/* `wint_t' is a signed 32-bit type. */ +#define WINT_TYPE "int" +#define WINT_TYPE_SIZE 32 + +/**** Register Usage. */ + +/*** Basic Characteristics of Registers. */ + +#define BPF_R0 0 +#define BPF_R1 1 +#define BPF_R2 2 +#define BPF_R3 3 +#define BPF_R4 4 +#define BPF_R5 5 +#define BPF_R6 6 +#define BPF_CTX BPF_R6 +#define BPF_R7 7 +#define BPF_R8 8 +#define BPF_R9 9 +#define BPF_SP BPF_R9 +#define BPF_R10 10 +#define BPF_FP BPF_R10 +/* 11 is not a real eBPF hard register and is eliminated or not used + in the final assembler. See below. */ + +#define FIRST_PSEUDO_REGISTER 12 + +/* The registers %r0..%r8 are available for general allocation. + %r9 is the pseudo-stack pointer. + %r10 is the stack frame, which is read-only. + %r11 (__arg__) is a fake register that always gets eliminated. */ +#define FIXED_REGISTERS \ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1} + +/* %r0..%r5 are clobbered by function calls. */ +#define CALL_USED_REGISTERS \ + {1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1} + +/**** Register Classes. */ + +enum reg_class +{ + NO_REGS, /* no registers in set. */ + ALL_REGS, /* all registers. */ + LIM_REG_CLASSES /* max value + 1. */ +}; + +#define N_REG_CLASSES (int) LIM_REG_CLASSES +#define GENERAL_REGS ALL_REGS + +/* An initializer containing the names of the register classes as C + string constants. These names are used in writing some of the + debugging dumps. */ +#define REG_CLASS_NAMES \ +{ \ + "NO_REGS", \ + "ALL_REGS" \ +} + +/* An initializer containing the contents of the register classes, as + integers which are bit masks. The Nth integer specifies the + contents of class N. The way the integer MASK is interpreted is + that register R is in the class if `MASK & (1 << R)' is 1. + + In eBPF all the hard registers are considered general-purpose + integer registers. */ +#define REG_CLASS_CONTENTS \ +{ \ + 0x00000000, /* NO_REGS */ \ + 0x00000fff, /* ALL_REGS */ \ +} + +/* A C expression whose value is a register class containing hard + register REGNO. In general there is more that one such class; + choose a class which is "minimal", meaning that no smaller class + also contains the register. */ +#define REGNO_REG_CLASS(REGNO) GENERAL_REGS + +/* A macro whose definition is the name of the class to which a + valid base register must belong. A base register is one used in + an address which is the register value plus a displacement. */ +#define BASE_REG_CLASS GENERAL_REGS + +/* A macro whose definition is the name of the class to which a + valid index register must belong. An index register is one used + in an address where its value is either multiplied by a scale + factor or added to another register (as well as added to a + displacement). */ +#define INDEX_REG_CLASS NO_REGS + +/* C expression which is nonzero if register number REGNO is suitable + for use as a base register in operand addresses. In eBPF every + hard register can be used for this purpose. */ +#define REGNO_OK_FOR_BASE_P(REGNO) \ + ((REGNO) < FIRST_PSEUDO_REGISTER) + +/* C expression which is nonzero if register number REGNO is suitable + for use as an index register in operand addresses. */ +#define REGNO_OK_FOR_INDEX_P(REGNO) false + +/**** Debugging Info ****/ + +/* We cannot support DWARF2 because of the limitations of eBPF. */ +#define DBX_DEBUGGING_INFO + +/**** Stack Layout and Calling Conventions. */ + +/*** Basic Stack Layout. */ + +#define STACK_GROWS_DOWNWARD 1 +#define FRAME_GROWS_DOWNWARD 1 + +/* The argument pointer always points to the first argument. */ +#define FIRST_PARM_OFFSET(FNDECL) 0 + +/* Unsupported. */ +#define RETURN_ADDR_RTX(count, frame) const0_rtx + +/*** Registers That Address the Stack Frame. */ + +#define FRAME_POINTER_REGNUM 10 +#define STACK_POINTER_REGNUM 9 +#define ARG_POINTER_REGNUM 11 +#define STATIC_CHAIN_REGNUM 8 + +/*** Registers elimination. */ + +#define ELIMINABLE_REGS \ + {{ ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM }, \ + { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }} + +/* Define the offset between two registers, one to be eliminated, and + the other its replacement, at the start of a routine. */ +#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ + do \ + { \ + (OFFSET) = bpf_initial_elimination_offset ((FROM), (TO)); \ + } while (0) + +/*** Passing Function Arguments on the Stack. */ + +/* The eBPF ABI doesn't support passing arguments on the stack. Only + in the first five registers. Code in bpf.c assures the stack is + never used when passing arguments. However, we still have to + define the constants below. */ + +/* If nonzero, push insns will be used to pass outgoing arguments. */ +#define PUSH_ARGS 0 + +/* If nonzero, function arguments will be evaluated from last to + first, rather than from first to last. */ +#define PUSH_ARGS_REVERSED 1 + +/* Allocate stack space for arguments at the beginning of each + function. */ +#define ACCUMULATE_OUTGOING_ARGS 1 + +/*** Passing Arguments in Registers. */ + +/* Use an integer in order to keep track of the number of arguments + passed to a function in integer registers, up to + MAX_ARGS_IN_REGISTERS. */ +#define CUMULATIVE_ARGS int + +/* INIT_CUMULATIVE_ARGS initializes a variable CUM of type + CUMULATIVE_ARGS for a call to a function whose data type is FNTYPE. + For a library call, FNTYPE is 0. */ +#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,FNDECL,N_NAMED_ARGS) \ + memset (&(CUM), 0, sizeof (CUM)) + +/* Nonzero if N is the number of a hard register in which function + arguments are sometimes passed. */ +#define FUNCTION_ARG_REGNO_P(N) ((N) >= 1 && (N) <= 5) + +/*** How Scalar Function Values are Returned. */ + +/* Define how to find the value returned by a library function + assuming the value has mode MODE. This is always %r0 for eBPF. */ +#define LIBCALL_VALUE(MODE) \ + gen_rtx_REG ((MODE), 0) + +/*** Generating Code for Profiling. */ + +/* We do not support profiling yet, so do not call `mcount'. */ +#define FUNCTION_PROFILER(FILE, LABELNO) do { } while (0) + +/*** Function Entry and Exit. */ + +/* We do not require an accurate stack pointer at function return. + This is because the stack pointer's original value is initialized + from the frame pointer, rather than decreased, to satisfy the + kernel's verifier. Thus, we have to save the stack pointer in + function prologue and restore it in function epilogue. If + EXIT_IGNORE_STACK is not set, then superfluous instructions are + generated to save and restore the stack pointer after and before + the function epilogue, respectively. */ +#define EXIT_IGNORE_STACK 1 + +/**** Support for Nested Functions. */ + +/* We have to define TRAMPOLINE_SIZE even if we don't ever generate + them. Set to 64 arbitrarily. */ +#define TRAMPOLINE_SIZE 64 + +/**** Addressing Modes. */ + +/* Maximum number of registers that can appear in a valid memory + address. */ +#define MAX_REGS_PER_ADDRESS 1 + +/* 1 if X is an rtx for a constant that is a valid address. */ + +#define CONSTANT_ADDRESS_P(X) 0 + +/**** Describing Relative Costs of Operations. */ + +/* Cost of a branch instruction. A value of 1 is the default. */ +#define BRANCH_COST(SPEED_P,PREDICTABLE_P) 1 + +/* The SPARC port says: Nonzero if access to memory by bytes is slow + and undesirable. For RISC chips, it means that access to memory by + bytes is no better than access by words when possible, so grab a + whole word and maybe make use of that. */ +#define SLOW_BYTE_ACCESS 1 + +/* Threshold of number of scalar memory-to-memory move instructions, + _below_ which a sequence of insns should be generated instead of a + string move insn or a library call. */ +#define MOVE_RATIO(speed) 128 + +/* Threshold of number of scalar move instructions, _below_ which a + sequence of insns should be generated to clear memory instead of a + string clear insn or a library call. */ +#define CLEAR_RATIO(speed) 128 + +/* Threshold of number of scalar move instructions, _below_ which a + sequence of insns should be generated to set memory to a constant + value, instead of a block set insn or a library call. */ +#define SET_RATIO(speed) 128 + +/* True if it is as good or better to call a constant function address + than to call an address kept in a register. */ +#define NO_FUNCTION_CSE 1 + +/**** Dividing the Output into Sections. */ + +#define TEXT_SECTION_ASM_OP "\t.text" +#define DATA_SECTION_ASM_OP "\t.data" +#define BSS_SECTION_ASM_OP "\t.bss" +#define COMMON_ASM_OP "\t.common\t" + +/**** Defining the Output Assembler Language. */ + +/*** The Overall Framework of an Assembler File. */ + +#define ASM_COMMENT_START ";" + +/* Output to assembler file text saying following lines + may contain character constants, extra white space, comments, etc. */ + +#ifndef ASM_APP_ON +#define ASM_APP_ON " #APP\n" +#endif + +/* Output to assembler file text saying following lines + no longer contain unusual constructs. */ + +#ifndef ASM_APP_OFF +#define ASM_APP_OFF " #NO_APP\n" +#endif + +/*** Output of Data. */ + +/*** Output of Uninitialized Variables. */ + +/* How to output an assembler line to define a local common + symbol. */ + +#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \ + do \ + { \ + fprintf ((FILE), "%s", COMMON_ASM_OP); \ + assemble_name ((FILE), (NAME)); \ + fprintf ((FILE), ",%u,%u\n", (int)(SIZE), (ALIGN) / (BITS_PER_UNIT)); \ + } \ + while (0) + +/* A C statement (sans semicolon) to output to the stdio stream + FILE the assembler definition of uninitialized global DECL named + NAME whose size is SIZE bytes and alignment is ALIGN bytes. + Try to use asm_output_aligned_bss to implement this macro. */ + +#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ + do { \ + ASM_OUTPUT_ALIGNED_LOCAL (FILE, NAME, SIZE, ALIGN); \ + } while (0) + +/* This says how to output an assembler line to define a local common + symbol. */ + +#define ASM_OUTPUT_ALIGNED_LOCAL(FILE,NAME,SIZE,ALIGN) \ + ( fputs ("\t.lcomm ", (FILE)), \ + assemble_name ((FILE), (NAME)), \ + fprintf ((FILE), "," HOST_WIDE_INT_PRINT_UNSIGNED "\n", \ + (SIZE), ((ALIGN) / BITS_PER_UNIT))) + +/*** Output and Generation of Labels. */ + +/* Globalizing directive for a label. */ +#define GLOBAL_ASM_OP "\t.global\t" + +/* This is how to store into the string LABEL + the symbol_ref name of an internal numbered label where + PREFIX is the class of label and NUM is the number within the class. + This is suitable for output with `assemble_name'. */ + +#undef ASM_GENERATE_INTERNAL_LABEL +#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \ + sprintf ((LABEL), "*%s%s%ld", (LOCAL_LABEL_PREFIX), (PREFIX), (long)(NUM)) + +/*** Macros Controlling Initialization Routines. */ + +#define INIT_SECTION_ASM_OP "\t.init" +#define FINI_SECTION_ASM_OP "\t.fini" + +/*** Output of Assembler Instructions. */ + +#define REGISTER_NAMES \ + { "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", \ + "%r8", "%r9", "%fp", "__arg__" } + +#define ADDITIONAL_REGISTER_NAMES \ + { { "%a", 0 }, { "%ctx", 6 }, { "%r10" , 10 } } + +#define LOCAL_LABEL_PREFIX "." +#define USER_LABEL_PREFIX "" + +#define PRINT_OPERAND(STREAM,X,CODE) \ + bpf_print_operand ((STREAM),(X),(CODE)) + +#define PRINT_OPERAND_ADDRESS(STREAM,X) \ + bpf_print_operand_address ((STREAM), (X)) + +/*** Assembler Commands for Alignment. */ + +/* This is how to output an assembler line that says to advance the + location counter to a multiple of 2**LOG bytes. */ +#define ASM_OUTPUT_ALIGN(STREAM,LOG) \ + fprintf (STREAM, "\t.align\t%d\n", (LOG)) + +/* This is how to output an assembler line + that says to advance the location counter by SIZE bytes. */ +#define ASM_OUTPUT_SKIP(FILE,SIZE) \ + fprintf (FILE, "\t.skip\t" HOST_WIDE_INT_PRINT_UNSIGNED "\n", (SIZE)) + +/**** Miscellaneous Parameters. */ + +/* Specify the machine mode that this machine uses for the index in + the tablejump instruction. */ +#define CASE_VECTOR_MODE DImode + +/* Define if operations between registers with integral mode smaller + than a word are always performed on the entire register. */ +#define WORD_REGISTER_OPERATIONS 1 + +/* C expression indicating when insns that read memory in MEM_MODE, an + integral mode narrower than a word, set the bits outsize of + MEM_MODE to be either the sign-extension or the zero-extension of + the data read. */ +#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND + +/* The maximum number of bytes that a single instruction can move + quickly between memory and registers or between two memory + locations. */ +#define MOVE_MAX 8 + +/* An alias for the machine mode for pointers. */ +#define Pmode DImode + +/* An alias for the machine mode used for memory references to + functions being called, in 'call' RTL expressions. */ +#define FUNCTION_MODE Pmode + +/* No libm on eBPF (for now.) */ +#define MATH_LIBRARY "" + +/**** libgcc settings. */ + +/* Iterating over the global constructors and destructors and + executing them requires the ability of doing indirect calls. + + eBPF doesn't support indirect calls, so no chance of supporting + constructors and destructors. */ +#define DO_GLOBAL_CTORS_BODY \ + do { } while (0) +#define DO_GLOBAL_DTORS_BODY \ + do { } while (0) + +#endif /* ! GCC_BPF_H */ diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md new file mode 100644 index 0000000..4c79522 --- /dev/null +++ b/gcc/config/bpf/bpf.md @@ -0,0 +1,497 @@ +;; Machine description for eBPF. +;; Copyright (C) 2019 Free Software Foundation, Inc. + +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. + +;; GCC is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +(include "predicates.md") +(include "constraints.md") + +;;;; Unspecs + +(define_c_enum "unspec" [ + UNSPEC_LDINDABS + UNSPEC_XADD +]) + +;;;; Constants + +(define_constants + [(R0_REGNUM 0) + (R1_REGNUM 1) + (R2_REGNUM 2) + (R3_REGNUM 3) + (R4_REGNUM 4) + (R5_REGNUM 5) + (R6_REGNUM 6) + (R7_REGNUM 7) + (R8_REGNUM 8) + (R9_REGNUM 9) + (R10_REGNUM 10) + (R11_REGNUM 11) +]) + +;;;; Attributes + +;; Instruction classes. +;; alu 64-bit arithmetic. +;; alu32 32-bit arithmetic. +;; end endianness conversion instructions. +;; ld load instructions. +;; lddx load 64-bit immediate instruction. +;; ldx generic load instructions. +;; st generic store instructions for immediates. +;; stx generic store instructions. +;; jmp jump instructions. +;; xadd atomic exchange-and-add instructions. +;; multi multiword sequence (or user asm statements). + +(define_attr "type" + "unknown,alu,alu32,end,ld,lddw,ldx,st,stx,jmp,xadd,multi" + (const_string "unknown")) + +;; Length of instruction in bytes. +(define_attr "length" "" + (cond [ + (eq_attr "type" "lddw") (const_int 16) + ] (const_int 8))) + +;; Describe a user's asm statement. +(define_asm_attributes + [(set_attr "type" "multi")]) + +;;;; Mode attributes and iterators + +(define_mode_attr mop [(QI "b") (HI "h") (SI "w") (DI "dw") + (SF "w") (DF "dw")]) +(define_mode_attr mtype [(SI "alu32") (DI "alu")]) +(define_mode_attr msuffix [(SI "32") (DI "")]) + +;;;; NOPs + +(define_insn "nop" + [(const_int 0)] + "" + "mov\t%%r0,%%r0" + [(set_attr "type" "alu")]) + +;;;; Arithmetic/Logical + +;; The arithmetic and logic operations below are defined for SI and DI +;; modes. The mode iterator AM is used in order to expand to two +;; insns, with the proper modes. +;; +;; 32-bit arithmetic (for SI modes) is implemented using the alu32 +;; instructions. + +(define_mode_iterator AM [SI DI]) + +;;; Addition +(define_insn "add3" + [(set (match_operand:AM 0 "register_operand" "=r,r") + (plus:AM (match_operand:AM 1 "register_operand" " 0,0") + (match_operand:AM 2 "reg_or_imm_operand" " r,I")))] + "1" + "add\t%0,%2" + [(set_attr "type" "")]) + +;;; Subtraction + +;; Note that subtractions of constants become additions, so there is +;; no need to handle immediate operands in the subMODE3 insns. + +(define_insn "sub3" + [(set (match_operand:AM 0 "register_operand" "=r") + (minus:AM (match_operand:AM 1 "register_operand" " 0") + (match_operand:AM 2 "register_operand" " r")))] + "" + "sub\t%0,%2" + [(set_attr "type" "")]) + +;;; Negation +(define_insn "neg2" + [(set (match_operand:AM 0 "register_operand" "=r") + (neg:AM (match_operand:AM 1 "register_operand" " 0")))] + "" + "neg\t%0" + [(set_attr "type" "")]) + +;;; Multiplication +(define_insn "mul3" + [(set (match_operand:AM 0 "register_operand" "=r,r") + (mult:AM (match_operand:AM 1 "register_operand" " 0,0") + (match_operand:AM 2 "reg_or_imm_operand" " r,I")))] + "" + "mul\t%0,%2" + [(set_attr "type" "")]) + +(define_insn "*mulsidi3_zeroextend" + [(set (match_operand:DI 0 "register_operand" "=r,r") + (zero_extend:DI + (mult:SI (match_operand:SI 1 "register_operand" "0,0") + (match_operand:SI 2 "reg_or_imm_operand" "r,I"))))] + "" + "mul32\t%0,%2" + [(set_attr "type" "alu32")]) + +;;; Division + +;; Note that eBPF doesn't provide instructions for signed integer +;; division. + +(define_insn "udiv3" + [(set (match_operand:AM 0 "register_operand" "=r,r") + (udiv:AM (match_operand:AM 1 "register_operand" " 0,0") + (match_operand:AM 2 "reg_or_imm_operand" "r,I")))] + "" + "div\t%0,%2" + [(set_attr "type" "")]) + +;;; Modulus + +;; Note that eBPF doesn't provide instructions for signed integer +;; remainder. + +(define_insn "umod3" + [(set (match_operand:AM 0 "register_operand" "=r,r") + (umod:AM (match_operand:AM 1 "register_operand" " 0,0") + (match_operand:AM 2 "reg_or_imm_operand" "r,I")))] + "" + "mod\t%0,%2" + [(set_attr "type" "")]) + +;;; Logical AND +(define_insn "and3" + [(set (match_operand:AM 0 "register_operand" "=r,r") + (and:AM (match_operand:AM 1 "register_operand" " 0,0") + (match_operand:AM 2 "reg_or_imm_operand" "r,I")))] + "" + "and\t%0,%2" + [(set_attr "type" "")]) + +;;; Logical inclusive-OR +(define_insn "ior3" + [(set (match_operand:AM 0 "register_operand" "=r,r") + (ior:AM (match_operand:AM 1 "register_operand" " 0,0") + (match_operand:AM 2 "reg_or_imm_operand" "r,I")))] + "" + "or\t%0,%2" + [(set_attr "type" "")]) + +;;; Logical exclusive-OR +(define_insn "xor3" + [(set (match_operand:AM 0 "register_operand" "=r,r") + (xor:AM (match_operand:AM 1 "register_operand" " 0,0") + (match_operand:AM 2 "reg_or_imm_operand" "r,I")))] + "" + "xor\t%0,%2" + [(set_attr "type" "")]) + +;;;; Conversions + +;;; Zero-extensions + +;; For register operands smaller than 32-bit zero-extending is +;; achieved ANDing the value in the source register to a suitable +;; mask. +;; +;; For register operands bigger or equal than 32-bit, we generate a +;; mov32 instruction to zero the high 32-bits of the destination +;; register. +;; +;; For memory operands, of any width, zero-extending is achieved using +;; the ldx{bhwdw} instructions to load the values in registers. + +(define_insn "zero_extendhidi2" + [(set (match_operand:DI 0 "register_operand" "=r,r") + (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))] + "" + "@ + and\t%0,0xffff + ldxh\t%0,%1" + [(set_attr "type" "alu,ldx")]) + +(define_insn "zero_extendqidi2" + [(set (match_operand:DI 0 "register_operand" "=r,r") + (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))] + "" + "@ + and\t%0,0xff + ldxb\t%0,%1" + [(set_attr "type" "alu,ldx")]) + +(define_insn "zero_extendsidi2" + [(set (match_operand:DI 0 "register_operand" "=r,r") + (zero_extend:DI + (match_operand:SI 1 "nonimmediate_operand" "r,m")))] + "" + "@ + mov32\t%0,%1 + ldxw\t%0,%1" + [(set_attr "type" "alu,ldx")]) + +;;; Sign-extension + +;; Sign-extending a 32-bit value into a 64-bit value is achieved using +;; shifting, with instructions generated by the expand below. + +(define_expand "extendsidi2" + [(set (match_operand:DI 0 "register_operand") + (sign_extend:DI (match_operand:SI 1 "register_operand")))] + "" +{ + operands[1] = gen_lowpart (DImode, operands[1]); + emit_insn (gen_ashldi3 (operands[0], operands[1], GEN_INT (32))); + emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (32))); + DONE; +}) + +;;;; Data movement + +(define_mode_iterator MM [QI HI SI DI SF DF]) + +(define_expand "mov" + [(set (match_operand:MM 0 "general_operand") + (match_operand:MM 1 "general_operand"))] + "" + " +{ + if (!register_operand(operands[0], mode) + && !register_operand(operands[1], mode)) + operands[1] = force_reg (mode, operands[1]); +}") + +(define_insn "*mov" + [(set (match_operand:MM 0 "nonimmediate_operand" "=r, r,r,m,m") + (match_operand:MM 1 "mov_src_operand" " m,rI,B,r,I"))] + "" + "@ + ldx\t%0,%1 + mov\t%0,%1 + lddw\t%0,%1 + stx\t%0,%1 + st\t%0,%1" +[(set_attr "type" "ldx,alu,alu,stx,st")]) + +;;;; Shifts + +(define_mode_iterator SIM [SI DI]) + +(define_insn "ashr3" + [(set (match_operand:SIM 0 "register_operand" "=r,r") + (ashiftrt:SIM (match_operand:SIM 1 "register_operand" " 0,0") + (match_operand:SIM 2 "reg_or_imm_operand" " r,I")))] + "" + "arsh\t%0,%2" + [(set_attr "type" "")]) + +(define_insn "ashl3" + [(set (match_operand:SIM 0 "register_operand" "=r,r") + (ashift:SIM (match_operand:SIM 1 "register_operand" " 0,0") + (match_operand:SIM 2 "reg_or_imm_operand" " r,I")))] + "" + "lsh\t%0,%2" + [(set_attr "type" "")]) + +(define_insn "lshr3" + [(set (match_operand:SIM 0 "register_operand" "=r,r") + (lshiftrt:SIM (match_operand:SIM 1 "register_operand" " 0,0") + (match_operand:SIM 2 "reg_or_imm_operand" " r,I")))] + "" + "rsh\t%0,%2" + [(set_attr "type" "")]) + +;;;; Conditional branches + +;; The eBPF jump instructions use 64-bit arithmetic when evaluating +;; the jump conditions. Therefore we use DI modes below. + +(define_expand "cbranchdi4" + [(set (pc) + (if_then_else (match_operator 0 "comparison_operator" + [(match_operand:DI 1 "register_operand") + (match_operand:DI 2 "reg_or_imm_operand")]) + (label_ref (match_operand 3 "" "")) + (pc)))] + "" +{ + if (!ordered_comparison_operator (operands[0], VOIDmode)) + FAIL; +}) + +(define_insn "*branch_on_di" + [(set (pc) + (if_then_else (match_operator 3 "ordered_comparison_operator" + [(match_operand:DI 0 "register_operand" "r") + (match_operand:DI 1 "reg_or_imm_operand" "rI")]) + (label_ref (match_operand 2 "" "")) + (pc)))] + "" +{ + int code = GET_CODE (operands[3]); + + switch (code) + { + case EQ: return "jeq\t%0,%1,%2"; break; + case NE: return "jne\t%0,%1,%2"; break; + case LT: return "jslt\t%0,%1,%2"; break; + case LE: return "jsle\t%0,%1,%2"; break; + case GT: return "jsgt\t%0,%1,%2"; break; + case GE: return "jsge\t%0,%1,%2"; break; + case LTU: return "jlt\t%0,%1,%2"; break; + case LEU: return "jle\t%0,%1,%2"; break; + case GTU: return "jgt\t%0,%1,%2"; break; + case GEU: return "jge\t%0,%1,%2"; break; + default: + gcc_unreachable (); + return ""; + } +} + [(set_attr "type" "jmp")]) + +;;;; Unconditional branches + +(define_insn "jump" + [(set (pc) + (label_ref (match_operand 0 "" "")))] + "" + "ja\t%0" +[(set_attr "type" "jmp")]) + +;;;; Function prologue/epilogue + +(define_insn "exit" + [(simple_return)] + "" + "exit" + [(set_attr "type" "jmp")]) + +(define_expand "prologue" + [(const_int 0)] + "" +{ + bpf_expand_prologue (); + DONE; +}) + +(define_expand "epilogue" + [(const_int 0)] + "" +{ + bpf_expand_epilogue (); + DONE; +}) + +;;;; Function calls + +(define_expand "call" + [(parallel [(call (match_operand 0 "") + (match_operand 1 "")) + (use (match_operand 2 "")) ;; next_arg_reg + (use (match_operand 3 ""))])] ;; struct_value_size_rtx + "" +{ + rtx target = XEXP (operands[0], 0); + emit_call_insn (gen_call_internal (target, operands[1])); + DONE; +}) + +(define_insn "call_internal" + [(call (mem:DI (match_operand:DI 0 "call_operand" "Sr")) + (match_operand:SI 1 "general_operand" ""))] + ;; operands[2] is next_arg_register + ;; operands[3] is struct_value_size_rtx. + "" + { return bpf_output_call (operands[0]); } + [(set_attr "type" "jmp")]) + +(define_expand "call_value" + [(parallel [(set (match_operand 0 "") + (call (match_operand 1 "") + (match_operand 2 ""))) + (use (match_operand 3 ""))])] ;; next_arg_reg + "" +{ + rtx target = XEXP (operands[1], 0); + emit_call_insn (gen_call_value_internal (operands[0], target, + operands[2])); + DONE; +}) + +(define_insn "call_value_internal" + [(set (match_operand 0 "register_operand" "") + (call (mem:DI (match_operand:DI 1 "call_operand" "Sr")) + (match_operand:SI 2 "general_operand" "")))] + ;; operands[3] is next_arg_register + ;; operands[4] is struct_value_size_rtx. + "" + { return bpf_output_call (operands[1]); } + [(set_attr "type" "jmp")]) + +(define_insn "sibcall" + [(call (label_ref (match_operand 0 "" "")) + (match_operand:SI 1 "general_operand" ""))] + ;; operands[2] is next_arg_register + ;; operands[3] is struct_value_size_rtx. + "" + "ja\t%0" + [(set_attr "type" "jmp")]) + +;;;; Non-generic load instructions + +(define_mode_iterator LDM [QI HI SI DI]) +(define_mode_attr ldop [(QI "b") (HI "h") (SI "w") (DI "dw")]) + +(define_insn "ldind" + [(set (reg:LDM R0_REGNUM) + (unspec:LDM [(match_operand:DI 0 "register_operand" "r") + (match_operand:SI 1 "imm32_operand" "I")] + UNSPEC_LDINDABS)) + (clobber (reg:DI R1_REGNUM)) + (clobber (reg:DI R2_REGNUM)) + (clobber (reg:DI R3_REGNUM)) + (clobber (reg:DI R4_REGNUM))] + "" + "ldind\t%0,%1" + [(set_attr "type" "ld")]) + +(define_insn "ldabs" + [(set (reg:LDM R0_REGNUM) + (unspec:LDM [(match_operand:SI 0 "imm32_operand" "I") + (match_operand:SI 1 "imm32_operand" "I")] + UNSPEC_LDINDABS)) + (clobber (reg:DI R1_REGNUM)) + (clobber (reg:DI R2_REGNUM)) + (clobber (reg:DI R3_REGNUM)) + (clobber (reg:DI R4_REGNUM))] + "" + "ldabs\t%0" + [(set_attr "type" "ld")]) + +;;;; Atomic increments + +(define_mode_iterator AMO [SI DI]) + +(define_insn "atomic_add" + [(set (match_operand:AMO 0 "memory_operand" "+m") + (unspec_volatile:AMO + [(plus:AMO (match_dup 0) + (match_operand:AMO 1 "register_operand" "r")) + (match_operand:SI 2 "const_int_operand")] ;; Memory model. + UNSPEC_XADD))] + "" + "xadd\t%0,%1" + [(set_attr "type" "xadd")]) diff --git a/gcc/config/bpf/bpf.opt b/gcc/config/bpf/bpf.opt new file mode 100644 index 0000000..e61cf95 --- /dev/null +++ b/gcc/config/bpf/bpf.opt @@ -0,0 +1,123 @@ +; Options for the eBPF compiler port. + +; Copyright (C) 2019 Free Software Foundation, Inc. +; +; This file is part of GCC. +; +; GCC is free software; you can redistribute it and/or modify it under +; the terms of the GNU General Public License as published by the Free +; Software Foundation; either version 3, or (at your option) any later +; version. +; +; GCC is distributed in the hope that it will be useful, but WITHOUT ANY +; WARRANTY; without even the implied warranty of MERCHANTABILITY or +; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +; for more details. +; +; You should have received a copy of the GNU General Public License +; along with GCC; see the file COPYING3. If not see +; . + +HeaderInclude +config/bpf/bpf-opts.h + +; Selecting the kind of kernel the eBPF will be running on. + +mkernel= +Target RejectNegative Joined Var(bpf_kernel) Enum(bpf_kernel) Init(LINUX_LATEST) +Generate eBPF for the given Linux kernel version. + +Enum +Name(bpf_kernel) Type(enum bpf_kernel_version) + +EnumValue +Enum(bpf_kernel) String(native) Value(LINUX_NATIVE) DriverOnly + +EnumValue +Enum(bpf_kernel) String(latest) Value(LINUX_LATEST) DriverOnly + +EnumValue +Enum(bpf_kernel) String(4.0) Value(LINUX_V4_0) + +EnumValue +Enum(bpf_kernel) String(4.1) Value(LINUX_V4_1) + +EnumValue +Enum(bpf_kernel) String(4.2) Value(LINUX_V4_2) + +EnumValue +Enum(bpf_kernel) String(4.3) Value(LINUX_V4_3) + +EnumValue +Enum(bpf_kernel) String(4.4) Value(LINUX_V4_4) + +EnumValue +Enum(bpf_kernel) String(4.5) Value(LINUX_V4_5) + +EnumValue +Enum(bpf_kernel) String(4.6) Value(LINUX_V4_6) + +EnumValue +Enum(bpf_kernel) String(4.7) Value(LINUX_V4_7) + +EnumValue +Enum(bpf_kernel) String(4.8) Value(LINUX_V4_8) + +EnumValue +Enum(bpf_kernel) String(4.9) Value(LINUX_V4_9) + +EnumValue +Enum(bpf_kernel) String(4.10) Value(LINUX_V4_10) + +EnumValue +Enum(bpf_kernel) String(4.11) Value(LINUX_V4_11) + +EnumValue +Enum(bpf_kernel) String(4.12) Value(LINUX_V4_12) + +EnumValue +Enum(bpf_kernel) String(4.13) Value(LINUX_V4_13) + +EnumValue +Enum(bpf_kernel) String(4.14) Value(LINUX_V4_14) + +EnumValue +Enum(bpf_kernel) String(4.15) Value(LINUX_V4_15) + +EnumValue +Enum(bpf_kernel) String(4.16) Value(LINUX_V4_16) + +EnumValue +Enum(bpf_kernel) String(4.17) Value(LINUX_V4_17) + +EnumValue +Enum(bpf_kernel) String(4.18) Value(LINUX_V4_18) + +EnumValue +Enum(bpf_kernel) String(4.19) Value(LINUX_V4_19) + +EnumValue +Enum(bpf_kernel) String(4.20) Value(LINUX_V4_20) + +EnumValue +Enum(bpf_kernel) String(5.0) Value(LINUX_V5_0) + +EnumValue +Enum(bpf_kernel) String(5.1) Value(LINUX_V5_1) + +EnumValue +Enum(bpf_kernel) String(5.2) Value(LINUX_V5_2) + +; Selecting big endian or little endian targets. + +mbig-endian +Target RejectNegative Report Mask(BIG_ENDIAN) +Generate big-endian eBPF. + +mlittle-endian +Target RejectNegative Report InverseMask(BIG_ENDIAN) +Generate little-endian eBPF. + +mframe-limit= +Target Joined RejectNegative UInteger IntegerRange(0, 32767) Var(bpf_frame_limit) Init(512) +Set a hard limit for the size of each stack frame, in bytes. diff --git a/gcc/config/bpf/constraints.md b/gcc/config/bpf/constraints.md new file mode 100644 index 0000000..f27b785 --- /dev/null +++ b/gcc/config/bpf/constraints.md @@ -0,0 +1,32 @@ +;; Constraint definitions for eBPF. +;; Copyright (C) 2019 Free Software Foundation, Inc. +;; +;; This file is part of GCC. +;; +;; GCC is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; GCC is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +(define_constraint "I" + "A 32-bit signed immediate." + (and (match_code "const_int") + (match_test "IN_RANGE (ival, -1 - 0x7fffffff, 0x7fffffff)"))) + +(define_constraint "B" + "A constant argument for LDDW." + (match_code "const,symbol_ref,label_ref,const_double,const_int")) + +(define_constraint "S" + "A constant call address." + (match_code "const,symbol_ref,label_ref,const_int")) + diff --git a/gcc/config/bpf/predicates.md b/gcc/config/bpf/predicates.md new file mode 100644 index 0000000..9ba0e78 --- /dev/null +++ b/gcc/config/bpf/predicates.md @@ -0,0 +1,64 @@ +;; Predicate definitions for eBPF. +;; Copyright (C) 2019 Free Software Foundation, Inc. +;; +;; This file is part of GCC. +;; +;; GCC is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; GCC is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +(define_predicate "reg_or_imm_operand" + (ior (and (match_code "const_int") + (match_test "IN_RANGE (INTVAL (op), -1 - 0x7fffffff, 0x7fffffff)")) + (match_operand 0 "register_operand"))) + +(define_predicate "imm32_operand" + (ior (and (match_code "const_int") + (match_test "IN_RANGE (INTVAL (op), 0, 0xffffffff)")) + (match_code "symbol_ref,label_ref,const"))) + +(define_predicate "lddw_operand" + (match_code "symbol_ref,label_ref,const,const_double,const_int")) + +(define_predicate "call_operand" + (match_code "reg,symbol_ref,const_int,const") +{ + if (GET_CODE (op) == CONST) + { + op = XEXP (op, 0); + + switch (GET_CODE (op)) + { + case SYMBOL_REF: + case LABEL_REF: + case CONST_INT: + return true; + break; + default: + break; + } + + return false; + } + + return true; +}) + +(define_predicate "mov_src_operand" + (ior (match_operand 0 "memory_operand") + (match_operand 0 "reg_or_imm_operand") + (match_operand 0 "lddw_operand"))) + +(define_predicate "register_compare_operator" + (match_code "eq,ne,geu,gtu,ge,gt")) + diff --git a/gcc/config/bpf/t-bpf b/gcc/config/bpf/t-bpf new file mode 100644 index 0000000..e69de29 diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index a922f5c..64fccfe 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -13549,6 +13549,8 @@ instructions, but allow the compiler to schedule those calls. * ARM ARMv8-M Security Extensions:: * AVR Built-in Functions:: * Blackfin Built-in Functions:: +* BPF Built-in Functions:: +* BPF Kernel Helpers:: * FR-V Built-in Functions:: * MIPS DSP Built-in Functions:: * MIPS Paired-Single Support:: @@ -14545,6 +14547,175 @@ void __builtin_bfin_csync (void) void __builtin_bfin_ssync (void) @end smallexample +@node BPF Built-in Functions +@subsection BPF Built-in Functions + +The following built-in functions are available for eBPF targets. + +@deftypefn {Built-in Function} unsigned long long __builtin_bpf_load_byte (unsigned long long @var{offset}) +Load a byte from the @code{struct sk_buff} packet data pointed by the register @code{%r6} and return it. +@end deftypefn + +@deftypefn {Built-in Function} unsigned long long __builtin_bpf_load_half (unsigned long long @var{offset}) +Load 16-bits from the @code{struct sk_buff} packet data pointed by the register @code{%r6} and return it. +@end deftypefn + +@deftypefn {Built-in Function} unsigned long long __builtin_bpf_load_word (unsigned long long @var{offset}) +Load 32-bits from the @code{struct sk_buff} packet data pointed by the register @code{%r6} and return it. +@end deftypefn + +@node BPF Kernel Helpers +@subsection BPF Kernel Helpers + +These built-in functions are available for calling kernel helpers, and +they are available depending on the kernel version selected as the +CPU. + +Rather than using the built-ins directly, it is preferred for programs +to include @file{bpf-helpers.h} and use the wrappers defined there. + +For a full description of what the helpers do, the arguments they +take, and the returned value, see the +@file{linux/include/uapi/linux/bpf.h} in a Linux source tree. + +@smallexample +void *__builtin_bpf_helper_map_lookup_elem (void *map, void *key) +int __builtin_bpf_helper_map_update_elem (void *map, void *key, + void *value, + unsigned long long flags) +int __builtin_bpf_helper_map_delete_elem (void *map, const void *key) +int __builtin_bpf_helper_map_push_elem (void *map, const void *value, + unsigned long long flags) +int __builtin_bpf_helper_map_pop_elem (void *map, void *value) +int __builtin_bpf_helper_map_peek_elem (void *map, void *value) +int __builtin_bpf_helper_clone_redirect (void *skb, + unsigned int ifindex, + unsigned long long flags) +int __builtin_bpf_helper_skb_get_tunnel_key (void *ctx, void *key, int size, int flags) +int __builtin_bpf_helper_skb_set_tunnel_key (void *ctx, void *key, int size, int flags) +int __builtin_bpf_helper_skb_get_tunnel_opt (void *ctx, void *md, int size) +int __builtin_bpf_helper_skb_set_tunnel_opt (void *ctx, void *md, int size) +int __builtin_bpf_helper_skb_get_xfrm_state (void *ctx, int index, void *state, + int size, int flags) +static unsigned long long __builtin_bpf_helper_skb_cgroup_id (void *ctx) +static unsigned long long __builtin_bpf_helper_skb_ancestor_cgroup_id + (void *ctx, int level) +int __builtin_bpf_helper_skb_vlan_push (void *ctx, __be16 vlan_proto, __u16 vlan_tci) +int __builtin_bpf_helper_skb_vlan_pop (void *ctx) +int __builtin_bpf_helper_skb_ecn_set_ce (void *ctx) + +int __builtin_bpf_helper_skb_load_bytes (void *ctx, int off, void *to, int len) +int __builtin_bpf_helper_skb_load_bytes_relative (void *ctx, int off, void *to, int len, __u32 start_header) +int __builtin_bpf_helper_skb_store_bytes (void *ctx, int off, void *from, int len, int flags) +int __builtin_bpf_helper_skb_under_cgroup (void *ctx, void *map, int index) +int __builtin_bpf_helper_skb_change_head (void *, int len, int flags) +int __builtin_bpf_helper_skb_pull_data (void *, int len) +int __builtin_bpf_helper_skb_change_proto (void *ctx, __be16 proto, __u64 flags) +int __builtin_bpf_helper_skb_change_type (void *ctx, __u32 type) +int __builtin_bpf_helper_skb_change_tail (void *ctx, __u32 len, __u64 flags) +int __builtin_bpf_helper_skb_adjust_room (void *ctx, __s32 len_diff, __u32 mode, + unsigned long long flags) +@end smallexample + +Other helpers: + +@smallexample +int __builtin_bpf_helper_probe_read (void *dst, unsigned int size, void *src) +unsigned long long __builtin_bpf_helper_ktime_get_ns (void) +int __builtin_bpf_helper_trace_printk (const char *fmt, unsigned int fmt_size, ...) +void __builtin_bpf_helper_tail_call (void *ctx, void *prog_array_map, unsigned int index) +unsigned int __builtin_bpf_helper_get_smp_processor_id (void) +unsigned long long __builtin_bpf_helper_get_current_pid_tgid (void) +unsigned long long __builtin_bpf_helper_get_current_uid_gid (void) +int __builtin_bpf_helper_get_current_comm (void *buf, unsigned int size_of_buf) +unsigned long long __builtin_bpf_helper_perf_event_read (void *map, unsigned long long flags) + +int __builtin_bpf_helper_redirect (unsigned int ifindex, unsigned long long flags) +int __builtin_bpf_helper_redirect_map (void *map, unsigned int key, unsigned long long flags) +int __builtin_bpf_helper_perf_event_output (void *ctx,void *map, unsigned long long flags, void *data, unsigned long long size) +int __builtin_bpf_helper_get_stackid (void *ctx, void *map, unsigned long long flags) +int __builtin_bpf_helper_probe_write_user (void *dst, const void *src, unsigned int len) +int __builtin_bpf_helper_current_task_under_cgroup (void *map, unsigned int index) + +static unsigned long long __builtin_bpf_helper_get_prandom_u32 (void) +int __builtin_bpf_helper_xdp_adjust_head (void *ctx, int offset) +int __builtin_bpf_helper_xdp_adjust_meta (void *ctx, int offset) +int __builtin_bpf_helper_get_socket_cookie (void *ctx) +int __builtin_bpf_helper_setsockopt (void *ctx, int level, int optname, void *optval, + int optlen) +int __builtin_bpf_helper_getsockopt (void *ctx, int level, int optname, void *optval, + int optlen) +int __builtin_bpf_helper_sock_ops_cb_flags_set (void *ctx, int flags) +int __builtin_bpf_helper_sk_redirect_map (void *ctx, void *map, int key, int flags) +int __builtin_bpf_helper_sk_redirect_hash (void *ctx, void *map, void *key, int flags) +int __builtin_bpf_helper_sock_map_update (void *map, void *key, void *value, + unsigned long long flags) +int __builtin_bpf_helper_sock_hash_update (void *map, void *key, void *value, + unsigned long long flags) +int __builtin_bpf_helper_perf_event_read_value (void *map, unsigned long long flags, + void *buf, unsigned int buf_size) +int __builtin_bpf_helper_perf_prog_read_value (void *ctx, void *buf, + unsigned int buf_size) + +int __builtin_bpf_helper_override_return (void *ctx, unsigned long rc) +int __builtin_bpf_helper_msg_redirect_map (void *ctx, void *map, int key, int flags) +int __builtin_bpf_helper_msg_redirect_hash (void *ctx, + void *map, void *key, int flags) +int __builtin_bpf_helper_msg_apply_bytes (void *ctx, int len) +int __builtin_bpf_helper_msg_cork_bytes (void *ctx, int len) +int __builtin_bpf_helper_msg_pull_data (void *ctx, int start, int end, int flags) +int __builtin_bpf_helper_msg_push_data (void *ctx, int start, int end, int flags) +int __builtin_bpf_helper_msg_pop_data (void *ctx, int start, int cut, int flags) +int __builtin_bpf_helper_bind (void *ctx, void *addr, int addr_len) +int __builtin_bpf_helper_xdp_adjust_tail (void *ctx, int offset) +int __builtin_bpf_helper_sk_select_reuseport (void *ctx, void *map, void *key, __u32 flags) +int __builtin_bpf_helper_get_stack (void *ctx, void *buf, int size, int flags) +int __builtin_bpf_helper_fib_lookup (void *ctx, struct bpf_fib_lookup *params, + int plen, __u32 flags) + +int __builtin_bpf_helper_lwt_push_encap (void *ctx, unsigned int type, void *hdr, + unsigned int len) +int __builtin_bpf_helper_lwt_seg6_store_bytes (void *ctx, unsigned int offset, + void *from, unsigned int len) +int __builtin_bpf_helper_lwt_seg6_action (void *ctx, unsigned int action, void *param, + unsigned int param_len) +int __builtin_bpf_helper_lwt_seg6_adjust_srh (void *ctx, unsigned int offset, + unsigned int len) +int __builtin_bpf_helper_rc_repeat (void *ctx) +int __builtin_bpf_helper_rc_keydown (void *ctx, unsigned int protocol, + unsigned long long scancode, unsigned int toggle) +static unsigned long long __builtin_bpf_helper_get_current_cgroup_id (void) +static void *__builtin_bpf_helper_get_local_storage (void *map, unsigned long long flags) +static struct bpf_sock *__builtin_bpf_helper_sk_lookup_tcp (void *ctx, void *tuple, int size, unsigned long long netns_id, unsigned long long flags) +static struct bpf_sock *__builtin_bpf_helper_sk_lookup_udp (void *ctx, void *tuple, int size, unsigned long long netns_id, unsigned long long flags) +int __builtin_bpf_helper_sk_release (struct bpf_sock *sk) +int __builtin_bpf_helper_rc_pointer_rel (void *ctx, int rel_x, int rel_y) +static void __builtin_bpf_helper_spin_lock (struct bpf_spin_lock *lock) +static void __builtin_bpf_helper_spin_unlock (struct bpf_spin_lock *lock) + +static struct bpf_sock *__builtin_bpf_helper_sk_fullsock (struct bpf_sock *sk) +static struct bpf_tcp_sock *__builtin_bpf_helper_tcp_sock (struct bpf_sock *sk) +static struct bpf_sock *__builtin_bpf_helper_get_listener_sock (struct bpf_sock *sk) + +int __builtin_bpf_helper_l3_csum_replace (void *ctx, int off, int from, int to, int flags) +int __builtin_bpf_helper_l4_csum_replace (void *ctx, int off, int from, int to, int flags) +int __builtin_bpf_helper_csum_diff (void *from, int from_size, void *to, int to_size, int seed) + +static unsigned int __builtin_bpf_helper_get_cgroup_classid (void *ctx) +static unsigned int __builtin_bpf_helper_get_route_realm (void *ctx) +static unsigned int __builtin_bpf_helper_get_hash_recalc (void *ctx) +static unsigned long long __builtin_bpf_helper_get_current_task (void *ctx) + +static long long __builtin_bpf_helper_csum_update (void *ctx, __u32 csum) +static void __builtin_bpf_helper_set_hash_invalid (void *ctx) +int __builtin_bpf_helper_get_numa_node_id (void) +int __builtin_bpf_helper_probe_read_str (void *ctx, __u32 size, + const void *unsafe_ptr) +static unsigned int __builtin_bpf_helper_get_socket_uid (void *ctx) +static unsigned int __builtin_bpf_helper_set_hash (void *ctx, __u32 hash) +@end smallexample + + @node FR-V Built-in Functions @subsection FR-V Built-in Functions diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index bfcd76e..7bcdfcb 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -802,6 +802,10 @@ Objective-C and Objective-C++ Dialects}. -msmall-text -mlarge-text @gol -mmemory-latency=@var{time}} +@emph{eBPF Options} +@gccoptlist{-mbig-endian -mlittle-endian -mkernel=@var{version} +-mframe-limit=@var{bytes}} + @emph{FR30 Options} @gccoptlist{-msmall-model -mno-lsim} @@ -15650,6 +15654,7 @@ platform. * C-SKY Options:: * Darwin Options:: * DEC Alpha Options:: +* eBPF Options:: * FR30 Options:: * FT32 Options:: * FRV Options:: @@ -19771,6 +19776,38 @@ Note that L3 is only valid for EV5. @end table @end table +@node eBPF Options +@subsection eBPF Options +@cindex eBPF Options + +@table @gcctabopt +@item -mframe-limit=@var{bytes} +This specifies the hard limit for frame sizes, in bytes. Currently, +the value that can be specified should be less than or equal to +@samp{32767}. Defaults to whatever limit is imposed by the version of +the Linux kernel targeted. + +@item -mkernel=@var{version} +@opindex mkernel +This specifies the minimum version of the kernel that will run the +compiled program. GCC uses this version to determine which +instructions to use, what kernel helpers to allow, etc. Currently, +@var{version} can be one of @samp{4.0}, @samp{4.1}, @samp{4.2}, +@samp{4.3}, @samp{4.4}, @samp{4.5}, @samp{4.6}, @samp{4.7}, +@samp{4.8}, @samp{4.9}, @samp{4.10}, @samp{4.11}, @samp{4.12}, +@samp{4.13}, @samp{4.14}, @samp{4.15}, @samp{4.16}, @samp{4.17}, +@samp{4.18}, @samp{4.19}, @samp{4.20}, @samp{5.0}, @samp{5.1}, +@samp{5.2}, @samp{latest} and @samp{native}. + +@item -mbig-endian +@opindex mbig-endian +Generate code for a big-endian target. + +@item -mlittle-endian +@opindex mlittle-endian +Generate code for a little-endian target. This is the default. +@end table + @node FR30 Options @subsection FR30 Options @cindex FR30 Options diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9533da6..faa487f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,220 @@ 2019-09-09 Jose E. Marchesi + * gcc.dg/builtins-config.h: eBPF doesn't support C99 standard + functions. + * gcc.c-torture/compile/20101217-1.c: Add a function prototype for + printf. + * gcc.c-torture/compile/20000211-1.c: Skip if target bpf-*-*. + * gcc.c-torture/compile/poor.c: Likewise. + * gcc.c-torture/compile/pr25311.c: Likewise. + * gcc.c-torture/compile/pr39928-1.c: Likewise. + * gcc.c-torture/compile/pr70061.c: Likewise. + * gcc.c-torture/compile/920501-7.c: Likewise. + * gcc.c-torture/compile/20000403-1.c: Likewise. + * gcc.c-torture/compile/20001226-1.c: Likewise. + * gcc.c-torture/compile/20030903-1.c: Likewise. + * gcc.c-torture/compile/20031125-1.c: Likewise. + * gcc.c-torture/compile/20040101-1.c: Likewise. + * gcc.c-torture/compile/20040317-2.c: Likewise. + * gcc.c-torture/compile/20040726-1.c: Likewise. + * gcc.c-torture/compile/20051216-1.c: Likewise. + * gcc.c-torture/compile/900313-1.c: Likewise. + * gcc.c-torture/compile/920625-1.c: Likewise. + * gcc.c-torture/compile/930421-1.c: Likewise. + * gcc.c-torture/compile/930623-1.c: Likewise. + * gcc.c-torture/compile/961004-1.c: Likewise. + * gcc.c-torture/compile/980504-1.c: Likewise. + * gcc.c-torture/compile/980816-1.c: Likewise. + * gcc.c-torture/compile/990625-1.c: Likewise. + * gcc.c-torture/compile/DFcmp.c: Likewise. + * gcc.c-torture/compile/HIcmp.c: Likewise. + * gcc.c-torture/compile/HIset.c: Likewise. + * gcc.c-torture/compile/QIcmp.c: Likewise. + * gcc.c-torture/compile/QIset.c: Likewise. + * gcc.c-torture/compile/SFset.c: Likewise. + * gcc.c-torture/compile/SIcmp.c: Likewise. + * gcc.c-torture/compile/SIset.c: Likewise. + * gcc.c-torture/compile/UHIcmp.c: Likewise. + * gcc.c-torture/compile/UQIcmp.c: Likewise. + * gcc.c-torture/compile/USIcmp.c: Likewise. + * gcc.c-torture/compile/consec.c: Likewise. + * gcc.c-torture/compile/limits-fndefn.c: Likewise. + * gcc.c-torture/compile/lll.c: Likewise. + * gcc.c-torture/compile/parms.c: Likewise. + * gcc.c-torture/compile/pass.c: Likewise. + * gcc.c-torture/compile/pp.c: Likewise. + * gcc.c-torture/compile/pr32399.c: Likewise. + * gcc.c-torture/compile/pr34091.c: Likewise. + * gcc.c-torture/compile/pr34688.c: Likewise. + * gcc.c-torture/compile/pr37258.c: Likewise. + * gcc.c-torture/compile/pr37327.c: Likewise. + * gcc.c-torture/compile/pr37381.c: Likewise. + * gcc.c-torture/compile/pr37669-2.c: Likewise. + * gcc.c-torture/compile/pr37669.c: Likewise. + * gcc.c-torture/compile/pr37742-3.c: Likewise. + * gcc.c-torture/compile/pr44063.c: Likewise. + * gcc.c-torture/compile/pr48596.c: Likewise. + * gcc.c-torture/compile/pr51856.c: Likewise. + * gcc.c-torture/compile/pr54428.c: Likewise. + * gcc.c-torture/compile/pr54713-1.c: Likewise. + * gcc.c-torture/compile/pr54713-2.c: Likewise. + * gcc.c-torture/compile/pr54713-3.c: Likewise. + * gcc.c-torture/compile/pr55921.c: Likewise. + * gcc.c-torture/compile/pr70240.c: Likewise. + * gcc.c-torture/compile/pr70355.c: Likewise. + * gcc.c-torture/compile/pr82052.c: Likewise. + * gcc.c-torture/compile/pr83487.c: Likewise. + * gcc.c-torture/compile/pr86122.c: Likewise. + * gcc.c-torture/compile/pret-arg.c: Likewise. + * gcc.c-torture/compile/regs-arg-size.c: Likewise. + * gcc.c-torture/compile/structret.c: Likewise. + * gcc.c-torture/compile/uuarg.c: Likewise. + * gcc.dg/20001009-1.c: Likewise. + * gcc.dg/20020418-1.c: Likewise. + * gcc.dg/20020426-2.c: Likewise. + * gcc.dg/20020430-1.c: Likewise. + * gcc.dg/20040306-1.c: Likewise. + * gcc.dg/20040622-2.c: Likewise. + * gcc.dg/20050603-2.c: Likewise. + * gcc.dg/20050629-1.c: Likewise. + * gcc.dg/20061026.c: Likewise. + * gcc.dg/Warray-bounds-3.c: Likewise. + * gcc.dg/Warray-bounds-30.c: Likewise. + * gcc.dg/Wframe-larger-than-2.c: Likewise. + * gcc.dg/Wframe-larger-than.c: Likewise. + * gcc.dg/Wrestrict-11.c: Likewise. + * gcc.c-torture/compile/20000804-1.c: Likewise. + +2019-09-09 Jose E. Marchesi + + * lib/target-supports.exp (check_effective_target_trampolines): + Adapt to eBPF. + (check_effective_target_indirect_jumps): Likewise. + (check_effective_target_nonlocal_goto): Likewise. + (check_effective_target_global_constructor): Likewise. + (check_effective_target_return_address): Likewise. + +2019-09-09 Jose E. Marchesi + + * gcc.target/bpf/bpf.exp: New file. + * gcc.target/bpf/builtin-load.c: Likewise. + * cc.target/bpf/constant-calls.c: Likewise. + * gcc.target/bpf/diag-funargs.c: Likewise. + * gcc.target/bpf/diag-funargs-2.c: Likewise. + * gcc.target/bpf/diag-funargs-3.c: Likewise. + * gcc.target/bpf/diag-indcalls.c: Likewise. + * gcc.target/bpf/helper-bind.c: Likewise. + * cc.target/bpf/helper-bpf-redirect.c: Likewise. + * gcc.target/bpf/helper-clone-redirect.c: Likewise. + * gcc.target/bpf/helper-csum-diff.c: Likewise. + * gcc.target/bpf/helper-csum-update.c: Likewise. + * gcc.target/bpf/helper-current-task-under-cgroup.c: Likewise. + * gcc.target/bpf/helper-fib-lookup.c: Likewise. + * gcc.target/bpf/helper-get-cgroup-classid.c: Likewise. + * gcc.target/bpf/helper-get-current-cgroup-id.c: Likewise. + * gcc.target/bpf/helper-get-current-comm.c: Likewise. + * gcc.target/bpf/helper-get-current-pid-tgid.c: Likewise. + * gcc.target/bpf/helper-get-current-task.c: Likewise. + * gcc.target/bpf/helper-get-current-uid-gid.c: Likewise. + * gcc.target/bpf/helper-get-hash-recalc.c: Likewise. + * gcc.target/bpf/helper-get-listener-sock.c: Likewise. + * gcc.target/bpf/helper-get-local-storage.c: Likewise. + * gcc.target/bpf/helper-get-numa-node-id.c: Likewise. + * gcc.target/bpf/helper-get-prandom-u32.c: Likewise. + * gcc.target/bpf/helper-get-route-realm.c: Likewise. + * gcc.target/bpf/helper-get-smp-processor-id.c: Likewise. + * gcc.target/bpf/helper-get-socket-cookie.c: Likewise. + * gcc.target/bpf/helper-get-socket-uid.c: Likewise. + * gcc.target/bpf/helper-getsockopt.c: Likewise. + * gcc.target/bpf/helper-get-stack.c: Likewise. + * gcc.target/bpf/helper-get-stackid.c: Likewise. + * gcc.target/bpf/helper-ktime-get-ns.c: Likewise. + * gcc.target/bpf/helper-l3-csum-replace.c: Likewise. + * gcc.target/bpf/helper-l4-csum-replace.c: Likewise. + * gcc.target/bpf/helper-lwt-push-encap.c: Likewise. + * gcc.target/bpf/helper-lwt-seg6-action.c: Likewise. + * gcc.target/bpf/helper-lwt-seg6-adjust-srh.c: Likewise. + * gcc.target/bpf/helper-lwt-seg6-store-bytes.c: Likewise. + * gcc.target/bpf/helper-map-delete-elem.c: Likewise. + * gcc.target/bpf/helper-map-lookup-elem.c: Likewise. + * gcc.target/bpf/helper-map-peek-elem.c: Likewise. + * gcc.target/bpf/helper-map-pop-elem.c: Likewise. + * gcc.target/bpf/helper-map-push-elem.c: Likewise. + * gcc.target/bpf/helper-map-update-elem.c: Likewise. + * gcc.target/bpf/helper-msg-apply-bytes.c: Likewise. + * gcc.target/bpf/helper-msg-cork-bytes.c: Likewise. + * gcc.target/bpf/helper-msg-pop-data.c: Likewise. + * gcc.target/bpf/helper-msg-pull-data.c: Likewise. + * gcc.target/bpf/helper-msg-push-data.c: Likewise. + * gcc.target/bpf/helper-msg-redirect-hash.c: Likewise. + * gcc.target/bpf/helper-msg-redirect-map.c: Likewise. + * gcc.target/bpf/helper-override-return.c: Likewise. + * gcc.target/bpf/helper-perf-event-output.c: Likewise. + * gcc.target/bpf/helper-perf-event-read.c: Likewise. + * gcc.target/bpf/helper-perf-event-read-value.c: Likewise. + * gcc.target/bpf/helper-perf-prog-read-value.c: Likewise. + * gcc.target/bpf/helper-probe-read.c: Likewise. + * gcc.target/bpf/helper-probe-read-str.c: Likewise. + * gcc.target/bpf/helper-probe-write-user.c: Likewise. + * gcc.target/bpf/helper-rc-keydown.c: Likewise. + * gcc.target/bpf/helper-rc-pointer-rel.c: Likewise. + * gcc.target/bpf/helper-rc-repeat.c: Likewise. + * gcc.target/bpf/helper-redirect-map.c: Likewise. + * gcc.target/bpf/helper-set-hash.c: Likewise. + * gcc.target/bpf/helper-set-hash-invalid.c: Likewise. + * gcc.target/bpf/helper-setsockopt.c: Likewise. + * gcc.target/bpf/helper-skb-adjust-room.c: Likewise. + * gcc.target/bpf/helper-skb-cgroup-id.c: Likewise. + * gcc.target/bpf/helper-skb-change-head.c: Likewise. + * gcc.target/bpf/helper-skb-change-proto.c: Likewise. + * gcc.target/bpf/helper-skb-change-tail.c: Likewise. + * gcc.target/bpf/helper-skb-change-type.c: Likewise. + * gcc.target/bpf/helper-skb-ecn-set-ce.c: Likewise. + * gcc.target/bpf/helper-skb-get-tunnel-key.c: Likewise. + * gcc.target/bpf/helper-skb-get-tunnel-opt.c: Likewise. + * gcc.target/bpf/helper-skb-get-xfrm-state.c: Likewise. + * gcc.target/bpf/helper-skb-load-bytes.c: Likewise. + * gcc.target/bpf/helper-skb-load-bytes-relative.c: Likewise. + * gcc.target/bpf/helper-skb-pull-data.c: Likewise. + * gcc.target/bpf/helper-skb-set-tunnel-key.c: Likewise. + * gcc.target/bpf/helper-skb-set-tunnel-opt.c: Likewise. + * gcc.target/bpf/helper-skb-store-bytes.c: Likewise. + * gcc.target/bpf/helper-skb-under-cgroup.c: Likewise. + * gcc.target/bpf/helper-skb-vlan-pop.c: Likewise. + * gcc.target/bpf/helper-skb-vlan-push.c: Likewise. + * gcc.target/bpf/helper-skc-lookup-tcp.c: Likewise. + * gcc.target/bpf/helper-sk-fullsock.c: Likewise. + * gcc.target/bpf/helper-sk-lookup-tcp.c: Likewise. + * gcc.target/bpf/helper-sk-lookup-upd.c: Likewise. + * gcc.target/bpf/helper-sk-redirect-hash.c: Likewise. + * gcc.target/bpf/helper-sk-redirect-map.c: Likewise. + * gcc.target/bpf/helper-sk-release.c: Likewise. + * gcc.target/bpf/helper-sk-select-reuseport.c: Likewise. + * gcc.target/bpf/helper-sk-storage-delete.c: Likewise. + * gcc.target/bpf/helper-sk-storage-get.c: Likewise. + * gcc.target/bpf/helper-sock-hash-update.c: Likewise. + * gcc.target/bpf/helper-sock-map-update.c: Likewise. + * gcc.target/bpf/helper-sock-ops-cb-flags-set.c: Likewise. + * gcc.target/bpf/helper-spin-lock.c: Likewise. + * gcc.target/bpf/helper-spin-unlock.c: Likewise. + * gcc.target/bpf/helper-strtol.c: Likewise. + * gcc.target/bpf/helper-strtoul.c: Likewise. + * gcc.target/bpf/helper-sysctl-get-current-value.c: Likewise. + * gcc.target/bpf/helper-sysctl-get-name.c: Likewise. + * gcc.target/bpf/helper-sysctl-get-new-value.c: Likewise. + * gcc.target/bpf/helper-sysctl-set-new-value.c: Likewise. + * gcc.target/bpf/helper-tail-call.c: Likewise. + * gcc.target/bpf/helper-tcp-check-syncookie.c: Likewise. + * gcc.target/bpf/helper-tcp-sock.c: Likewise. + * gcc.target/bpf/helper-trace-printk.c: Likewise. + * gcc.target/bpf/helper-xdp-adjust-head.c: Likewise. + * gcc.target/bpf/helper-xdp-adjust-meta.c: Likewise. + * gcc.target/bpf/helper-xdp-adjust-tail.c: Likewise. + * gcc.target/bpf/skb-ancestor-cgroup-id.c: Likewise. + * gcc.target/bpf/sync-fetch-and-add.c: Likewise. + +2019-09-09 Jose E. Marchesi + * lib/target-supports.exp (check_effective_target_indirect_calls): New proc. * gcc.c-torture/compile/20010102-1.c: Annotate with diff --git a/gcc/testsuite/gcc.c-torture/compile/20000211-1.c b/gcc/testsuite/gcc.c-torture/compile/20000211-1.c index 7a7c8c0..b83d6a4 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20000211-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20000211-1.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + typedef __SIZE_TYPE__ size_t; typedef unsigned char Bufbyte; typedef int Bytecount; diff --git a/gcc/testsuite/gcc.c-torture/compile/20000403-1.c b/gcc/testsuite/gcc.c-torture/compile/20000403-1.c index 27345b5..cb56028 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20000403-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20000403-1.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + struct utsname { char sysname[32 ]; char version[32 ]; diff --git a/gcc/testsuite/gcc.c-torture/compile/20000804-1.c b/gcc/testsuite/gcc.c-torture/compile/20000804-1.c index 550669b..95bb0fa 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20000804-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20000804-1.c @@ -5,6 +5,7 @@ /* { dg-skip-if "No 64-bit registers" { m32c-*-* } } */ /* { dg-skip-if "Not enough 64-bit registers" { pdp11-*-* } { "-O0" } { "" } } */ /* { dg-xfail-if "Inconsistent constraint on asm" { csky-*-* } { "-O0" } { "" } } */ +/* { dg-xfail-if "Inconsistent constraint on asm" { bpf-*-* } { "-O0" } { "" } } */ /* { dg-xfail-if "" { h8300-*-* } } */ /* { dg-require-stack-size "99*4+16" } */ diff --git a/gcc/testsuite/gcc.c-torture/compile/20001226-1.c b/gcc/testsuite/gcc.c-torture/compile/20001226-1.c index 073ac6a..234cdbf 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20001226-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20001226-1.c @@ -2,6 +2,7 @@ /* { dg-skip-if "too much code for avr" { "avr-*-*" } } */ /* { dg-skip-if "too much code for pdp11" { "pdp11-*-*" } } */ /* { dg-skip-if "" { m32c-*-* } } */ +/* { dg-skip-if "jumps too far for eBPF" { bpf-*-* } } */ /* { dg-timeout-factor 4.0 } */ /* This testcase exposed two branch shortening bugs on powerpc. */ diff --git a/gcc/testsuite/gcc.c-torture/compile/20030903-1.c b/gcc/testsuite/gcc.c-torture/compile/20030903-1.c index fa4d30d..116b092 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20030903-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20030903-1.c @@ -1,6 +1,8 @@ /* Derived from PR optimization/11700. */ /* The compiler used to ICE during reload for m68k targets. */ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ + void check_complex (__complex__ double, __complex__ double, __complex__ double, __complex__ int); void check_float (double, double, double, int); diff --git a/gcc/testsuite/gcc.c-torture/compile/20031125-1.c b/gcc/testsuite/gcc.c-torture/compile/20031125-1.c index d3e9267..bec6c93 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20031125-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20031125-1.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + short *_offsetTable; /* This tests to make sure PRE splits the entry block ->block 0 edge when there are multiple block 0 predecessors. diff --git a/gcc/testsuite/gcc.c-torture/compile/20040101-1.c b/gcc/testsuite/gcc.c-torture/compile/20040101-1.c index 5c2688a..6027cb5 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20040101-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20040101-1.c @@ -1,4 +1,5 @@ /* { dg-skip-if "not enough registers" { pdp11-*-* } } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ typedef unsigned short uint16_t; typedef unsigned int uint32_t; diff --git a/gcc/testsuite/gcc.c-torture/compile/20040317-2.c b/gcc/testsuite/gcc.c-torture/compile/20040317-2.c index 3c8ee2b..3a1fbde2 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20040317-2.c +++ b/gcc/testsuite/gcc.c-torture/compile/20040317-2.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + typedef struct _ScaleRec *ScaleWidget; typedef struct { diff --git a/gcc/testsuite/gcc.c-torture/compile/20040726-1.c b/gcc/testsuite/gcc.c-torture/compile/20040726-1.c index e53ccd6..aea43a5 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20040726-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20040726-1.c @@ -1,4 +1,6 @@ /* PR rtl-optimization/16643 */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + void foo (int a, int b, int c, int d, int e, int *f) { if (a == 0) diff --git a/gcc/testsuite/gcc.c-torture/compile/20051216-1.c b/gcc/testsuite/gcc.c-torture/compile/20051216-1.c index ed6ac72..55751ec 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20051216-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20051216-1.c @@ -1,4 +1,5 @@ /* PR rtl-optimization/25432 */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ void *malloc (__SIZE_TYPE__); void *realloc (void *, __SIZE_TYPE__); diff --git a/gcc/testsuite/gcc.c-torture/compile/20101217-1.c b/gcc/testsuite/gcc.c-torture/compile/20101217-1.c index c4eef0e..46bdcf5e 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20101217-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20101217-1.c @@ -1,5 +1,7 @@ /* Testcase provided by HUAWEI. */ -#include + +extern int printf (const char * __format, ...); + int main() { int cur_k; diff --git a/gcc/testsuite/gcc.c-torture/compile/900313-1.c b/gcc/testsuite/gcc.c-torture/compile/900313-1.c index 2bac581..12252b4 100644 --- a/gcc/testsuite/gcc.c-torture/compile/900313-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/900313-1.c @@ -1,4 +1,6 @@ /* { dg-require-effective-target alloca } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + main () { char *a; diff --git a/gcc/testsuite/gcc.c-torture/compile/920501-7.c b/gcc/testsuite/gcc.c-torture/compile/920501-7.c index 2af15e3..0fac5f3 100644 --- a/gcc/testsuite/gcc.c-torture/compile/920501-7.c +++ b/gcc/testsuite/gcc.c-torture/compile/920501-7.c @@ -1,3 +1,4 @@ /* { dg-require-effective-target label_values } */ +/* { dg-skip-if "no support for indirect jumps" { bpf-*-* } } */ x(){if(&&e-&&b<0)x();b:goto*&&b;e:;} diff --git a/gcc/testsuite/gcc.c-torture/compile/920625-1.c b/gcc/testsuite/gcc.c-torture/compile/920625-1.c index 720d43f..759a356 100644 --- a/gcc/testsuite/gcc.c-torture/compile/920625-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/920625-1.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + typedef unsigned long int unsigned_word; typedef signed long int signed_word; typedef unsigned_word word; diff --git a/gcc/testsuite/gcc.c-torture/compile/930421-1.c b/gcc/testsuite/gcc.c-torture/compile/930421-1.c index 01b465f..9e16fe1 100644 --- a/gcc/testsuite/gcc.c-torture/compile/930421-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/930421-1.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + double q(double); f (int **x, int *r, int *s, int a, int b, int c, int d) diff --git a/gcc/testsuite/gcc.c-torture/compile/930623-1.c b/gcc/testsuite/gcc.c-torture/compile/930623-1.c index 022ad01..dd45bbc 100644 --- a/gcc/testsuite/gcc.c-torture/compile/930623-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/930623-1.c @@ -1,4 +1,5 @@ /* { dg-require-effective-target untyped_assembly } */ +/* { dg-skip-if "no __builtin_apply in eBPF" { bpf-*-* } } */ g (a, b) {} diff --git a/gcc/testsuite/gcc.c-torture/compile/961004-1.c b/gcc/testsuite/gcc.c-torture/compile/961004-1.c index 6407b62..cf47f60 100644 --- a/gcc/testsuite/gcc.c-torture/compile/961004-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/961004-1.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + void f1 (o1, o2, o3, i, j, k) long long *o1, *o2, *o3; diff --git a/gcc/testsuite/gcc.c-torture/compile/980504-1.c b/gcc/testsuite/gcc.c-torture/compile/980504-1.c index 7b757cc..6e043a7 100644 --- a/gcc/testsuite/gcc.c-torture/compile/980504-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/980504-1.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + typedef struct _geom_elem { double coeffs[6]; } pGeomDefRec, *pGeomDefPtr; diff --git a/gcc/testsuite/gcc.c-torture/compile/980816-1.c b/gcc/testsuite/gcc.c-torture/compile/980816-1.c index a79100f..5bd83b1 100644 --- a/gcc/testsuite/gcc.c-torture/compile/980816-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/980816-1.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + typedef __SIZE_TYPE__ size_t; typedef void *XtPointer; diff --git a/gcc/testsuite/gcc.c-torture/compile/990625-1.c b/gcc/testsuite/gcc.c-torture/compile/990625-1.c index 97a2331..befff06 100644 --- a/gcc/testsuite/gcc.c-torture/compile/990625-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/990625-1.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "no string.h in eBPF" { bpf-*-* } } */ + #define __USE_STRING_INLINES #include diff --git a/gcc/testsuite/gcc.c-torture/compile/DFcmp.c b/gcc/testsuite/gcc.c-torture/compile/DFcmp.c index 3bb2534..808874d 100644 --- a/gcc/testsuite/gcc.c-torture/compile/DFcmp.c +++ b/gcc/testsuite/gcc.c-torture/compile/DFcmp.c @@ -1,4 +1,6 @@ /* { dg-require-effective-target int32plus } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + #define type double type glob0, glob1; diff --git a/gcc/testsuite/gcc.c-torture/compile/HIcmp.c b/gcc/testsuite/gcc.c-torture/compile/HIcmp.c index 77b4788..6e68271 100644 --- a/gcc/testsuite/gcc.c-torture/compile/HIcmp.c +++ b/gcc/testsuite/gcc.c-torture/compile/HIcmp.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + #define type short type glob0, glob1; diff --git a/gcc/testsuite/gcc.c-torture/compile/HIset.c b/gcc/testsuite/gcc.c-torture/compile/HIset.c index 163cb7c..a0d426c 100644 --- a/gcc/testsuite/gcc.c-torture/compile/HIset.c +++ b/gcc/testsuite/gcc.c-torture/compile/HIset.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + #define E0 ((type *)10000000) #define reg0 r0 #define indreg0 (*p0) diff --git a/gcc/testsuite/gcc.c-torture/compile/QIcmp.c b/gcc/testsuite/gcc.c-torture/compile/QIcmp.c index c516164..a4dba24 100644 --- a/gcc/testsuite/gcc.c-torture/compile/QIcmp.c +++ b/gcc/testsuite/gcc.c-torture/compile/QIcmp.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + #define type signed char type glob0, glob1; diff --git a/gcc/testsuite/gcc.c-torture/compile/QIset.c b/gcc/testsuite/gcc.c-torture/compile/QIset.c index 212609d..e2fde2b 100644 --- a/gcc/testsuite/gcc.c-torture/compile/QIset.c +++ b/gcc/testsuite/gcc.c-torture/compile/QIset.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + #define E0 ((type *)10000000) #define reg0 r0 #define indreg0 (*p0) diff --git a/gcc/testsuite/gcc.c-torture/compile/SFset.c b/gcc/testsuite/gcc.c-torture/compile/SFset.c index dc7f48d..a7efecf 100644 --- a/gcc/testsuite/gcc.c-torture/compile/SFset.c +++ b/gcc/testsuite/gcc.c-torture/compile/SFset.c @@ -1,4 +1,5 @@ /* { dg-require-effective-target int32plus } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ #define E0 ((type *)10000000) #define reg0 r0 diff --git a/gcc/testsuite/gcc.c-torture/compile/SIcmp.c b/gcc/testsuite/gcc.c-torture/compile/SIcmp.c index 4a9e0d5..ce1281b 100644 --- a/gcc/testsuite/gcc.c-torture/compile/SIcmp.c +++ b/gcc/testsuite/gcc.c-torture/compile/SIcmp.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + #define type int type glob0, glob1; diff --git a/gcc/testsuite/gcc.c-torture/compile/SIset.c b/gcc/testsuite/gcc.c-torture/compile/SIset.c index 5fb9357..b200a26 100644 --- a/gcc/testsuite/gcc.c-torture/compile/SIset.c +++ b/gcc/testsuite/gcc.c-torture/compile/SIset.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + #define E0 ((type *)10000000) #define reg0 r0 #define indreg0 (*p0) diff --git a/gcc/testsuite/gcc.c-torture/compile/UHIcmp.c b/gcc/testsuite/gcc.c-torture/compile/UHIcmp.c index 529e3a3..b0029d2 100644 --- a/gcc/testsuite/gcc.c-torture/compile/UHIcmp.c +++ b/gcc/testsuite/gcc.c-torture/compile/UHIcmp.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + #define type unsigned short type glob0, glob1; diff --git a/gcc/testsuite/gcc.c-torture/compile/UQIcmp.c b/gcc/testsuite/gcc.c-torture/compile/UQIcmp.c index 3e9cdeb..e28d13b 100644 --- a/gcc/testsuite/gcc.c-torture/compile/UQIcmp.c +++ b/gcc/testsuite/gcc.c-torture/compile/UQIcmp.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + #define type unsigned char type glob0, glob1; diff --git a/gcc/testsuite/gcc.c-torture/compile/USIcmp.c b/gcc/testsuite/gcc.c-torture/compile/USIcmp.c index 69788a4..27e5503 100644 --- a/gcc/testsuite/gcc.c-torture/compile/USIcmp.c +++ b/gcc/testsuite/gcc.c-torture/compile/USIcmp.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + #define type unsigned int type glob0, glob1; diff --git a/gcc/testsuite/gcc.c-torture/compile/consec.c b/gcc/testsuite/gcc.c-torture/compile/consec.c index 01fa25b..b8c376d 100644 --- a/gcc/testsuite/gcc.c-torture/compile/consec.c +++ b/gcc/testsuite/gcc.c-torture/compile/consec.c @@ -1,4 +1,6 @@ /* { dg-require-effective-target untyped_assembly } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + int glob; conseq (a, b, c, d) diff --git a/gcc/testsuite/gcc.c-torture/compile/limits-fndefn.c b/gcc/testsuite/gcc.c-torture/compile/limits-fndefn.c index 0bd8f6a..5320473 100644 --- a/gcc/testsuite/gcc.c-torture/compile/limits-fndefn.c +++ b/gcc/testsuite/gcc.c-torture/compile/limits-fndefn.c @@ -1,5 +1,6 @@ /* { dg-skip-if "too complex for avr" { avr-*-* } } */ /* { dg-skip-if "ptxas times out" { nvptx-*-* } } */ +/* { dg-skip-if "no chance for bpf" { bpf-*-* } } */ /* { dg-timeout-factor 4.0 } */ #define LIM1(x) x##0, x##1, x##2, x##3, x##4, x##5, x##6, x##7, x##8, x##9, #define LIM2(x) LIM1(x##0) LIM1(x##1) LIM1(x##2) LIM1(x##3) LIM1(x##4) \ diff --git a/gcc/testsuite/gcc.c-torture/compile/lll.c b/gcc/testsuite/gcc.c-torture/compile/lll.c index dee9dc3..ea09c87 100644 --- a/gcc/testsuite/gcc.c-torture/compile/lll.c +++ b/gcc/testsuite/gcc.c-torture/compile/lll.c @@ -1,3 +1,4 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ byte_match_count2 (buf, n, xm, m1, m2, m3, m4) unsigned *buf; diff --git a/gcc/testsuite/gcc.c-torture/compile/parms.c b/gcc/testsuite/gcc.c-torture/compile/parms.c index 8205a9c..1bfc93d 100644 --- a/gcc/testsuite/gcc.c-torture/compile/parms.c +++ b/gcc/testsuite/gcc.c-torture/compile/parms.c @@ -1,4 +1,5 @@ /* { dg-require-effective-target alloca } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ #define alloca __builtin_alloca x (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, x, y) diff --git a/gcc/testsuite/gcc.c-torture/compile/pass.c b/gcc/testsuite/gcc.c-torture/compile/pass.c index 4e02839..529a01d 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pass.c +++ b/gcc/testsuite/gcc.c-torture/compile/pass.c @@ -1,4 +1,6 @@ /* { dg-require-effective-target untyped_assembly } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + int foo (a, b, c) { diff --git a/gcc/testsuite/gcc.c-torture/compile/poor.c b/gcc/testsuite/gcc.c-torture/compile/poor.c index 66d584a..20287ef 100644 --- a/gcc/testsuite/gcc.c-torture/compile/poor.c +++ b/gcc/testsuite/gcc.c-torture/compile/poor.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ + typedef struct { char c[510]; diff --git a/gcc/testsuite/gcc.c-torture/compile/pp.c b/gcc/testsuite/gcc.c-torture/compile/pp.c index 7d38d53..c1e09ea 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pp.c +++ b/gcc/testsuite/gcc.c-torture/compile/pp.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + foo (a, b, c, d, e, i0, f, i1) double a, b, c, d, e, f; int i0, i1; diff --git a/gcc/testsuite/gcc.c-torture/compile/pr25311.c b/gcc/testsuite/gcc.c-torture/compile/pr25311.c index 26c5bc3..43ef3fd 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr25311.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr25311.c @@ -1,3 +1,4 @@ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ struct w { diff --git a/gcc/testsuite/gcc.c-torture/compile/pr32399.c b/gcc/testsuite/gcc.c-torture/compile/pr32399.c index cc2b1b1..b29dbd7 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr32399.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr32399.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + void f(unsigned char *src, unsigned char *dst, int num, unsigned char *pos, unsigned char *diffuse, int hasdiffuse, unsigned char *specular, int hasspecular) { int i; diff --git a/gcc/testsuite/gcc.c-torture/compile/pr34091.c b/gcc/testsuite/gcc.c-torture/compile/pr34091.c index 0b85491..a623a38 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr34091.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr34091.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + typedef unsigned int GLenum; typedef unsigned char GLboolean; typedef int GLint; diff --git a/gcc/testsuite/gcc.c-torture/compile/pr34688.c b/gcc/testsuite/gcc.c-torture/compile/pr34688.c index 60e0f3c..ec890cb 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr34688.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr34688.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + typedef __SIZE_TYPE__ size_t; typedef struct { } diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37258.c b/gcc/testsuite/gcc.c-torture/compile/pr37258.c index 286f2fc..4180178 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr37258.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr37258.c @@ -1,4 +1,6 @@ /* { dg-require-effective-target untyped_assembly } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + typedef signed char int8_t; typedef short int int16_t; typedef int int32_t; diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37327.c b/gcc/testsuite/gcc.c-torture/compile/pr37327.c index 79946b7..5ca9d1d 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr37327.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr37327.c @@ -1,4 +1,6 @@ /* { dg-require-effective-target untyped_assembly } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + typedef signed char int8_t; typedef short int int16_t; typedef int int32_t; diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37381.c b/gcc/testsuite/gcc.c-torture/compile/pr37381.c index a2fed66..d8cd47d 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr37381.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr37381.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + extern unsigned int __invalid_size_argument_for_IOC; typedef unsigned int __u32; struct video_window diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37669-2.c b/gcc/testsuite/gcc.c-torture/compile/pr37669-2.c index abeae7a..2170dda 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr37669-2.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr37669-2.c @@ -1,4 +1,5 @@ /* PR middle-end/37669 */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ #define FMT10 "%d%d%d%d%d%d%d%d%d%d" #define FMT100 FMT10 FMT10 FMT10 FMT10 FMT10 FMT10 FMT10 FMT10 FMT10 FMT10 diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37669.c b/gcc/testsuite/gcc.c-torture/compile/pr37669.c index a2eafc75..36e4c39 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr37669.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr37669.c @@ -1,6 +1,7 @@ /* This testcase used to fail because a miscompiled execute_fold_all_builtins. */ /* { dg-options "-fgnu89-inline" } */ /* { dg-require-effective-target int32plus } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ typedef __SIZE_TYPE__ size_t; extern __inline __attribute__ ((__always_inline__)) int __attribute__ diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37742-3.c b/gcc/testsuite/gcc.c-torture/compile/pr37742-3.c index 541bd42..9e7b10f 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr37742-3.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr37742-3.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + void matmul_i4 (int * __restrict dest_y, const int * __restrict abase, const int * __restrict bbase_y, diff --git a/gcc/testsuite/gcc.c-torture/compile/pr39928-1.c b/gcc/testsuite/gcc.c-torture/compile/pr39928-1.c index 1abb5cc..ae6a63b 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr39928-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr39928-1.c @@ -1,4 +1,6 @@ /* { dg-options "-msse" { target { i?86-*-* x86_64-*-* } } } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + typedef float __m128 __attribute__ ((__vector_size__ (16), __may_alias__)); extern __m128 _mm_sub_ps (__m128 __A, __m128 __B); extern __m128 _mm_mul_ps (__m128 __A, __m128 __B); diff --git a/gcc/testsuite/gcc.c-torture/compile/pr44063.c b/gcc/testsuite/gcc.c-torture/compile/pr44063.c index 596e1dc..32208f6 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr44063.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr44063.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ + typedef signed char int8_t; typedef short int16_t; typedef unsigned char uint8_t; diff --git a/gcc/testsuite/gcc.c-torture/compile/pr48596.c b/gcc/testsuite/gcc.c-torture/compile/pr48596.c index 382a152..743bd82 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr48596.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr48596.c @@ -1,4 +1,6 @@ /* PR target/48596 */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + enum { nrrdCenterUnknown, nrrdCenterNode, nrrdCenterCell, nrrdCenterLast }; typedef struct { int size; int center; } NrrdAxis; typedef struct { int dim; NrrdAxis axis[10]; } Nrrd; diff --git a/gcc/testsuite/gcc.c-torture/compile/pr51856.c b/gcc/testsuite/gcc.c-torture/compile/pr51856.c index 6644c7f..823a0be 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr51856.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr51856.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + struct B { int b1; long long b2, b3; int b4; }; struct C { char c1[40], c2, c3[96]; long long c4[5], c5; char c6[596]; }; void fn1 (long long), fn2 (char *, int), fn4 (void); diff --git a/gcc/testsuite/gcc.c-torture/compile/pr54428.c b/gcc/testsuite/gcc.c-torture/compile/pr54428.c index 84a5dbd..d783337 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr54428.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr54428.c @@ -1,4 +1,5 @@ /* PR c/54428 */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ typedef double _Complex C; diff --git a/gcc/testsuite/gcc.c-torture/compile/pr54713-1.c b/gcc/testsuite/gcc.c-torture/compile/pr54713-1.c index f042ea2..0d4172a 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr54713-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr54713-1.c @@ -1,4 +1,5 @@ /* PR tree-optimization/54713 */ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ #ifndef N #define N 8 diff --git a/gcc/testsuite/gcc.c-torture/compile/pr54713-2.c b/gcc/testsuite/gcc.c-torture/compile/pr54713-2.c index c391037..f7d2364 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr54713-2.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr54713-2.c @@ -1,4 +1,5 @@ /* PR tree-optimization/54713 */ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ #define N 16 #define ONE 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 diff --git a/gcc/testsuite/gcc.c-torture/compile/pr54713-3.c b/gcc/testsuite/gcc.c-torture/compile/pr54713-3.c index 6164a5e..76a35b0 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr54713-3.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr54713-3.c @@ -1,4 +1,5 @@ /* PR tree-optimization/54713 */ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ #define N 32 #define ONE 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ diff --git a/gcc/testsuite/gcc.c-torture/compile/pr55921.c b/gcc/testsuite/gcc.c-torture/compile/pr55921.c index de0635d6..cf9084e 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr55921.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr55921.c @@ -1,5 +1,6 @@ /* PR tree-optimization/55921 */ /* { dg-skip-if "Not enough registers" { "pdp11-*-*" } } */ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ typedef union { diff --git a/gcc/testsuite/gcc.c-torture/compile/pr70061.c b/gcc/testsuite/gcc.c-torture/compile/pr70061.c index a7ebcfc..aabfdda 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr70061.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr70061.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + typedef int v8si __attribute__ ((vector_size (32))); int diff --git a/gcc/testsuite/gcc.c-torture/compile/pr70240.c b/gcc/testsuite/gcc.c-torture/compile/pr70240.c index 830d4dd..466d3a7 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr70240.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr70240.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + typedef short v16hi __attribute__ ((vector_size (32))); typedef int v8si __attribute__ ((vector_size (32))); typedef long long v4di __attribute__ ((vector_size (32))); diff --git a/gcc/testsuite/gcc.c-torture/compile/pr70355.c b/gcc/testsuite/gcc.c-torture/compile/pr70355.c index 4749427..f711420 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr70355.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr70355.c @@ -1,5 +1,7 @@ /* { dg-require-effective-target int128 } */ /* { dg-additional-options "-g" } */ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ + typedef unsigned __int128 v2ti __attribute__ ((vector_size (32))); diff --git a/gcc/testsuite/gcc.c-torture/compile/pr82052.c b/gcc/testsuite/gcc.c-torture/compile/pr82052.c index 3763161..09fac5e 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr82052.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr82052.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ + typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned uint32_t; diff --git a/gcc/testsuite/gcc.c-torture/compile/pr83487.c b/gcc/testsuite/gcc.c-torture/compile/pr83487.c index 9effb1e..9de0e17 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr83487.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr83487.c @@ -1,4 +1,5 @@ /* PR middle-end/83487 */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ struct __attribute__ ((aligned)) A {}; struct A a; diff --git a/gcc/testsuite/gcc.c-torture/compile/pr86122.c b/gcc/testsuite/gcc.c-torture/compile/pr86122.c index 0a4fd14..1bd4673 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr86122.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr86122.c @@ -1,4 +1,5 @@ /* PR middle-end/86122 */ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ _Complex int foo (_Complex int x) diff --git a/gcc/testsuite/gcc.c-torture/compile/pret-arg.c b/gcc/testsuite/gcc.c-torture/compile/pret-arg.c index a7fa856..d86d135 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pret-arg.c +++ b/gcc/testsuite/gcc.c-torture/compile/pret-arg.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + foo (a, b, c, d, e, f, g, h, i, j, xx) double xx; { diff --git a/gcc/testsuite/gcc.c-torture/compile/regs-arg-size.c b/gcc/testsuite/gcc.c-torture/compile/regs-arg-size.c index f5f0111..7751886 100644 --- a/gcc/testsuite/gcc.c-torture/compile/regs-arg-size.c +++ b/gcc/testsuite/gcc.c-torture/compile/regs-arg-size.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ + int foo; typedef long unsigned int size_t; typedef short unsigned int wchar_t; diff --git a/gcc/testsuite/gcc.c-torture/compile/structret.c b/gcc/testsuite/gcc.c-torture/compile/structret.c index 9c705d4..d99eaa63 100644 --- a/gcc/testsuite/gcc.c-torture/compile/structret.c +++ b/gcc/testsuite/gcc.c-torture/compile/structret.c @@ -1,3 +1,5 @@ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + struct foo { int a, b, c, d; diff --git a/gcc/testsuite/gcc.c-torture/compile/uuarg.c b/gcc/testsuite/gcc.c-torture/compile/uuarg.c index 930dd8a..875c7c3 100644 --- a/gcc/testsuite/gcc.c-torture/compile/uuarg.c +++ b/gcc/testsuite/gcc.c-torture/compile/uuarg.c @@ -1,4 +1,6 @@ /* { dg-require-effective-target untyped_assembly } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ + foo (a, b, c, d, e, f, g, h, i) { return foo () + i; diff --git a/gcc/testsuite/gcc.dg/20001009-1.c b/gcc/testsuite/gcc.dg/20001009-1.c index 1a55677..580e4b4 100644 --- a/gcc/testsuite/gcc.dg/20001009-1.c +++ b/gcc/testsuite/gcc.dg/20001009-1.c @@ -1,5 +1,6 @@ /* { dg-do compile { target fpic } } */ /* { dg-options "-O2 -fpic" } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ extern void foo (void *a, double x, double y); void diff --git a/gcc/testsuite/gcc.dg/20020418-1.c b/gcc/testsuite/gcc.dg/20020418-1.c index 7314ec0..456967f 100644 --- a/gcc/testsuite/gcc.dg/20020418-1.c +++ b/gcc/testsuite/gcc.dg/20020418-1.c @@ -2,6 +2,7 @@ /* { dg-do compile } */ /* { dg-options "-O2" } */ /* { dg-options "-O2 -msse -ffast-math" { target i?86-*-* x86_64-*-* } } */ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ void bar (float *a, float *b); diff --git a/gcc/testsuite/gcc.dg/20020426-2.c b/gcc/testsuite/gcc.dg/20020426-2.c index 9ad7a54..96517f7b 100644 --- a/gcc/testsuite/gcc.dg/20020426-2.c +++ b/gcc/testsuite/gcc.dg/20020426-2.c @@ -3,6 +3,7 @@ /* { dg-do run } */ /* { dg-options "-O2" } */ /* { dg-options "-O2 -frename-registers -fomit-frame-pointer -fPIC -mtune=i686" { target { { i?86-*-* x86_64-*-* } && { ia32 && fpic } } } } */ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ extern void exit (int); diff --git a/gcc/testsuite/gcc.dg/20020430-1.c b/gcc/testsuite/gcc.dg/20020430-1.c index 63915a2..f48bb67 100644 --- a/gcc/testsuite/gcc.dg/20020430-1.c +++ b/gcc/testsuite/gcc.dg/20020430-1.c @@ -6,6 +6,7 @@ /* { dg-do compile { target fpic } } */ /* { dg-options "-O2 -frename-registers -fpic" } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ typedef unsigned long XID; typedef XID Window; diff --git a/gcc/testsuite/gcc.dg/20040306-1.c b/gcc/testsuite/gcc.dg/20040306-1.c index 903d20a..8cac869 100644 --- a/gcc/testsuite/gcc.dg/20040306-1.c +++ b/gcc/testsuite/gcc.dg/20040306-1.c @@ -2,7 +2,7 @@ /* { dg-do compile } */ /* { dg-options "-O2" } */ - +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ typedef struct test { diff --git a/gcc/testsuite/gcc.dg/20040622-2.c b/gcc/testsuite/gcc.dg/20040622-2.c index 0be320f..e62ec36 100644 --- a/gcc/testsuite/gcc.dg/20040622-2.c +++ b/gcc/testsuite/gcc.dg/20040622-2.c @@ -1,5 +1,6 @@ /* { dg-do link } */ /* { dg-require-effective-target ptr32plus } */ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ /* This validates codegen for [r1+32760] on Darwin. */ void f(char x[32688], double *y, double *z) __attribute__((noinline)); void f(char x[32688], double *y, double *z) {} diff --git a/gcc/testsuite/gcc.dg/20050603-2.c b/gcc/testsuite/gcc.dg/20050603-2.c index 8c8e58e..a135e3e 100644 --- a/gcc/testsuite/gcc.dg/20050603-2.c +++ b/gcc/testsuite/gcc.dg/20050603-2.c @@ -1,5 +1,6 @@ /* { dg-do run } */ /* { dg-options "-O2" } */ +/* { dg-skip-if "no stdlib.h in eBPF" { bpf-*-* } } */ #include struct s { unsigned short f: 16; diff --git a/gcc/testsuite/gcc.dg/20050629-1.c b/gcc/testsuite/gcc.dg/20050629-1.c index 0dd47f7..99d9ce8 100644 --- a/gcc/testsuite/gcc.dg/20050629-1.c +++ b/gcc/testsuite/gcc.dg/20050629-1.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-O2 -w" } */ +/* { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ /* This file was automatically reduced from tree-ssa-operands.c. It contains many warnings, but it exposes a copy propagation bug that diff --git a/gcc/testsuite/gcc.dg/20061026.c b/gcc/testsuite/gcc.dg/20061026.c index 741ea2e..fa8069c 100644 --- a/gcc/testsuite/gcc.dg/20061026.c +++ b/gcc/testsuite/gcc.dg/20061026.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-O1" } */ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ /* This testcase failed on s390. The frame size for function f will be exactly 32768 bytes. The back end has to recognize that this is to diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-3.c b/gcc/testsuite/gcc.dg/Warray-bounds-3.c index 773f463..f119502 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-3.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-3.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-O2 -Warray-bounds" } */ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ /* based on PR 31227 */ typedef __SIZE_TYPE__ size_t; diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-30.c b/gcc/testsuite/gcc.dg/Warray-bounds-30.c index ac7e9a6..b996568 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-30.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-30.c @@ -1,7 +1,8 @@ /* PR tree-optimization/84047 - missing -Warray-bounds on an out-of-bounds index into an array { dg-do compile } - { dg-options "-O2 -Warray-bounds=2 -ftrack-macro-expansion=0" } */ + { dg-options "-O2 -Warray-bounds=2 -ftrack-macro-expansion=0" } + { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ #include "range.h" diff --git a/gcc/testsuite/gcc.dg/Wframe-larger-than-2.c b/gcc/testsuite/gcc.dg/Wframe-larger-than-2.c index 1a5402f..d7068d0 100644 --- a/gcc/testsuite/gcc.dg/Wframe-larger-than-2.c +++ b/gcc/testsuite/gcc.dg/Wframe-larger-than-2.c @@ -1,6 +1,7 @@ /* Exercise -Wframe-larger-than= with a byte-size suffix. { dg-do compile } - { dg-options "-O -Wframe-larger-than=1KB" } */ + { dg-options "-O -Wframe-larger-than=1KB" } + { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ extern void f (void*, ...); diff --git a/gcc/testsuite/gcc.dg/Wframe-larger-than.c b/gcc/testsuite/gcc.dg/Wframe-larger-than.c index fab0adf..8a40cf3 100644 --- a/gcc/testsuite/gcc.dg/Wframe-larger-than.c +++ b/gcc/testsuite/gcc.dg/Wframe-larger-than.c @@ -4,6 +4,7 @@ /* { dg-do compile } */ /* { dg-options "-Wframe-larger-than=2048" } */ +/* { dg-skip-if "exceeds eBPF stack limit" { bpf-*-* } } */ extern void func(char *); diff --git a/gcc/testsuite/gcc.dg/Wrestrict-11.c b/gcc/testsuite/gcc.dg/Wrestrict-11.c index 7b4b5aa..07b9cdd 100644 --- a/gcc/testsuite/gcc.dg/Wrestrict-11.c +++ b/gcc/testsuite/gcc.dg/Wrestrict-11.c @@ -3,7 +3,8 @@ that calls to strncpy involving multidimensional arrays of structs don't trigger false positive -Wrestrict warnings. { dg-do compile } - { dg-options "-O2 -Wrestrict -ftrack-macro-expansion=0" } */ + { dg-options "-O2 -Wrestrict -ftrack-macro-expansion=0" } + { dg-skip-if "too many arguments in function call" { bpf-*-* } } */ typedef __SIZE_TYPE__ size_t; diff --git a/gcc/testsuite/gcc.dg/builtins-config.h b/gcc/testsuite/gcc.dg/builtins-config.h index f00e91a..5e27c1d 100644 --- a/gcc/testsuite/gcc.dg/builtins-config.h +++ b/gcc/testsuite/gcc.dg/builtins-config.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004, 2005, 2006, 2009, 2011, 2012 +/* Copyright (C) 2003, 2004, 2005, 2006, 2009, 2011, 2012, 2019 Free Software Foundation. Define macros useful in tests for bulitin functions. */ @@ -20,6 +20,8 @@ /* FreeBSD up to version 8 lacks support for cexp and friends. */ #elif defined(__vxworks) /* VxWorks doesn't have a full C99 time. (cabs is missing, for example.) */ +#elif defined (__BPF__) +/* No chance for eBPF to support C99 functions. */ #elif defined(_WIN32) && !defined(__CYGWIN__) /* Windows doesn't have the entire C99 runtime. */ #elif (defined(__APPLE__) && defined(__ppc__) \ diff --git a/gcc/testsuite/gcc.target/bpf/bpf.exp b/gcc/testsuite/gcc.target/bpf/bpf.exp new file mode 100644 index 0000000..e5c8cfc --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/bpf.exp @@ -0,0 +1,41 @@ +# Copyright (C) 2019 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# GCC testsuite that uses the `dg.exp' driver. + +# Exit immediately if this isn't an eBPF target. +if ![istarget bpf-*-*] then { + return +} + +# Load support procs. +load_lib gcc-dg.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_CFLAGS +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS " -ansi -pedantic-errors" +} + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \ + "" $DEFAULT_CFLAGS + +# All done. +dg-finish diff --git a/gcc/testsuite/gcc.target/bpf/builtin-load.c b/gcc/testsuite/gcc.target/bpf/builtin-load.c new file mode 100644 index 0000000..0f93d91 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/builtin-load.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O0 -std=gnu99" } */ + +void foo () +{ + long long ll, off; + + /* Indirect. */ + ll = __builtin_bpf_load_byte (off); + ll = __builtin_bpf_load_half (off); + ll = __builtin_bpf_load_word (off); + + /* Absolute. */ + ll = __builtin_bpf_load_byte (0); + ll = __builtin_bpf_load_half (4); + ll = __builtin_bpf_load_word (8); +} + +/* { dg-final { scan-assembler "ldindb\t%r.,0.*ldindh\t%r.,0.*ldindw\t%r.,0" } } */ +/* { dg-final { scan-assembler "ldabsb\t0.*ldabsh\t4.*ldabsw\t8" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/constant-calls.c b/gcc/testsuite/gcc.target/bpf/constant-calls.c new file mode 100644 index 0000000..84612a9 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/constant-calls.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-xfail-if "" { bpf-*-* } } */ + +typedef void *(*T)(void); +f1 () +{ + ((T) 0)(); +} +f2 () +{ + ((T) 1000)(); +} +f3 () +{ + ((T) 1000000)(); +} + +/* { dg-final { scan-assembler "call\t0" } } */ +/* { dg-final { scan-assembler "call\t1000" } } */ +/* { dg-final { scan-assembler "call\t10000" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/diag-funargs-2.c b/gcc/testsuite/gcc.target/bpf/diag-funargs-2.c new file mode 100644 index 0000000..7c991af --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/diag-funargs-2.c @@ -0,0 +1,26 @@ +/* Verify proper errors are generated for functions taking too many + arguments, with aggregates and 128-bit arguments. */ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +#include + +struct ja +{ + long i1; + long i2; + long i3; + long i4; + long i5; + long i6; +}; + +void jorl (struct ja, unsigned __int128, unsigned __int128, int i3); + +int foo () +{ + struct ja je; + jorl (je, 1, 2, 3); /* { dg-error "too many function arguments" } */ + return 2L /1; +} + diff --git a/gcc/testsuite/gcc.target/bpf/diag-funargs-3.c b/gcc/testsuite/gcc.target/bpf/diag-funargs-3.c new file mode 100644 index 0000000..d9d42c1 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/diag-funargs-3.c @@ -0,0 +1,26 @@ +/* Verify proper errors are generated for functions taking too many + arguments, with aggregates and 128-bit arguments. */ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +#include + +struct ja +{ + long i1; + long i2; + long i3; + long i4; + long i5; + long i6; +}; + +void jorl (struct ja, int, int, int, unsigned __int128); + +int foo () +{ + struct ja je; + jorl (je, 1, 2, 3, 4); /* { dg-error "too many function arguments" } */ + return 2L /1; +} + diff --git a/gcc/testsuite/gcc.target/bpf/diag-funargs.c b/gcc/testsuite/gcc.target/bpf/diag-funargs.c new file mode 100644 index 0000000..d4e9c06 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/diag-funargs.c @@ -0,0 +1,15 @@ +/* Verify proper errors are generated for functions taking too many + arguments. */ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +int +foo (int a1, /* { dg-error "too many function arguments" } */ + int a2, + int a3, + int a4, + int a5, + int a6) +{ + return a6; +} diff --git a/gcc/testsuite/gcc.target/bpf/diag-indcalls.c b/gcc/testsuite/gcc.target/bpf/diag-indcalls.c new file mode 100644 index 0000000..9263fcf --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/diag-indcalls.c @@ -0,0 +1,11 @@ +/* Verify proper errors are generated for indirect function calls. */ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +void (*fnp) (void); + +void +foo () +{ + (*fnp) (); +} /* { dg-error "indirect call in function" } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-bind.c b/gcc/testsuite/gcc.target/bpf/helper-bind.c new file mode 100644 index 0000000..2d1fedc --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-bind.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *ctx, *addr; + int addr_len; + + ret = __builtin_bpf_helper_bind (ctx, addr, addr_len); +} + +/* { dg-final { scan-assembler "call\t64" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-bpf-redirect.c b/gcc/testsuite/gcc.target/bpf/helper-bpf-redirect.c new file mode 100644 index 0000000..844c88d --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-bpf-redirect.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + uint32_t ifindex; + uint64_t flags; + + ret = __builtin_bpf_helper_redirect (ifindex, flags); +} + +/* { dg-final { scan-assembler "call\t23" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-clone-redirect.c b/gcc/testsuite/gcc.target/bpf/helper-clone-redirect.c new file mode 100644 index 0000000..a4fb813 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-clone-redirect.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + uint32_t ifindex; + uint64_t flags; + + ret = __builtin_bpf_helper_clone_redirect (skb, ifindex, flags); +} + +/* { dg-final { scan-assembler "call\t13" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-csum-diff.c b/gcc/testsuite/gcc.target/bpf/helper-csum-diff.c new file mode 100644 index 0000000..ef38192 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-csum-diff.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int64_t ret; + int32_t *to, *from; + uint64_t to_size, from_size; + int seed; + + ret = __builtin_bpf_helper_csum_diff (from, from_size, to, to_size, seed); +} + +/* { dg-final { scan-assembler "call\t28" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-csum-update.c b/gcc/testsuite/gcc.target/bpf/helper-csum-update.c new file mode 100644 index 0000000..3cde867 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-csum-update.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int64_t ret; + void *skb; + int csum; + + ret = __builtin_bpf_helper_csum_update (skb, csum); +} + +/* { dg-final { scan-assembler "call\t40" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-current-task-under-cgroup.c b/gcc/testsuite/gcc.target/bpf/helper-current-task-under-cgroup.c new file mode 100644 index 0000000..a7eb6e6 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-current-task-under-cgroup.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *map; + uint32_t index; + + ret = __builtin_bpf_helper_current_task_under_cgroup (map, index); +} + +/* { dg-final { scan-assembler "call\t37" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-fib-lookup.c b/gcc/testsuite/gcc.target/bpf/helper-fib-lookup.c new file mode 100644 index 0000000..9a9f79d --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-fib-lookup.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *ctx, *params; + int plen; + uint32_t flags; + + ret = __builtin_bpf_helper_fib_lookup (ctx, params, plen, flags); +} + +/* { dg-final { scan-assembler "call\t69" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-cgroup-classid.c b/gcc/testsuite/gcc.target/bpf/helper-get-cgroup-classid.c new file mode 100644 index 0000000..6cfd14d --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-cgroup-classid.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint32_t ret; + void *skb; + + ret = __builtin_bpf_helper_get_cgroup_classid (skb); +} + +/* { dg-final { scan-assembler "call\t17" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-current-cgroup-id.c b/gcc/testsuite/gcc.target/bpf/helper-get-current-cgroup-id.c new file mode 100644 index 0000000..916dc4d --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-current-cgroup-id.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint64_t ret; + + ret = __builtin_bpf_helper_get_current_cgroup_id (); +} + +/* { dg-final { scan-assembler "call\t80" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-current-comm.c b/gcc/testsuite/gcc.target/bpf/helper-get-current-comm.c new file mode 100644 index 0000000..efc330c --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-current-comm.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *buf; + uint32_t size_of_buf; + + ret = __builtin_bpf_helper_get_current_comm (buf, size_of_buf); +} + +/* { dg-final { scan-assembler "call\t16" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-current-pid-tgid.c b/gcc/testsuite/gcc.target/bpf/helper-get-current-pid-tgid.c new file mode 100644 index 0000000..32d3e9c --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-current-pid-tgid.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint64_t ret; + + ret = __builtin_bpf_helper_get_current_pid_tgid (); +} + +/* { dg-final { scan-assembler "call\t14" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-current-task.c b/gcc/testsuite/gcc.target/bpf/helper-get-current-task.c new file mode 100644 index 0000000..016c134 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-current-task.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint64_t ret; + + ret = __builtin_bpf_helper_get_current_task (); +} + +/* { dg-final { scan-assembler "call\t35" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-current-uid-gid.c b/gcc/testsuite/gcc.target/bpf/helper-get-current-uid-gid.c new file mode 100644 index 0000000..1dc2f9f --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-current-uid-gid.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint64_t ret; + + ret = __builtin_bpf_helper_get_current_uid_gid (); +} + +/* { dg-final { scan-assembler "call\t15" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-hash-recalc.c b/gcc/testsuite/gcc.target/bpf/helper-get-hash-recalc.c new file mode 100644 index 0000000..1db5d87 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-hash-recalc.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint32_t ret; + void *skb; + + ret = __builtin_bpf_helper_get_hash_recalc (skb); +} + +/* { dg-final { scan-assembler "call\t34" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-listener-sock.c b/gcc/testsuite/gcc.target/bpf/helper-get-listener-sock.c new file mode 100644 index 0000000..298da1c --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-listener-sock.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + void *ret, *sk; + + ret = __builtin_bpf_helper_get_listener_sock (sk); +} + +/* { dg-final { scan-assembler "call\t98" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-local-storage.c b/gcc/testsuite/gcc.target/bpf/helper-get-local-storage.c new file mode 100644 index 0000000..88da67e --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-local-storage.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + void *ret, *map; + uint64_t flags; + + ret = __builtin_bpf_helper_get_local_storage (map, flags); +} + +/* { dg-final { scan-assembler "call\t81" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-numa-node-id.c b/gcc/testsuite/gcc.target/bpf/helper-get-numa-node-id.c new file mode 100644 index 0000000..628e101 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-numa-node-id.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + + ret = __builtin_bpf_helper_get_numa_node_id (); +} + +/* { dg-final { scan-assembler "call\t42" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-prandom-u32.c b/gcc/testsuite/gcc.target/bpf/helper-get-prandom-u32.c new file mode 100644 index 0000000..6d3e5bc --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-prandom-u32.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint32_t ret; + + ret = __builtin_bpf_helper_get_prandom_u32 (); +} + +/* { dg-final { scan-assembler "call\t7" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-route-realm.c b/gcc/testsuite/gcc.target/bpf/helper-get-route-realm.c new file mode 100644 index 0000000..5056c4a --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-route-realm.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint32_t ret; + void *skb; + + ret = __builtin_bpf_helper_get_route_realm (skb); +} + +/* { dg-final { scan-assembler "call\t24" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-smp-processor-id.c b/gcc/testsuite/gcc.target/bpf/helper-get-smp-processor-id.c new file mode 100644 index 0000000..655b873 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-smp-processor-id.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint32_t ret; + + ret = __builtin_bpf_helper_get_smp_processor_id (); +} + +/* { dg-final { scan-assembler "call\t8" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-socket-cookie.c b/gcc/testsuite/gcc.target/bpf/helper-get-socket-cookie.c new file mode 100644 index 0000000..afd17dd --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-socket-cookie.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint64_t ret; + void *skb; + + ret = __builtin_bpf_helper_get_socket_cookie (skb); +} + +/* { dg-final { scan-assembler "call\t46" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-socket-uid.c b/gcc/testsuite/gcc.target/bpf/helper-get-socket-uid.c new file mode 100644 index 0000000..3a274c9 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-socket-uid.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint32_t ret; + void *skb; + + ret = __builtin_bpf_helper_get_socket_uid (skb); +} + +/* { dg-final { scan-assembler "call\t47" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-stack.c b/gcc/testsuite/gcc.target/bpf/helper-get-stack.c new file mode 100644 index 0000000..bbcdeb5 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-stack.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *regs, *buf; + uint32_t size; + uint64_t flags; + + ret = __builtin_bpf_helper_get_stack (regs, buf, size, flags); +} + +/* { dg-final { scan-assembler "call\t67" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-get-stackid.c b/gcc/testsuite/gcc.target/bpf/helper-get-stackid.c new file mode 100644 index 0000000..319d15c --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-get-stackid.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *ctx, *map; + uint64_t flags; + + ret = __builtin_bpf_helper_get_stackid (ctx, map, flags); +} + +/* { dg-final { scan-assembler "call\t27" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-getsockopt.c b/gcc/testsuite/gcc.target/bpf/helper-getsockopt.c new file mode 100644 index 0000000..fb16f15 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-getsockopt.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *bpf_socket; + int level, optname, optlen; + char *optval; + + ret = __builtin_bpf_helper_getsockopt (bpf_socket, level, + optname, optval, optlen); +} + +/* { dg-final { scan-assembler "call\t57" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-ktime-get-ns.c b/gcc/testsuite/gcc.target/bpf/helper-ktime-get-ns.c new file mode 100644 index 0000000..405df05 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-ktime-get-ns.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint64_t ret; + ret = __builtin_bpf_helper_ktime_get_ns (); +} + +/* { dg-final { scan-assembler "call\t5" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-l3-csum-replace.c b/gcc/testsuite/gcc.target/bpf/helper-l3-csum-replace.c new file mode 100644 index 0000000..ac17662 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-l3-csum-replace.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + uint32_t offset; + uint64_t from, to, size; + + ret = __builtin_bpf_helper_l3_csum_replace (skb, offset, from, to, size); +} + +/* { dg-final { scan-assembler "call\t10" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-l4-csum-replace.c b/gcc/testsuite/gcc.target/bpf/helper-l4-csum-replace.c new file mode 100644 index 0000000..52b5514 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-l4-csum-replace.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + uint32_t offset; + uint64_t from, to, size; + + ret = __builtin_bpf_helper_l4_csum_replace (skb, offset, from, to, size); +} + +/* { dg-final { scan-assembler "call\t11" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-lwt-push-encap.c b/gcc/testsuite/gcc.target/bpf/helper-lwt-push-encap.c new file mode 100644 index 0000000..1baed27 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-lwt-push-encap.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb, *hdr; + uint32_t type, len; + + ret = __builtin_bpf_helper_lwt_push_encap (skb, type, hdr, len); +} + +/* { dg-final { scan-assembler "call\t73" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-action.c b/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-action.c new file mode 100644 index 0000000..ccc94c1 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-action.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb, *param; + uint32_t action, param_len; + + ret = __builtin_bpf_helper_lwt_seg6_action (skb, action, + param, param_len); +} + +/* { dg-final { scan-assembler "call\t76" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-adjust-srh.c b/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-adjust-srh.c new file mode 100644 index 0000000..5e95124 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-adjust-srh.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + uint32_t offset, delta; + + ret = __builtin_bpf_helper_lwt_seg6_adjust_srh (skb, offset, + delta); +} + +/* { dg-final { scan-assembler "call\t75" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-store-bytes.c b/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-store-bytes.c new file mode 100644 index 0000000..098f976 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-store-bytes.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb, *from; + uint32_t offset, len; + + ret = __builtin_bpf_helper_lwt_seg6_store_bytes (skb, offset, + from, len); +} + +/* { dg-final { scan-assembler "call\t74" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-map-delete-elem.c b/gcc/testsuite/gcc.target/bpf/helper-map-delete-elem.c new file mode 100644 index 0000000..b8a6cde --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-map-delete-elem.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +char *map () { return 0; } + +void +foo () +{ + int ret; + char *key = 0; + + ret = __builtin_bpf_helper_map_delete_elem (map (), key); +} + +/* { dg-final { scan-assembler "call\t3" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-map-lookup-elem.c b/gcc/testsuite/gcc.target/bpf/helper-map-lookup-elem.c new file mode 100644 index 0000000..839cfc4 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-map-lookup-elem.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ + +char *map () { return 0; } + +void +foo () +{ + char *key = 0, *value = 0; + value = __builtin_bpf_helper_map_lookup_elem (map (), key); +} + +/* { dg-final { scan-assembler "call\t1" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-map-peek-elem.c b/gcc/testsuite/gcc.target/bpf/helper-map-peek-elem.c new file mode 100644 index 0000000..6d0acb1 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-map-peek-elem.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +char *map () { return 0; } + +void +foo () +{ + int ret; + char *value = 0; + + ret = __builtin_bpf_helper_map_peek_elem (map (), value); +} + +/* { dg-final { scan-assembler "call\t89" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-map-pop-elem.c b/gcc/testsuite/gcc.target/bpf/helper-map-pop-elem.c new file mode 100644 index 0000000..71a7851 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-map-pop-elem.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +char *map () { return 0; } + +void +foo () +{ + int ret; + char *value = 0; + + ret = __builtin_bpf_helper_map_pop_elem (map (), value); +} + +/* { dg-final { scan-assembler "call\t88" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-map-push-elem.c b/gcc/testsuite/gcc.target/bpf/helper-map-push-elem.c new file mode 100644 index 0000000..53bc0ac --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-map-push-elem.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-std=gnu99" } */ + +char *map () { return 0; } + +void +foo () +{ + int ret; + char *value = 0; + long long flags = 0; + + ret = __builtin_bpf_helper_map_push_elem (map (), value, flags); +} + +/* { dg-final { scan-assembler "call\t87" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-map-update-elem.c b/gcc/testsuite/gcc.target/bpf/helper-map-update-elem.c new file mode 100644 index 0000000..6281442 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-map-update-elem.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-std=gnu99" } */ + +char *map () { return 0; } + +void +foo () +{ + int ret; + long long flags = 0; + char *key = 0, *value = 0; + + ret = __builtin_bpf_helper_map_update_elem (map (), key, value, flags); +} + +/* { dg-final { scan-assembler "call\t2" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-msg-apply-bytes.c b/gcc/testsuite/gcc.target/bpf/helper-msg-apply-bytes.c new file mode 100644 index 0000000..3b831ac --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-msg-apply-bytes.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *msg; + uint32_t bytes; + + ret = __builtin_bpf_helper_msg_apply_bytes (msg, bytes); +} + +/* { dg-final { scan-assembler "call\t61" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-msg-cork-bytes.c b/gcc/testsuite/gcc.target/bpf/helper-msg-cork-bytes.c new file mode 100644 index 0000000..2c4ee21 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-msg-cork-bytes.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *msg; + uint32_t bytes; + + ret = __builtin_bpf_helper_msg_cork_bytes (msg, bytes); +} + +/* { dg-final { scan-assembler "call\t62" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-msg-pop-data.c b/gcc/testsuite/gcc.target/bpf/helper-msg-pop-data.c new file mode 100644 index 0000000..377c036 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-msg-pop-data.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + uint32_t start, pop; + uint64_t flags; + + ret = __builtin_bpf_helper_msg_pop_data (skb, start, pop, flags); +} + +/* { dg-final { scan-assembler "call\t91" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-msg-pull-data.c b/gcc/testsuite/gcc.target/bpf/helper-msg-pull-data.c new file mode 100644 index 0000000..ef27493 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-msg-pull-data.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *msg; + uint32_t start, end; + uint64_t flags; + + ret = __builtin_bpf_helper_msg_pull_data (msg, start, end, flags); +} + +/* { dg-final { scan-assembler "call\t63" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-msg-push-data.c b/gcc/testsuite/gcc.target/bpf/helper-msg-push-data.c new file mode 100644 index 0000000..9e256bc --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-msg-push-data.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + uint32_t start, len; + uint64_t flags; + + ret = __builtin_bpf_helper_msg_push_data (skb, start, len, flags); +} + +/* { dg-final { scan-assembler "call\t90" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-msg-redirect-hash.c b/gcc/testsuite/gcc.target/bpf/helper-msg-redirect-hash.c new file mode 100644 index 0000000..2e9d413 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-msg-redirect-hash.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *msg, *map, *key; + uint64_t flags; + + ret = __builtin_bpf_helper_msg_redirect_hash (msg, map, key, + flags); +} + +/* { dg-final { scan-assembler "call\t71" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-msg-redirect-map.c b/gcc/testsuite/gcc.target/bpf/helper-msg-redirect-map.c new file mode 100644 index 0000000..f5f8405 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-msg-redirect-map.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *msg, *map; + uint64_t key; + uint64_t flags; + + ret = __builtin_bpf_helper_msg_redirect_map (msg, map, key, + flags); +} + +/* { dg-final { scan-assembler "call\t60" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-override-return.c b/gcc/testsuite/gcc.target/bpf/helper-override-return.c new file mode 100644 index 0000000..3bd5424 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-override-return.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *regs; + uint64_t rc; + + ret = __builtin_bpf_helper_override_return (regs, rc); +} + +/* { dg-final { scan-assembler "call\t58" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-perf-event-output.c b/gcc/testsuite/gcc.target/bpf/helper-perf-event-output.c new file mode 100644 index 0000000..afb3201 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-perf-event-output.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *ctx, *map; + uint64_t flags; + void *data; + uint64_t size; + + ret = __builtin_bpf_helper_perf_event_output (ctx, map, flags, data, size); +} + +/* { dg-final { scan-assembler "call\t25" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-perf-event-read-value.c b/gcc/testsuite/gcc.target/bpf/helper-perf-event-read-value.c new file mode 100644 index 0000000..1d512c9 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-perf-event-read-value.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *map, *buf; + uint64_t flags; + uint64_t buf_size; + + ret = __builtin_bpf_helper_perf_event_read_value (map, flags, buf, buf_size); +} + +/* { dg-final { scan-assembler "call\t55" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-perf-event-read.c b/gcc/testsuite/gcc.target/bpf/helper-perf-event-read.c new file mode 100644 index 0000000..f099a09 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-perf-event-read.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint64_t ret; + void *map; + uint64_t flags; + + ret = __builtin_bpf_helper_perf_event_read (map, flags); +} + +/* { dg-final { scan-assembler "call\t22" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-perf-prog-read-value.c b/gcc/testsuite/gcc.target/bpf/helper-perf-prog-read-value.c new file mode 100644 index 0000000..00c4a3a --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-perf-prog-read-value.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *ctx, *buf; + uint64_t buf_size; + + ret = __builtin_bpf_helper_perf_prog_read_value (ctx, buf, buf_size); +} + +/* { dg-final { scan-assembler "call\t56" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-probe-read-str.c b/gcc/testsuite/gcc.target/bpf/helper-probe-read-str.c new file mode 100644 index 0000000..fd04760 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-probe-read-str.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + int size; + void *dst; + const void *unsafe_ptr; + + ret = __builtin_bpf_helper_probe_read_str (dst, size, unsafe_ptr); +} + +/* { dg-final { scan-assembler "call\t45" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-probe-read.c b/gcc/testsuite/gcc.target/bpf/helper-probe-read.c new file mode 100644 index 0000000..a77a907 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-probe-read.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *src, *dst; + uint32_t size; + + ret = __builtin_bpf_helper_probe_read (dst, size, src); +} + +/* { dg-final { scan-assembler "call\t4" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-probe-write-user.c b/gcc/testsuite/gcc.target/bpf/helper-probe-write-user.c new file mode 100644 index 0000000..bf22620 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-probe-write-user.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *dst, *src; + uint32_t len; + + ret = __builtin_bpf_helper_probe_write_user (dst, src, len); +} + +/* { dg-final { scan-assembler "call\t36" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-rc-keydown.c b/gcc/testsuite/gcc.target/bpf/helper-rc-keydown.c new file mode 100644 index 0000000..58e9395 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-rc-keydown.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *ctx; + uint32_t protocol, toggle; + uint64_t scancode; + + ret = __builtin_bpf_helper_rc_keydown (ctx, protocol, + scancode, toggle); +} + +/* { dg-final { scan-assembler "call\t78" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-rc-pointer-rel.c b/gcc/testsuite/gcc.target/bpf/helper-rc-pointer-rel.c new file mode 100644 index 0000000..e776bc7 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-rc-pointer-rel.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *ctx; + int32_t rel_x, rel_y; + + ret = __builtin_bpf_helper_rc_pointer_rel (ctx, rel_x, rel_y); +} + +/* { dg-final { scan-assembler "call\t92" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-rc-repeat.c b/gcc/testsuite/gcc.target/bpf/helper-rc-repeat.c new file mode 100644 index 0000000..0ebc7de --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-rc-repeat.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *ctx; + + ret = __builtin_bpf_helper_rc_repeat (ctx); +} + +/* { dg-final { scan-assembler "call\t77" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-redirect-map.c b/gcc/testsuite/gcc.target/bpf/helper-redirect-map.c new file mode 100644 index 0000000..daeecc2 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-redirect-map.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *map; + uint32_t key; + uint64_t flags; + + ret = __builtin_bpf_helper_redirect_map (map, key, flags); +} + +/* { dg-final { scan-assembler "call\t51" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-set-hash-invalid.c b/gcc/testsuite/gcc.target/bpf/helper-set-hash-invalid.c new file mode 100644 index 0000000..4bc63ff --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-set-hash-invalid.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + void *skb; + + __builtin_bpf_helper_set_hash_invalid (skb); +} + +/* { dg-final { scan-assembler "call\t41" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-set-hash.c b/gcc/testsuite/gcc.target/bpf/helper-set-hash.c new file mode 100644 index 0000000..d01ae6e --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-set-hash.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint32_t ret; + void *skb; + uint32_t hash; + + ret = __builtin_bpf_helper_set_hash (skb, hash); +} + +/* { dg-final { scan-assembler "call\t48" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-setsockopt.c b/gcc/testsuite/gcc.target/bpf/helper-setsockopt.c new file mode 100644 index 0000000..6f3b450 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-setsockopt.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *bpf_socket; + int level; + int optname; + void *optval; + int optlen; + + ret = __builtin_bpf_helper_setsockopt (bpf_socket, level, optname, + optval, optlen); +} + +/* { dg-final { scan-assembler "call\t49" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-fullsock.c b/gcc/testsuite/gcc.target/bpf/helper-sk-fullsock.c new file mode 100644 index 0000000..abe813d --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sk-fullsock.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + void *ret, *sk; + + ret = __builtin_bpf_helper_sk_fullsock (sk); +} + +/* { dg-final { scan-assembler "call\t95" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-lookup-tcp.c b/gcc/testsuite/gcc.target/bpf/helper-sk-lookup-tcp.c new file mode 100644 index 0000000..4408640 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sk-lookup-tcp.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + void *ret; + void *ctx, *tuple; + uint32_t tuple_size; + uint64_t netns, flags; + + ret = __builtin_bpf_helper_sk_lookup_tcp (ctx, + tuple, + tuple_size, + netns, flags); +} + +/* { dg-final { scan-assembler "call\t84" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-lookup-upd.c b/gcc/testsuite/gcc.target/bpf/helper-sk-lookup-upd.c new file mode 100644 index 0000000..4c50f9c --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sk-lookup-upd.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + void *ret; + void *ctx, *tuple; + uint32_t tuple_size; + uint64_t netns, flags; + + ret = __builtin_bpf_helper_sk_lookup_udp (ctx, + tuple, + tuple_size, + netns, flags); +} + +/* { dg-final { scan-assembler "call\t85" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-redirect-hash.c b/gcc/testsuite/gcc.target/bpf/helper-sk-redirect-hash.c new file mode 100644 index 0000000..7047c9f --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sk-redirect-hash.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb, *map, *key; + uint64_t flags; + + ret = __builtin_bpf_helper_sk_redirect_hash (skb, map, key, + flags); +} + +/* { dg-final { scan-assembler "call\t72" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-redirect-map.c b/gcc/testsuite/gcc.target/bpf/helper-sk-redirect-map.c new file mode 100644 index 0000000..5afb0ac --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sk-redirect-map.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *ctx, *map; + uint32_t key; + uint64_t flags; + + ret = __builtin_bpf_helper_sk_redirect_map (ctx, map, key, flags); +} + +/* { dg-final { scan-assembler "call\t52" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-release.c b/gcc/testsuite/gcc.target/bpf/helper-sk-release.c new file mode 100644 index 0000000..f054c90 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sk-release.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *sock; + + ret = __builtin_bpf_helper_sk_release (sock); +} + +/* { dg-final { scan-assembler "call\t86" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-select-reuseport.c b/gcc/testsuite/gcc.target/bpf/helper-sk-select-reuseport.c new file mode 100644 index 0000000..399ad2c --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sk-select-reuseport.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *reuse, *map, *key; + uint64_t flags; + + ret = __builtin_bpf_helper_sk_select_reuseport (reuse, map, + key, flags); +} + +/* { dg-final { scan-assembler "call\t82" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-storage-delete.c b/gcc/testsuite/gcc.target/bpf/helper-sk-storage-delete.c new file mode 100644 index 0000000..07c5875 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sk-storage-delete.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *map, *sk; + + ret = __builtin_bpf_helper_sk_storage_delete (map, sk); +} + +/* { dg-final { scan-assembler "call\t108" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sk-storage-get.c b/gcc/testsuite/gcc.target/bpf/helper-sk-storage-get.c new file mode 100644 index 0000000..a199ef0 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sk-storage-get.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + void *ret; + void *map, *sk, *value; + uint64_t flags; + + ret = __builtin_bpf_helper_sk_storage_get (map, sk, value, + flags); +} + +/* { dg-final { scan-assembler "call\t107" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-adjust-room.c b/gcc/testsuite/gcc.target/bpf/helper-skb-adjust-room.c new file mode 100644 index 0000000..88196f5 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-adjust-room.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + int32_t len_diff; + uint32_t mode; + uint64_t flags; + + ret = __builtin_bpf_helper_skb_adjust_room (skb, len_diff, mode, flags); +} + +/* { dg-final { scan-assembler "call\t50" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-cgroup-id.c b/gcc/testsuite/gcc.target/bpf/helper-skb-cgroup-id.c new file mode 100644 index 0000000..7c9021e --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-cgroup-id.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + uint64_t ret; + void *skb; + + ret = __builtin_bpf_helper_skb_cgroup_id (skb); +} + +/* { dg-final { scan-assembler "call\t79" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-change-head.c b/gcc/testsuite/gcc.target/bpf/helper-skb-change-head.c new file mode 100644 index 0000000..de62815 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-change-head.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + uint32_t len; + uint64_t flags; + + ret = __builtin_bpf_helper_skb_change_head (skb, len, flags); +} + +/* { dg-final { scan-assembler "call\t43" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-change-proto.c b/gcc/testsuite/gcc.target/bpf/helper-skb-change-proto.c new file mode 100644 index 0000000..5738f3c --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-change-proto.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + int16_t proto; + uint64_t flags; + + ret = __builtin_bpf_helper_skb_change_proto (skb, proto, flags); +} + +/* { dg-final { scan-assembler "call\t31" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-change-tail.c b/gcc/testsuite/gcc.target/bpf/helper-skb-change-tail.c new file mode 100644 index 0000000..1fb6b45 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-change-tail.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + uint32_t len; + uint64_t flags; + + ret = __builtin_bpf_helper_skb_change_tail (skb, len, flags); +} + +/* { dg-final { scan-assembler "call\t38" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-change-type.c b/gcc/testsuite/gcc.target/bpf/helper-skb-change-type.c new file mode 100644 index 0000000..bcf22ce --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-change-type.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + uint32_t type; + + ret = __builtin_bpf_helper_skb_change_type (skb, type); +} + +/* { dg-final { scan-assembler "call\t32" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-ecn-set-ce.c b/gcc/testsuite/gcc.target/bpf/helper-skb-ecn-set-ce.c new file mode 100644 index 0000000..f769993 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-ecn-set-ce.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + + ret = __builtin_bpf_helper_skb_ecn_set_ce (skb); +} + +/* { dg-final { scan-assembler "call\t97" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-key.c b/gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-key.c new file mode 100644 index 0000000..0d4db23 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-key.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb, *key; + uint32_t size; + uint64_t flags; + + ret = __builtin_bpf_helper_skb_get_tunnel_key (skb, key, size, flags); +} + +/* { dg-final { scan-assembler "call\t20" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-opt.c b/gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-opt.c new file mode 100644 index 0000000..9428657 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-opt.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + uint8_t *opt; + uint32_t size; + + ret = __builtin_bpf_helper_skb_get_tunnel_opt (skb, opt, size); +} + +/* { dg-final { scan-assembler "call\t29" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-get-xfrm-state.c b/gcc/testsuite/gcc.target/bpf/helper-skb-get-xfrm-state.c new file mode 100644 index 0000000..8217b4a --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-get-xfrm-state.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb, *xfrm_state; + uint32_t index, size; + uint64_t flags; + + ret = __builtin_bpf_helper_skb_get_xfrm_state (skb, index, + xfrm_state, size, flags); +} + +/* { dg-final { scan-assembler "call\t66" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes-relative.c b/gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes-relative.c new file mode 100644 index 0000000..bcaa43b --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes-relative.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb, *to; + uint32_t offset, len, start_header; + + ret = __builtin_bpf_helper_skb_load_bytes_relative (skb, offset, + to, len, + start_header); +} + +/* { dg-final { scan-assembler "call\t68" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes.c b/gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes.c new file mode 100644 index 0000000..9da5454 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb, *to; + uint32_t offset, len; + + ret = __builtin_bpf_helper_skb_load_bytes (skb, offset, to, len); +} + +/* { dg-final { scan-assembler "call\t26" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-pull-data.c b/gcc/testsuite/gcc.target/bpf/helper-skb-pull-data.c new file mode 100644 index 0000000..9bb8b8d --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-pull-data.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + uint32_t len; + + ret = __builtin_bpf_helper_skb_pull_data (skb, len); +} + +/* { dg-final { scan-assembler "call\t39" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-key.c b/gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-key.c new file mode 100644 index 0000000..21b835f --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-key.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb, *key; + uint32_t size; + uint64_t flags; + + ret = __builtin_bpf_helper_skb_set_tunnel_key (skb, key, size, flags); +} + +/* { dg-final { scan-assembler "call\t21" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-opt.c b/gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-opt.c new file mode 100644 index 0000000..5a0528e --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-opt.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + uint8_t *opt; + uint32_t size; + + ret = __builtin_bpf_helper_skb_set_tunnel_opt (skb, opt, size); +} + +/* { dg-final { scan-assembler "call\t30" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-store-bytes.c b/gcc/testsuite/gcc.target/bpf/helper-skb-store-bytes.c new file mode 100644 index 0000000..a41967c --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-store-bytes.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + uint32_t offset; + void *from; + uint32_t len; + uint64_t flags; + + ret = __builtin_bpf_helper_skb_store_bytes (skb, offset, from, len, flags); +} + +/* { dg-final { scan-assembler "call\t9" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-under-cgroup.c b/gcc/testsuite/gcc.target/bpf/helper-skb-under-cgroup.c new file mode 100644 index 0000000..0ccee8b --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-under-cgroup.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb, *map; + uint32_t index; + + ret = __builtin_bpf_helper_skb_under_cgroup (skb, map, index); +} + +/* { dg-final { scan-assembler "call\t33" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-vlan-pop.c b/gcc/testsuite/gcc.target/bpf/helper-skb-vlan-pop.c new file mode 100644 index 0000000..e99a0ac --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-vlan-pop.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + + ret = __builtin_bpf_helper_skb_vlan_pop (skb); +} + +/* { dg-final { scan-assembler "call\t19" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skb-vlan-push.c b/gcc/testsuite/gcc.target/bpf/helper-skb-vlan-push.c new file mode 100644 index 0000000..dbe52ae --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skb-vlan-push.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + int16_t vlan_proto; + uint16_t vlan_tci; + + ret = __builtin_bpf_helper_skb_vlan_push (skb, vlan_proto, vlan_tci); +} + +/* { dg-final { scan-assembler "call\t18" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-skc-lookup-tcp.c b/gcc/testsuite/gcc.target/bpf/helper-skc-lookup-tcp.c new file mode 100644 index 0000000..bbc4b99 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-skc-lookup-tcp.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + void *ret; + void *ctx, *tuple; + uint32_t tuple_size; + uint64_t netns, flags; + + ret = __builtin_bpf_helper_skc_lookup_tcp (ctx, tuple, + tuple_size, netns, flags); +} + +/* { dg-final { scan-assembler "call\t99" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sock-hash-update.c b/gcc/testsuite/gcc.target/bpf/helper-sock-hash-update.c new file mode 100644 index 0000000..bbb77ef --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sock-hash-update.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skops, *map, *key; + uint64_t flags; + + ret = __builtin_bpf_helper_sock_hash_update (skops, map, key, + flags); +} + +/* { dg-final { scan-assembler "call\t70" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sock-map-update.c b/gcc/testsuite/gcc.target/bpf/helper-sock-map-update.c new file mode 100644 index 0000000..301e59e --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sock-map-update.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skops, *map, *key; + uint64_t flags; + + ret = __builtin_bpf_helper_sock_map_update (skops, map, key, + flags); +} + +/* { dg-final { scan-assembler "call\t53" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sock-ops-cb-flags-set.c b/gcc/testsuite/gcc.target/bpf/helper-sock-ops-cb-flags-set.c new file mode 100644 index 0000000..2056312 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sock-ops-cb-flags-set.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *bpf_sock; + int argval; + + ret = __builtin_bpf_helper_sock_ops_cb_flags_set (bpf_sock, + argval); +} + +/* { dg-final { scan-assembler "call\t59" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-spin-lock.c b/gcc/testsuite/gcc.target/bpf/helper-spin-lock.c new file mode 100644 index 0000000..4178914 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-spin-lock.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + void *lock; + + __builtin_bpf_helper_spin_lock (lock); +} + +/* { dg-final { scan-assembler "call\t93" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-spin-unlock.c b/gcc/testsuite/gcc.target/bpf/helper-spin-unlock.c new file mode 100644 index 0000000..c2416b6 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-spin-unlock.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + void *lock; + + __builtin_bpf_helper_spin_unlock (lock); +} + +/* { dg-final { scan-assembler "call\t94" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-strtol.c b/gcc/testsuite/gcc.target/bpf/helper-strtol.c new file mode 100644 index 0000000..e15b6d6 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-strtol.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ + +#include +#include + +void +foo () +{ + int ret; + void *buf; + long res; + uint64_t flags; + size_t buf_len; + + ret = __builtin_bpf_helper_strtol (buf, buf_len, flags, &res); +} + +/* { dg-final { scan-assembler "call\t105" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-strtoul.c b/gcc/testsuite/gcc.target/bpf/helper-strtoul.c new file mode 100644 index 0000000..bc0d776 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-strtoul.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ + +#include +#include + +void +foo () +{ + int ret; + void *buf; + unsigned long res; + uint64_t flags; + size_t buf_len; + + ret = __builtin_bpf_helper_strtoul (buf, buf_len, flags, &res); +} + +/* { dg-final { scan-assembler "call\t106" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-current-value.c b/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-current-value.c new file mode 100644 index 0000000..8035841 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-current-value.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +#include +#include + +void +foo () +{ + int ret; + void *ctx, *buf; + size_t buf_len; + + ret = __builtin_bpf_helper_sysctl_get_current_value (ctx, buf, + buf_len); +} + +/* { dg-final { scan-assembler "call\t102" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-name.c b/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-name.c new file mode 100644 index 0000000..a748b4b --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-name.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ + +#include +#include + +void +foo () +{ + int ret; + void *ctx, *buf; + size_t buf_len; + uint64_t flags; + + ret = __builtin_bpf_helper_sysctl_get_name (ctx, buf, + buf_len, flags); +} + +/* { dg-final { scan-assembler "call\t101" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-new-value.c b/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-new-value.c new file mode 100644 index 0000000..2c48351 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sysctl-get-new-value.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +#include +#include + +void +foo () +{ + int ret; + void *ctx, *buf; + size_t buf_len; + + ret = __builtin_bpf_helper_sysctl_get_new_value (ctx, buf, + buf_len); +} + +/* { dg-final { scan-assembler "call\t103" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-sysctl-set-new-value.c b/gcc/testsuite/gcc.target/bpf/helper-sysctl-set-new-value.c new file mode 100644 index 0000000..fc3780d --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-sysctl-set-new-value.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +#include +#include + +void +foo () +{ + int ret; + void *ctx, *buf; + size_t buf_len; + + ret = __builtin_bpf_helper_sysctl_set_new_value (ctx, buf, + buf_len); +} + +/* { dg-final { scan-assembler "call\t104" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-tail-call.c b/gcc/testsuite/gcc.target/bpf/helper-tail-call.c new file mode 100644 index 0000000..618064f --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-tail-call.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + void *ctx, *prog_array_map; + uint32_t index; + + __builtin_bpf_helper_tail_call (ctx, prog_array_map, index); +} + +/* { dg-final { scan-assembler "call\t12" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-tcp-check-syncookie.c b/gcc/testsuite/gcc.target/bpf/helper-tcp-check-syncookie.c new file mode 100644 index 0000000..95846c6 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-tcp-check-syncookie.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *sk, *iph, *th; + uint32_t iph_len, th_len; + + ret = __builtin_bpf_helper_tcp_check_syncookie (sk, iph, + iph_len, + th, th_len); +} + +/* { dg-final { scan-assembler "call\t100" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-tcp-sock.c b/gcc/testsuite/gcc.target/bpf/helper-tcp-sock.c new file mode 100644 index 0000000..ab8f2de --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-tcp-sock.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + void *ret, *sk; + + ret = __builtin_bpf_helper_tcp_sock (sk); +} + +/* { dg-final { scan-assembler "call\t96" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-trace-printk.c b/gcc/testsuite/gcc.target/bpf/helper-trace-printk.c new file mode 100644 index 0000000..fcf9d5c --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-trace-printk.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +char *map () { return 0; } + +void +foo () +{ + int ret; + + ret = __builtin_bpf_helper_trace_printk ("foo %d %d", sizeof ("foo %d %d"), 10, 20); +} + +/* { dg-final { scan-assembler "call\t6" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-head.c b/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-head.c new file mode 100644 index 0000000..3dce543 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-head.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *xdp_md; + int delta; + + ret = __builtin_bpf_helper_xdp_adjust_head (xdp_md, delta); +} + +/* { dg-final { scan-assembler "call\t44" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-meta.c b/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-meta.c new file mode 100644 index 0000000..38a1374 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-meta.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *xdp_md; + int delta; + + ret = __builtin_bpf_helper_xdp_adjust_meta (xdp_md, delta); +} + +/* { dg-final { scan-assembler "call\t54" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-tail.c b/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-tail.c new file mode 100644 index 0000000..319b65a --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-tail.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *xdp_md; + int delta; + + ret = __builtin_bpf_helper_xdp_adjust_tail (xdp_md, delta); +} + +/* { dg-final { scan-assembler "call\t65" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/skb-ancestor-cgroup-id.c b/gcc/testsuite/gcc.target/bpf/skb-ancestor-cgroup-id.c new file mode 100644 index 0000000..ce193ec --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/skb-ancestor-cgroup-id.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +#include + +void +foo () +{ + int ret; + void *skb; + int ancestor_level; + + ret = __builtin_bpf_helper_skb_ancestor_cgroup_id (skb, + ancestor_level); +} + +/* { dg-final { scan-assembler "call\t83" } } */ diff --git a/gcc/testsuite/gcc.target/bpf/sync-fetch-and-add.c b/gcc/testsuite/gcc.target/bpf/sync-fetch-and-add.c new file mode 100644 index 0000000..69949f1 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/sync-fetch-and-add.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +long delta; +long *val; + +void +foo () +{ + __sync_fetch_and_add(val, delta); + __sync_fetch_and_add((int *)val, (int)delta); +} + +/* { dg-final { scan-assembler "xadddw\t.*" } } */ +/* { dg-final { scan-assembler "xaddw\t.*" } } */ diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 4d03cc0..3db1902 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -526,7 +526,8 @@ proc check_effective_target_trampolines { } { || [istarget nvptx-*-*] || [istarget hppa2.0w-hp-hpux11.23] || [istarget hppa64-hp-hpux11.23] - || [istarget pru-*-*] } { + || [istarget pru-*-*] + || [istarget bpf-*-*] } { return 0; } return 1 @@ -781,7 +782,7 @@ proc add_options_for_tls { flags } { # Return 1 if indirect jumps are supported, 0 otherwise. proc check_effective_target_indirect_jumps {} { - if { [istarget nvptx-*-*] } { + if { [istarget nvptx-*-*] || [istarget bpf-*-*] } { return 0 } return 1 @@ -790,7 +791,7 @@ proc check_effective_target_indirect_jumps {} { # Return 1 if nonlocal goto is supported, 0 otherwise. proc check_effective_target_nonlocal_goto {} { - if { [istarget nvptx-*-*] } { + if { [istarget nvptx-*-*] || [istarget bpf-*-*] } { return 0 } return 1 @@ -799,10 +800,9 @@ proc check_effective_target_nonlocal_goto {} { # Return 1 if global constructors are supported, 0 otherwise. proc check_effective_target_global_constructor {} { - if { [istarget nvptx-*-*] } { - return 0 - } - if { [istarget amdgcn-*-*] } { + if { [istarget nvptx-*-*] + || [istarget amdgcn-*-*] + || [istarget bpf-*-*] } { return 0 } return 1 @@ -825,6 +825,10 @@ proc check_effective_target_return_address {} { if { [istarget nvptx-*-*] } { return 0 } + # No notion of return address in eBPF. + if { [istarget bpf-*-*] } { + return 0 + } # It could be supported on amdgcn, but isn't yet. if { [istarget amdgcn*-*-*] } { return 0 -- cgit v1.1 From b245befcdd8ca0c38df47ea86537b92881490591 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 9 Sep 2019 12:26:50 +0200 Subject: re PR target/91704 ([X86] Codegen for _mm256_cmpgt_epi8 is affected by -funsigned-char) PR target/91704 * config/i386/avxintrin.h (__v32qs): New typedef. * config/i386/avx2intrin.h (_mm256_cmpgt_epi8): Use casts to __v32qs instead of __v32qi. * gcc.target/i386/pr91704.c: New test. From-SVN: r275507 --- gcc/ChangeLog | 7 +++++++ gcc/config/i386/avx2intrin.h | 2 +- gcc/config/i386/avxintrin.h | 1 + gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.target/i386/pr91704.c | 14 ++++++++++++++ 5 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr91704.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 34b2f62..fc56822 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2019-09-09 Jakub Jelinek + + PR target/91704 + * config/i386/avxintrin.h (__v32qs): New typedef. + * config/i386/avx2intrin.h (_mm256_cmpgt_epi8): Use casts to __v32qs + instead of __v32qi. + 2019-09-09 Jose E. Marchesi * doc/invoke.texi (Option Summary): Cover eBPF. diff --git a/gcc/config/i386/avx2intrin.h b/gcc/config/i386/avx2intrin.h index 7606efd..372d77f 100644 --- a/gcc/config/i386/avx2intrin.h +++ b/gcc/config/i386/avx2intrin.h @@ -258,7 +258,7 @@ extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_cmpgt_epi8 (__m256i __A, __m256i __B) { - return (__m256i) ((__v32qi)__A > (__v32qi)__B); + return (__m256i) ((__v32qs)__A > (__v32qs)__B); } extern __inline __m256i diff --git a/gcc/config/i386/avxintrin.h b/gcc/config/i386/avxintrin.h index c8f8d53..95a9e01 100644 --- a/gcc/config/i386/avxintrin.h +++ b/gcc/config/i386/avxintrin.h @@ -47,6 +47,7 @@ typedef unsigned int __v8su __attribute__ ((__vector_size__ (32))); typedef short __v16hi __attribute__ ((__vector_size__ (32))); typedef unsigned short __v16hu __attribute__ ((__vector_size__ (32))); typedef char __v32qi __attribute__ ((__vector_size__ (32))); +typedef signed char __v32qs __attribute__ ((__vector_size__ (32))); typedef unsigned char __v32qu __attribute__ ((__vector_size__ (32))); /* The Intel API is flexible enough that we must allow aliasing with other diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index faa487f..d1c448a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-09 Jakub Jelinek + + PR target/91704 + * gcc.target/i386/pr91704.c: New test. + 2019-09-09 Jose E. Marchesi * gcc.dg/builtins-config.h: eBPF doesn't support C99 standard diff --git a/gcc/testsuite/gcc.target/i386/pr91704.c b/gcc/testsuite/gcc.target/i386/pr91704.c new file mode 100644 index 0000000..b996e24 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr91704.c @@ -0,0 +1,14 @@ +/* PR target/91704 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -funsigned-char -mavx2 -mavx512f -masm=att" } */ +/* { dg-final { scan-assembler-times "\tvpcmpgtb\t%ymm" 1 } } */ +/* { dg-final { scan-assembler-not "\tvpsubusb\t" } } */ +/* { dg-final { scan-assembler-not "\tvpcmpeqb\t" } } */ + +#include + +__m256i +foo (__m256i x, __m256i y) +{ + return _mm256_cmpgt_epi8 (x, y); +} -- cgit v1.1 From ca47c3987c09df50cd9504652e4a8f6f8656bf94 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 9 Sep 2019 12:31:02 +0200 Subject: re PR target/87853 (_mm_cmpgt_epi8 broken with -funsigned-char) PR target/87853 * config/i386/emmintrin.h (_mm_cmpeq_epi8): Use casts to __v16qi instead of __v16qs. * gcc.target/i386/pr87853.c: New test. From-SVN: r275508 --- gcc/ChangeLog | 4 ++++ gcc/config/i386/emmintrin.h | 2 +- gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/gcc.target/i386/pr87853.c | 20 ++++++++++++++++++++ 4 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr87853.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fc56822..6c749d2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,9 @@ 2019-09-09 Jakub Jelinek + PR target/87853 + * config/i386/emmintrin.h (_mm_cmpeq_epi8): Use casts to __v16qi + instead of __v16qs. + PR target/91704 * config/i386/avxintrin.h (__v32qs): New typedef. * config/i386/avx2intrin.h (_mm256_cmpgt_epi8): Use casts to __v32qs diff --git a/gcc/config/i386/emmintrin.h b/gcc/config/i386/emmintrin.h index f9e7b33..1683d84 100644 --- a/gcc/config/i386/emmintrin.h +++ b/gcc/config/i386/emmintrin.h @@ -1308,7 +1308,7 @@ _mm_xor_si128 (__m128i __A, __m128i __B) extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_cmpeq_epi8 (__m128i __A, __m128i __B) { - return (__m128i) ((__v16qs)__A == (__v16qs)__B); + return (__m128i) ((__v16qi)__A == (__v16qi)__B); } extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d1c448a..ec2872b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2019-09-09 Jakub Jelinek + PR target/87853 + * gcc.target/i386/pr87853.c: New test. + PR target/91704 * gcc.target/i386/pr91704.c: New test. diff --git a/gcc/testsuite/gcc.target/i386/pr87853.c b/gcc/testsuite/gcc.target/i386/pr87853.c new file mode 100644 index 0000000..9a28887 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr87853.c @@ -0,0 +1,20 @@ +/* PR target/87853 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -funsigned-char -msse2 -mno-sse3 -masm=att" } */ +/* { dg-final { scan-assembler-times "\tpcmpgtb\t%xmm" 2 } } */ +/* { dg-final { scan-assembler-not "\tpsubusb\t" } } */ +/* { dg-final { scan-assembler-not "\tpcmpeqb\t" } } */ + +#include + +__m128i +foo (__m128i x, __m128i y) +{ + return _mm_cmpgt_epi8 (x, y); +} + +__m128i +bar (__m128i x, __m128i y) +{ + return _mm_cmplt_epi8 (x, y); +} -- cgit v1.1 From f48ef52e40171a47221401a0f7b4e8648b6c541f Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Mon, 9 Sep 2019 13:47:54 +0200 Subject: Update comment of removed options. 2019-09-09 Martin Liska * config/i386/i386.opt: Update comment of removed options that are preserved only for backward compatibility. 2019-09-09 Martin Liska * c.opt: Update comment of removed options that are preserved only for backward compatibility. From-SVN: r275517 --- gcc/ChangeLog | 6 ++++++ gcc/c-family/ChangeLog | 6 ++++++ gcc/c-family/c.opt | 46 +++++++++++++++++++++++----------------------- gcc/config/i386/i386.opt | 4 ++-- 4 files changed, 37 insertions(+), 25 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6c749d2..6c567aa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-09-09 Martin Liska + + * config/i386/i386.opt: Update comment of removed + options that are preserved only for backward + compatibility. + 2019-09-09 Jakub Jelinek PR target/87853 diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 6e20cb4..7e838fb2 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2019-09-09 Martin Liska + + * c.opt: Update comment of removed + options that are preserved only for backward + compatibility. + 2019-09-06 Martin Liska PR c++/91125 diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index ec54666..c580447 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -429,7 +429,7 @@ Warn about subscripts whose type is \"char\". Wchkp C ObjC C++ ObjC++ Warning Deprecated -Deprecated in GCC 9. This switch has no effect. +Removed in GCC 9. This switch has no effect. Wclobbered C ObjC C++ ObjC++ Var(warn_clobbered) Warning EnabledBy(Wextra) @@ -1338,90 +1338,90 @@ and character literals. fcheck-pointer-bounds C ObjC C++ ObjC++ LTO Deprecated -Deprecated in GCC 9. This switch has no effect. +Removed in GCC 9. This switch has no effect. fchkp-check-incomplete-type C ObjC C++ ObjC++ LTO Deprecated -Deprecated in GCC 9. This switch has no effect. +Removed in GCC 9. This switch has no effect. fchkp-zero-input-bounds-for-main C ObjC C++ ObjC++ LTO Deprecated -Deprecated in GCC 9. This switch has no effect. +Removed in GCC 9. This switch has no effect. fchkp-first-field-has-own-bounds C ObjC C++ ObjC++ LTO Deprecated RejectNegative -Deprecated in GCC 9. This switch has no effect. +Removed in GCC 9. This switch has no effect. fchkp-narrow-bounds C ObjC C++ ObjC++ LTO Deprecated -Deprecated in GCC 9. This switch has no effect. +Removed in GCC 9. This switch has no effect. fchkp-narrow-to-innermost-array C ObjC C++ ObjC++ LTO Deprecated RejectNegative -Deprecated in GCC 9. This switch has no effect. +Removed in GCC 9. This switch has no effect. fchkp-flexible-struct-trailing-arrays C ObjC C++ ObjC++ LTO Deprecated -Deprecated in GCC 9. This switch has no effect. +Removed in GCC 9. This switch has no effect. fchkp-optimize C ObjC C++ ObjC++ LTO Deprecated fchkp-use-fast-string-functions C ObjC C++ ObjC++ LTO Deprecated -Deprecated in GCC 9. This switch has no effect. +Removed in GCC 9. This switch has no effect. fchkp-use-nochk-string-functions C ObjC C++ ObjC++ LTO Deprecated -Deprecated in GCC 9. This switch has no effect. +Removed in GCC 9. This switch has no effect. fchkp-use-static-bounds C ObjC C++ ObjC++ LTO Deprecated -Deprecated in GCC 9. This switch has no effect. +Removed in GCC 9. This switch has no effect. fchkp-use-static-const-bounds C ObjC C++ ObjC++ LTO Deprecated -Deprecated in GCC 9. This switch has no effect. +Removed in GCC 9. This switch has no effect. fchkp-treat-zero-dynamic-size-as-infinite C ObjC C++ ObjC++ LTO Deprecated -Deprecated in GCC 9. This switch has no effect. +Removed in GCC 9. This switch has no effect. fchkp-check-read C ObjC C++ ObjC++ LTO Deprecated -Deprecated in GCC 9. This switch has no effect. +Removed in GCC 9. This switch has no effect. fchkp-check-write C ObjC C++ ObjC++ LTO Deprecated -Deprecated in GCC 9. This switch has no effect. +Removed in GCC 9. This switch has no effect. fchkp-store-bounds C ObjC C++ ObjC++ LTO Deprecated -Deprecated in GCC 9. This switch has no effect. +Removed in GCC 9. This switch has no effect. fchkp-instrument-calls C ObjC C++ ObjC++ LTO Deprecated -Deprecated in GCC 9. This switch has no effect. +Removed in GCC 9. This switch has no effect. fchkp-instrument-marked-only C ObjC C++ ObjC++ LTO Deprecated -Deprecated in GCC 9. This switch has no effect. +Removed in GCC 9. This switch has no effect. fchkp-use-wrappers C ObjC C++ ObjC++ LTO Deprecated -Deprecated in GCC 9. This switch has no effect. +Removed in GCC 9. This switch has no effect. static-libmpx Driver Deprecated -Deprecated in GCC 9. This switch has no effect. +Removed in GCC 9. This switch has no effect. static-libmpxwrappers Driver Deprecated -Deprecated in GCC 9. This switch has no effect. +Removed in GCC 9. This switch has no effect. fcilkplus C ObjC C++ ObjC++ LTO Undocumented Ignore -Deprecated in GCC 8. This switch has no effect. +Removed in GCC 8. This switch has no effect. fconcepts C++ ObjC++ Var(flag_concepts) @@ -1764,7 +1764,7 @@ Used in Fix-and-Continue mode to indicate that object files may be swapped in at frepo C++ ObjC++ Deprecated -Deprecated in GCC 10. This switch has no effect. +Removed in GCC 10. This switch has no effect. frtti C++ ObjC++ Optimization Var(flag_rtti) Init(1) diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index 599e799..5d47212 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -968,7 +968,7 @@ Support RTM built-in functions and code generation. mmpx Target Deprecated -Deprecated in GCC 9. This switch has no effect. +Removed in GCC 9. This switch has no effect. mmwaitx Target Report Mask(ISA_MWAITX) Var(ix86_isa_flags2) Save @@ -1113,4 +1113,4 @@ AVX512BF16 built-in functions and code generation. menqcmd Target Report Mask(ISA_ENQCMD) Var(ix86_isa_flags2) Save -Support ENQCMD built-in functions and code generation. \ No newline at end of file +Support ENQCMD built-in functions and code generation. -- cgit v1.1 From a6edd18cb32993213508aaa4879af7485c1bbaac Mon Sep 17 00:00:00 2001 From: Barnaby Wilks Date: Mon, 9 Sep 2019 12:05:36 +0000 Subject: match.pd: Add flag_unsafe_math_optimizations check before deciding on the widest type in... 2019-09-09 Barnaby Wilks * match.pd: Add flag_unsafe_math_optimizations check before deciding on the widest type in a binary math operation. * gcc.dg/fold-binary-math-casts.c: New test. From-SVN: r275518 --- gcc/ChangeLog | 5 +++ gcc/match.pd | 12 +++++- gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gcc.dg/fold-binary-math-casts.c | 58 +++++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/fold-binary-math-casts.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6c567aa..b58b92a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-09-09 Barnaby Wilks + + * match.pd: Add flag_unsafe_math_optimizations check + before deciding on the widest type in a binary math operation. + 2019-09-09 Martin Liska * config/i386/i386.opt: Update comment of removed diff --git a/gcc/match.pd b/gcc/match.pd index 1d13543..5b2d95d 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -5040,10 +5040,18 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && newtype == type && types_match (newtype, type)) (op (convert:newtype @1) (convert:newtype @2)) - (with { if (TYPE_PRECISION (ty1) > TYPE_PRECISION (newtype)) + (with + { + if (!flag_unsafe_math_optimizations) + { + if (TYPE_PRECISION (ty1) > TYPE_PRECISION (newtype)) newtype = ty1; + if (TYPE_PRECISION (ty2) > TYPE_PRECISION (newtype)) - newtype = ty2; } + newtype = ty2; + } + } + /* Sometimes this transformation is safe (cannot change results through affecting double rounding cases) and sometimes it is not. If NEWTYPE is diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ec2872b..6129f91 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-09-09 Barnaby Wilks + + * gcc.dg/fold-binary-math-casts.c: New test. + 2019-09-09 Jakub Jelinek PR target/87853 diff --git a/gcc/testsuite/gcc.dg/fold-binary-math-casts.c b/gcc/testsuite/gcc.dg/fold-binary-math-casts.c new file mode 100644 index 0000000..53c247f --- /dev/null +++ b/gcc/testsuite/gcc.dg/fold-binary-math-casts.c @@ -0,0 +1,58 @@ +/* { dg-do compile } */ +/* { dg-options "-Ofast -fdump-tree-optimized" } */ + +#include + +float +f (float x, float y) +{ + double z = 1.0 / x; + return z * y; +} + +float +g (float x, float y) +{ + double a = 1.0 / x; + double b = 1.0 / y; + long double k = x*x*x*x*x*x; + + return a + b - k; +} + +float +h (float x) +{ + double a = x * 2.0; + double b = a / 3.5f; + return a + b; +} + +float +i (float y, float z) +{ + return pow (y, 2.0) / (double) (y + z); +} + +float +j (float x, float y) +{ + double t = 4.0 * x; + double z = t + y; + return z; +} + +float +k (float a) +{ + return 1.0 / sqrtf (a); +} + +float +l (float a) +{ + return (double) a * (a / 2.0); +} + +/* { dg-final { scan-tree-dump-not "\\(double\\)" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "\\(float\\)" "optimized" } } */ -- cgit v1.1 From f78f73cbd284abe4f1718fd7803f5f98800de225 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Mon, 9 Sep 2019 16:52:12 +0000 Subject: Remove bt-load.c bt-load.c has AFAIK been dead code since the removal of the SH5 port in 2016. I have a patch series that would need to update the liveness tracking in a nontrivial way, so it seemed better to remove the pass rather than install an untested and probably bogus change. 2019-09-09 Richard Sandiford gcc/ * Makefile.in (OBJS): Remove bt-load.o. * doc/invoke.texi (fbranch-target-load-optimize): Delete. (fbranch-target-load-optimize2, fbtr-bb-exclusive): Likewise. * common.opt (fbranch-target-load-optimize): Mark as Ignore and document that the option no longer does anything. (fbranch-target-load-optimize2, fbtr-bb-exclusive): Likewise. * target.def (branch_target_register_class): Delete. (branch_target_register_callee_saved): Likewise. * doc/tm.texi.in (TARGET_BRANCH_TARGET_REGISTER_CLASS): Likewise. (TARGET_BRANCH_TARGET_REGISTER_CALLEE_SAVED): Likewise. * doc/tm.texi: Regenerate. * tree-pass.h (make_pass_branch_target_load_optimize1): Delete. (make_pass_branch_target_load_optimize2): Likewise. * passes.def (pass_branch_target_load_optimize1): Likewise. (pass_branch_target_load_optimize2): Likewise. * targhooks.h (default_branch_target_register_class): Likewise. * targhooks.c (default_branch_target_register_class): Likewise. * opt-suggestions.c (test_completion_valid_options): Remove -fbtr-bb-exclusive from the list of test options. * bt-load.c: Remove. From-SVN: r275521 --- gcc/ChangeLog | 23 + gcc/Makefile.in | 1 - gcc/bt-load.c | 1577 ------------------------------------------------- gcc/common.opt | 12 +- gcc/doc/invoke.texi | 21 +- gcc/doc/tm.texi | 22 - gcc/doc/tm.texi.in | 4 - gcc/opt-suggestions.c | 1 - gcc/passes.def | 2 - gcc/target.def | 32 - gcc/targhooks.c | 6 - gcc/targhooks.h | 1 - gcc/tree-pass.h | 4 - 13 files changed, 30 insertions(+), 1676 deletions(-) delete mode 100644 gcc/bt-load.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b58b92a..f640d89 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,26 @@ +2019-09-09 Richard Sandiford + + * Makefile.in (OBJS): Remove bt-load.o. + * doc/invoke.texi (fbranch-target-load-optimize): Delete. + (fbranch-target-load-optimize2, fbtr-bb-exclusive): Likewise. + * common.opt (fbranch-target-load-optimize): Mark as Ignore and + document that the option no longer does anything. + (fbranch-target-load-optimize2, fbtr-bb-exclusive): Likewise. + * target.def (branch_target_register_class): Delete. + (branch_target_register_callee_saved): Likewise. + * doc/tm.texi.in (TARGET_BRANCH_TARGET_REGISTER_CLASS): Likewise. + (TARGET_BRANCH_TARGET_REGISTER_CALLEE_SAVED): Likewise. + * doc/tm.texi: Regenerate. + * tree-pass.h (make_pass_branch_target_load_optimize1): Delete. + (make_pass_branch_target_load_optimize2): Likewise. + * passes.def (pass_branch_target_load_optimize1): Likewise. + (pass_branch_target_load_optimize2): Likewise. + * targhooks.h (default_branch_target_register_class): Likewise. + * targhooks.c (default_branch_target_register_class): Likewise. + * opt-suggestions.c (test_completion_valid_options): Remove + -fbtr-bb-exclusive from the list of test options. + * bt-load.c: Remove. + 2019-09-09 Barnaby Wilks * match.pd: Add flag_unsafe_math_optimizations check diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 99d88a4..0fe02fb 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1241,7 +1241,6 @@ OBJS = \ auto-profile.o \ bb-reorder.o \ bitmap.o \ - bt-load.o \ builtins.o \ caller-save.o \ calls.o \ diff --git a/gcc/bt-load.c b/gcc/bt-load.c deleted file mode 100644 index f68879ca..0000000 --- a/gcc/bt-load.c +++ /dev/null @@ -1,1577 +0,0 @@ -/* Perform branch target register load optimizations. - Copyright (C) 2001-2019 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "backend.h" -#include "target.h" -#include "rtl.h" -#include "tree.h" -#include "df.h" -#include "insn-config.h" -#include "regs.h" -#include "memmodel.h" -#include "emit-rtl.h" -#include "recog.h" -#include "diagnostic-core.h" -#include "expr.h" -#include "insn-attr.h" -#include "tree-pass.h" -#include "cfgrtl.h" -#include "cfganal.h" -#include "cfgcleanup.h" -#include "cfgloop.h" -#include "rtl-iter.h" -#include "fibonacci_heap.h" - -struct btr_def; - -/* Target register optimizations - these are performed after reload. */ - -struct btr_def_group -{ - btr_def_group *next; - rtx src; - btr_def *members; -}; - -struct btr_user -{ - btr_user *next; - basic_block bb; - int luid; - rtx_insn *insn; - /* If INSN has a single use of a single branch register, then - USE points to it within INSN. If there is more than - one branch register use, or the use is in some way ambiguous, - then USE is NULL. */ - rtx use; - int n_reaching_defs; - int first_reaching_def; - char other_use_this_block; -}; - -/* btr_def structs appear on three lists: - 1. A list of all btr_def structures (head is - ALL_BTR_DEFS, linked by the NEXT field). - 2. A list of branch reg definitions per basic block (head is - BB_BTR_DEFS[i], linked by the NEXT_THIS_BB field). - 3. A list of all branch reg definitions belonging to the same - group (head is in a BTR_DEF_GROUP struct, linked by - NEXT_THIS_GROUP field). */ - -struct btr_def -{ - btr_def *next_this_bb; - btr_def *next_this_group; - basic_block bb; - int luid; - rtx_insn *insn; - int btr; - int cost; - /* For a branch register setting insn that has a constant - source (i.e. a label), group links together all the - insns with the same source. For other branch register - setting insns, group is NULL. */ - btr_def_group *group; - btr_user *uses; - /* If this def has a reaching use which is not a simple use - in a branch instruction, then has_ambiguous_use will be true, - and we will not attempt to migrate this definition. */ - char has_ambiguous_use; - /* live_range is an approximation to the true live range for this - def/use web, because it records the set of blocks that contain - the live range. There could be other live ranges for the same - branch register in that set of blocks, either in the block - containing the def (before the def), or in a block containing - a use (after the use). If there are such other live ranges, then - other_btr_uses_before_def or other_btr_uses_after_use must be set true - as appropriate. */ - char other_btr_uses_before_def; - char other_btr_uses_after_use; - /* We set own_end when we have moved a definition into a dominator. - Thus, when a later combination removes this definition again, we know - to clear out trs_live_at_end again. */ - char own_end; - bitmap live_range; -}; - -typedef fibonacci_heap btr_heap_t; -typedef fibonacci_node btr_heap_node_t; - -static int issue_rate; - -static int basic_block_freq (const_basic_block); -static int insn_sets_btr_p (const rtx_insn *, int, int *); -static void find_btr_def_group (btr_def_group **, btr_def *); -static btr_def *add_btr_def (btr_heap_t *, basic_block, int, rtx_insn *, - unsigned int, int, btr_def_group **); -static btr_user *new_btr_user (basic_block, int, rtx_insn *); -static void dump_hard_reg_set (HARD_REG_SET); -static void dump_btrs_live (int); -static void note_other_use_this_block (unsigned int, btr_user *); -static void compute_defs_uses_and_gen (btr_heap_t *, btr_def **, btr_user **, - sbitmap *, sbitmap *, HARD_REG_SET *); -static void compute_kill (sbitmap *, sbitmap *, HARD_REG_SET *); -static void compute_out (sbitmap *bb_out, sbitmap *, sbitmap *, int); -static void link_btr_uses (btr_def **, btr_user **, sbitmap *, sbitmap *, int); -static void build_btr_def_use_webs (btr_heap_t *); -static int block_at_edge_of_live_range_p (int, btr_def *); -static void clear_btr_from_live_range (btr_def *def); -static void add_btr_to_live_range (btr_def *, int); -static void augment_live_range (bitmap, HARD_REG_SET *, basic_block, - basic_block, int); -static int choose_btr (HARD_REG_SET); -static void combine_btr_defs (btr_def *, HARD_REG_SET *); -static void btr_def_live_range (btr_def *, HARD_REG_SET *); -static void move_btr_def (basic_block, int, btr_def *, bitmap, HARD_REG_SET *); -static int migrate_btr_def (btr_def *, int); -static void migrate_btr_defs (enum reg_class, int); -static int can_move_up (const_basic_block, const rtx_insn *, int); -static void note_btr_set (rtx, const_rtx, void *); - -/* The following code performs code motion of target load instructions - (instructions that set branch target registers), to move them - forward away from the branch instructions and out of loops (or, - more generally, from a more frequently executed place to a less - frequently executed place). - Moving target load instructions further in front of the branch - instruction that uses the target register value means that the hardware - has a better chance of preloading the instructions at the branch - target by the time the branch is reached. This avoids bubbles - when a taken branch needs to flush out the pipeline. - Moving target load instructions out of loops means they are executed - less frequently. */ - -/* An obstack to hold the def-use web data structures built up for - migrating branch target load instructions. */ -static struct obstack migrate_btrl_obstack; - -/* Array indexed by basic block number, giving the set of registers - live in that block. */ -static HARD_REG_SET *btrs_live; - -/* Array indexed by basic block number, giving the set of registers live at - the end of that block, including any uses by a final jump insn, if any. */ -static HARD_REG_SET *btrs_live_at_end; - -/* Set of all target registers that we are willing to allocate. */ -static HARD_REG_SET all_btrs; - -/* Provide lower and upper bounds for target register numbers, so that - we don't need to search through all the hard registers all the time. */ -static int first_btr, last_btr; - - - -/* Return an estimate of the frequency of execution of block bb. */ -static int -basic_block_freq (const_basic_block bb) -{ - return bb->count.to_frequency (cfun); -} - -/* If the rtx at *XP references (sets or reads) any branch target - register, return one such register. If EXCLUDEP is set, disregard - any references within that location. */ -static rtx * -find_btr_use (rtx *xp, rtx *excludep = 0) -{ - subrtx_ptr_iterator::array_type array; - FOR_EACH_SUBRTX_PTR (iter, array, xp, NONCONST) - { - rtx *loc = *iter; - if (loc == excludep) - iter.skip_subrtxes (); - else - { - const_rtx x = *loc; - if (REG_P (x) - && overlaps_hard_reg_set_p (all_btrs, GET_MODE (x), REGNO (x))) - return loc; - } - } - return 0; -} - -/* Return true if insn is an instruction that sets a target register. - if CHECK_CONST is true, only return true if the source is constant. - If such a set is found and REGNO is nonzero, assign the register number - of the destination register to *REGNO. */ -static int -insn_sets_btr_p (const rtx_insn *insn, int check_const, int *regno) -{ - rtx set; - - if (NONJUMP_INSN_P (insn) - && (set = single_set (insn))) - { - rtx dest = SET_DEST (set); - rtx src = SET_SRC (set); - - if (GET_CODE (dest) == SUBREG) - dest = XEXP (dest, 0); - - if (REG_P (dest) - && TEST_HARD_REG_BIT (all_btrs, REGNO (dest))) - { - gcc_assert (!find_btr_use (&src)); - - if (!check_const || CONSTANT_P (src)) - { - if (regno) - *regno = REGNO (dest); - return 1; - } - } - } - return 0; -} - -/* Find the group that the target register definition DEF belongs - to in the list starting with *ALL_BTR_DEF_GROUPS. If no such - group exists, create one. Add def to the group. */ -static void -find_btr_def_group (btr_def_group **all_btr_def_groups, btr_def *def) -{ - if (insn_sets_btr_p (def->insn, 1, NULL)) - { - btr_def_group *this_group; - rtx def_src = SET_SRC (single_set (def->insn)); - - /* ?? This linear search is an efficiency concern, particularly - as the search will almost always fail to find a match. */ - for (this_group = *all_btr_def_groups; - this_group != NULL; - this_group = this_group->next) - if (rtx_equal_p (def_src, this_group->src)) - break; - - if (!this_group) - { - this_group = XOBNEW (&migrate_btrl_obstack, btr_def_group); - this_group->src = def_src; - this_group->members = NULL; - this_group->next = *all_btr_def_groups; - *all_btr_def_groups = this_group; - } - def->group = this_group; - def->next_this_group = this_group->members; - this_group->members = def; - } - else - def->group = NULL; -} - -/* Create a new target register definition structure, for a definition in - block BB, instruction INSN, and insert it into ALL_BTR_DEFS. Return - the new definition. */ -static btr_def * -add_btr_def (btr_heap_t *all_btr_defs, basic_block bb, int insn_luid, - rtx_insn *insn, - unsigned int dest_reg, int other_btr_uses_before_def, - btr_def_group **all_btr_def_groups) -{ - btr_def *this_def = XOBNEW (&migrate_btrl_obstack, btr_def); - this_def->bb = bb; - this_def->luid = insn_luid; - this_def->insn = insn; - this_def->btr = dest_reg; - this_def->cost = basic_block_freq (bb); - this_def->has_ambiguous_use = 0; - this_def->other_btr_uses_before_def = other_btr_uses_before_def; - this_def->other_btr_uses_after_use = 0; - this_def->next_this_bb = NULL; - this_def->next_this_group = NULL; - this_def->uses = NULL; - this_def->live_range = NULL; - find_btr_def_group (all_btr_def_groups, this_def); - - all_btr_defs->insert (-this_def->cost, this_def); - - if (dump_file) - fprintf (dump_file, - "Found target reg definition: sets %u { bb %d, insn %d }%s priority %d\n", - dest_reg, bb->index, INSN_UID (insn), - (this_def->group ? "" : ":not const"), this_def->cost); - - return this_def; -} - -/* Create a new target register user structure, for a use in block BB, - instruction INSN. Return the new user. */ -static btr_user * -new_btr_user (basic_block bb, int insn_luid, rtx_insn *insn) -{ - /* This instruction reads target registers. We need - to decide whether we can replace all target register - uses easily. - */ - rtx *usep = find_btr_use (&PATTERN (insn)); - rtx use; - btr_user *user = NULL; - - if (usep) - { - int unambiguous_single_use; - - /* We want to ensure that USE is the only use of a target - register in INSN, so that we know that to rewrite INSN to use - a different target register, all we have to do is replace USE. */ - unambiguous_single_use = !find_btr_use (&PATTERN (insn), usep); - if (!unambiguous_single_use) - usep = NULL; - } - use = usep ? *usep : NULL_RTX; - user = XOBNEW (&migrate_btrl_obstack, btr_user); - user->bb = bb; - user->luid = insn_luid; - user->insn = insn; - user->use = use; - user->other_use_this_block = 0; - user->next = NULL; - user->n_reaching_defs = 0; - user->first_reaching_def = -1; - - if (dump_file) - { - fprintf (dump_file, "Uses target reg: { bb %d, insn %d }", - bb->index, INSN_UID (insn)); - - if (user->use) - fprintf (dump_file, ": unambiguous use of reg %d\n", - REGNO (user->use)); - } - - return user; -} - -/* Write the contents of S to the dump file. */ -static void -dump_hard_reg_set (HARD_REG_SET s) -{ - int reg; - for (reg = 0; reg < FIRST_PSEUDO_REGISTER; reg++) - if (TEST_HARD_REG_BIT (s, reg)) - fprintf (dump_file, " %d", reg); -} - -/* Write the set of target regs live in block BB to the dump file. */ -static void -dump_btrs_live (int bb) -{ - fprintf (dump_file, "BB%d live:", bb); - dump_hard_reg_set (btrs_live[bb]); - fprintf (dump_file, "\n"); -} - -/* REGNO is the number of a branch target register that is being used or - set. USERS_THIS_BB is a list of preceding branch target register users; - If any of them use the same register, set their other_use_this_block - flag. */ -static void -note_other_use_this_block (unsigned int regno, btr_user *users_this_bb) -{ - btr_user *user; - - for (user = users_this_bb; user != NULL; user = user->next) - if (user->use && REGNO (user->use) == regno) - user->other_use_this_block = 1; -} - -struct defs_uses_info { - btr_user *users_this_bb; - HARD_REG_SET btrs_written_in_block; - HARD_REG_SET btrs_live_in_block; - sbitmap bb_gen; - sbitmap *btr_defset; -}; - -/* Called via note_stores or directly to register stores into / - clobbers of a branch target register DEST that are not recognized as - straightforward definitions. DATA points to information about the - current basic block that needs updating. */ -static void -note_btr_set (rtx dest, const_rtx set ATTRIBUTE_UNUSED, void *data) -{ - defs_uses_info *info = (defs_uses_info *) data; - int regno, end_regno; - - if (!REG_P (dest)) - return; - regno = REGNO (dest); - end_regno = END_REGNO (dest); - for (; regno < end_regno; regno++) - if (TEST_HARD_REG_BIT (all_btrs, regno)) - { - note_other_use_this_block (regno, info->users_this_bb); - SET_HARD_REG_BIT (info->btrs_written_in_block, regno); - SET_HARD_REG_BIT (info->btrs_live_in_block, regno); - bitmap_and_compl (info->bb_gen, info->bb_gen, - info->btr_defset[regno - first_btr]); - } -} - -static void -compute_defs_uses_and_gen (btr_heap_t *all_btr_defs, btr_def **def_array, - btr_user **use_array, sbitmap *btr_defset, - sbitmap *bb_gen, HARD_REG_SET *btrs_written) -{ - /* Scan the code building up the set of all defs and all uses. - For each target register, build the set of defs of that register. - For each block, calculate the set of target registers - written in that block. - Also calculate the set of btrs ever live in that block. - */ - int i; - int insn_luid = 0; - btr_def_group *all_btr_def_groups = NULL; - defs_uses_info info; - - bitmap_vector_clear (bb_gen, last_basic_block_for_fn (cfun)); - for (i = NUM_FIXED_BLOCKS; i < last_basic_block_for_fn (cfun); i++) - { - basic_block bb = BASIC_BLOCK_FOR_FN (cfun, i); - int reg; - btr_def *defs_this_bb = NULL; - rtx_insn *insn; - rtx_insn *last; - int can_throw = 0; - - info.users_this_bb = NULL; - info.bb_gen = bb_gen[i]; - info.btr_defset = btr_defset; - - CLEAR_HARD_REG_SET (info.btrs_live_in_block); - CLEAR_HARD_REG_SET (info.btrs_written_in_block); - for (reg = first_btr; reg <= last_btr; reg++) - if (TEST_HARD_REG_BIT (all_btrs, reg) - && REGNO_REG_SET_P (df_get_live_in (bb), reg)) - SET_HARD_REG_BIT (info.btrs_live_in_block, reg); - - for (insn = BB_HEAD (bb), last = NEXT_INSN (BB_END (bb)); - insn != last; - insn = NEXT_INSN (insn), insn_luid++) - { - if (INSN_P (insn)) - { - int regno; - int insn_uid = INSN_UID (insn); - - if (insn_sets_btr_p (insn, 0, ®no)) - { - btr_def *def = add_btr_def ( - all_btr_defs, bb, insn_luid, insn, regno, - TEST_HARD_REG_BIT (info.btrs_live_in_block, regno), - &all_btr_def_groups); - - def_array[insn_uid] = def; - SET_HARD_REG_BIT (info.btrs_written_in_block, regno); - SET_HARD_REG_BIT (info.btrs_live_in_block, regno); - bitmap_and_compl (bb_gen[i], bb_gen[i], - btr_defset[regno - first_btr]); - bitmap_set_bit (bb_gen[i], insn_uid); - def->next_this_bb = defs_this_bb; - defs_this_bb = def; - bitmap_set_bit (btr_defset[regno - first_btr], insn_uid); - note_other_use_this_block (regno, info.users_this_bb); - } - /* Check for the blockage emitted by expand_nl_goto_receiver. */ - else if (cfun->has_nonlocal_label - && GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE) - { - btr_user *user; - - /* Do the equivalent of calling note_other_use_this_block - for every target register. */ - for (user = info.users_this_bb; user != NULL; - user = user->next) - if (user->use) - user->other_use_this_block = 1; - IOR_HARD_REG_SET (info.btrs_written_in_block, all_btrs); - IOR_HARD_REG_SET (info.btrs_live_in_block, all_btrs); - bitmap_clear (info.bb_gen); - } - else - { - if (find_btr_use (&PATTERN (insn))) - { - btr_user *user = new_btr_user (bb, insn_luid, insn); - - use_array[insn_uid] = user; - if (user->use) - SET_HARD_REG_BIT (info.btrs_live_in_block, - REGNO (user->use)); - else - { - int reg; - for (reg = first_btr; reg <= last_btr; reg++) - if (TEST_HARD_REG_BIT (all_btrs, reg) - && refers_to_regno_p (reg, user->insn)) - { - note_other_use_this_block (reg, - info.users_this_bb); - SET_HARD_REG_BIT (info.btrs_live_in_block, reg); - } - note_stores (PATTERN (insn), note_btr_set, &info); - } - user->next = info.users_this_bb; - info.users_this_bb = user; - } - if (CALL_P (insn)) - { - HARD_REG_SET *clobbered = &call_used_reg_set; - HARD_REG_SET call_saved; - rtx pat = PATTERN (insn); - int i; - - /* Check for sibcall. */ - if (GET_CODE (pat) == PARALLEL) - for (i = XVECLEN (pat, 0) - 1; i >= 0; i--) - if (ANY_RETURN_P (XVECEXP (pat, 0, i))) - { - COMPL_HARD_REG_SET (call_saved, - call_used_reg_set); - clobbered = &call_saved; - } - - for (regno = first_btr; regno <= last_btr; regno++) - if (TEST_HARD_REG_BIT (*clobbered, regno)) - note_btr_set (regno_reg_rtx[regno], NULL_RTX, &info); - } - } - } - } - - COPY_HARD_REG_SET (btrs_live[i], info.btrs_live_in_block); - COPY_HARD_REG_SET (btrs_written[i], info.btrs_written_in_block); - - REG_SET_TO_HARD_REG_SET (btrs_live_at_end[i], df_get_live_out (bb)); - /* If this block ends in a jump insn, add any uses or even clobbers - of branch target registers that it might have. */ - for (insn = BB_END (bb); insn != BB_HEAD (bb) && ! INSN_P (insn); ) - insn = PREV_INSN (insn); - /* ??? for the fall-through edge, it would make sense to insert the - btr set on the edge, but that would require to split the block - early on so that we can distinguish between dominance from the fall - through edge - which can use the call-clobbered registers - from - dominance by the throw edge. */ - if (can_throw_internal (insn)) - { - HARD_REG_SET tmp; - - COPY_HARD_REG_SET (tmp, call_used_reg_set); - AND_HARD_REG_SET (tmp, all_btrs); - IOR_HARD_REG_SET (btrs_live_at_end[i], tmp); - can_throw = 1; - } - if (can_throw || JUMP_P (insn)) - { - int regno; - - for (regno = first_btr; regno <= last_btr; regno++) - if (refers_to_regno_p (regno, insn)) - SET_HARD_REG_BIT (btrs_live_at_end[i], regno); - } - - if (dump_file) - dump_btrs_live (i); - } -} - -static void -compute_kill (sbitmap *bb_kill, sbitmap *btr_defset, - HARD_REG_SET *btrs_written) -{ - int i; - int regno; - - /* For each basic block, form the set BB_KILL - the set - of definitions that the block kills. */ - bitmap_vector_clear (bb_kill, last_basic_block_for_fn (cfun)); - for (i = NUM_FIXED_BLOCKS; i < last_basic_block_for_fn (cfun); i++) - { - for (regno = first_btr; regno <= last_btr; regno++) - if (TEST_HARD_REG_BIT (all_btrs, regno) - && TEST_HARD_REG_BIT (btrs_written[i], regno)) - bitmap_ior (bb_kill[i], bb_kill[i], - btr_defset[regno - first_btr]); - } -} - -static void -compute_out (sbitmap *bb_out, sbitmap *bb_gen, sbitmap *bb_kill, int max_uid) -{ - /* Perform iterative dataflow: - Initially, for all blocks, BB_OUT = BB_GEN. - For each block, - BB_IN = union over predecessors of BB_OUT(pred) - BB_OUT = (BB_IN - BB_KILL) + BB_GEN - Iterate until the bb_out sets stop growing. */ - int i; - int changed; - auto_sbitmap bb_in (max_uid); - - for (i = NUM_FIXED_BLOCKS; i < last_basic_block_for_fn (cfun); i++) - bitmap_copy (bb_out[i], bb_gen[i]); - - changed = 1; - while (changed) - { - changed = 0; - for (i = NUM_FIXED_BLOCKS; i < last_basic_block_for_fn (cfun); i++) - { - bitmap_union_of_preds (bb_in, bb_out, BASIC_BLOCK_FOR_FN (cfun, i)); - changed |= bitmap_ior_and_compl (bb_out[i], bb_gen[i], - bb_in, bb_kill[i]); - } - } -} - -static void -link_btr_uses (btr_def **def_array, btr_user **use_array, sbitmap *bb_out, - sbitmap *btr_defset, int max_uid) -{ - int i; - auto_sbitmap reaching_defs (max_uid); - - /* Link uses to the uses lists of all of their reaching defs. - Count up the number of reaching defs of each use. */ - for (i = NUM_FIXED_BLOCKS; i < last_basic_block_for_fn (cfun); i++) - { - basic_block bb = BASIC_BLOCK_FOR_FN (cfun, i); - rtx_insn *insn; - rtx_insn *last; - - bitmap_union_of_preds (reaching_defs, bb_out, BASIC_BLOCK_FOR_FN (cfun, i)); - for (insn = BB_HEAD (bb), last = NEXT_INSN (BB_END (bb)); - insn != last; - insn = NEXT_INSN (insn)) - { - if (INSN_P (insn)) - { - int insn_uid = INSN_UID (insn); - - btr_def *def = def_array[insn_uid]; - btr_user *user = use_array[insn_uid]; - if (def != NULL) - { - /* Remove all reaching defs of regno except - for this one. */ - bitmap_and_compl (reaching_defs, reaching_defs, - btr_defset[def->btr - first_btr]); - bitmap_set_bit (reaching_defs, insn_uid); - } - - if (user != NULL) - { - /* Find all the reaching defs for this use. */ - auto_sbitmap reaching_defs_of_reg (max_uid); - unsigned int uid = 0; - sbitmap_iterator sbi; - - if (user->use) - bitmap_and ( - reaching_defs_of_reg, - reaching_defs, - btr_defset[REGNO (user->use) - first_btr]); - else - { - int reg; - - bitmap_clear (reaching_defs_of_reg); - for (reg = first_btr; reg <= last_btr; reg++) - if (TEST_HARD_REG_BIT (all_btrs, reg) - && refers_to_regno_p (reg, user->insn)) - bitmap_or_and (reaching_defs_of_reg, - reaching_defs_of_reg, - reaching_defs, - btr_defset[reg - first_btr]); - } - EXECUTE_IF_SET_IN_BITMAP (reaching_defs_of_reg, 0, uid, sbi) - { - btr_def *def = def_array[uid]; - - /* We now know that def reaches user. */ - - if (dump_file) - fprintf (dump_file, - "Def in insn %d reaches use in insn %d\n", - uid, insn_uid); - - user->n_reaching_defs++; - if (!user->use) - def->has_ambiguous_use = 1; - if (user->first_reaching_def != -1) - { /* There is more than one reaching def. This is - a rare case, so just give up on this def/use - web when it occurs. */ - def->has_ambiguous_use = 1; - def_array[user->first_reaching_def] - ->has_ambiguous_use = 1; - if (dump_file) - fprintf (dump_file, - "(use %d has multiple reaching defs)\n", - insn_uid); - } - else - user->first_reaching_def = uid; - if (user->other_use_this_block) - def->other_btr_uses_after_use = 1; - user->next = def->uses; - def->uses = user; - } - } - - if (CALL_P (insn)) - { - int regno; - - for (regno = first_btr; regno <= last_btr; regno++) - if (TEST_HARD_REG_BIT (all_btrs, regno) - && TEST_HARD_REG_BIT (call_used_reg_set, regno)) - bitmap_and_compl (reaching_defs, reaching_defs, - btr_defset[regno - first_btr]); - } - } - } - } -} - -static void -build_btr_def_use_webs (btr_heap_t *all_btr_defs) -{ - const int max_uid = get_max_uid (); - btr_def **def_array = XCNEWVEC (btr_def *, max_uid); - btr_user **use_array = XCNEWVEC (btr_user *, max_uid); - sbitmap *btr_defset = sbitmap_vector_alloc ( - (last_btr - first_btr) + 1, max_uid); - sbitmap *bb_gen = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), - max_uid); - HARD_REG_SET *btrs_written = XCNEWVEC (HARD_REG_SET, - last_basic_block_for_fn (cfun)); - sbitmap *bb_kill; - sbitmap *bb_out; - - bitmap_vector_clear (btr_defset, (last_btr - first_btr) + 1); - - compute_defs_uses_and_gen (all_btr_defs, def_array, use_array, btr_defset, - bb_gen, btrs_written); - - bb_kill = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), max_uid); - compute_kill (bb_kill, btr_defset, btrs_written); - free (btrs_written); - - bb_out = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), max_uid); - compute_out (bb_out, bb_gen, bb_kill, max_uid); - - sbitmap_vector_free (bb_gen); - sbitmap_vector_free (bb_kill); - - link_btr_uses (def_array, use_array, bb_out, btr_defset, max_uid); - - sbitmap_vector_free (bb_out); - sbitmap_vector_free (btr_defset); - free (use_array); - free (def_array); -} - -/* Return true if basic block BB contains the start or end of the - live range of the definition DEF, AND there are other live - ranges of the same target register that include BB. */ -static int -block_at_edge_of_live_range_p (int bb, btr_def *def) -{ - if (def->other_btr_uses_before_def - && BASIC_BLOCK_FOR_FN (cfun, bb) == def->bb) - return 1; - else if (def->other_btr_uses_after_use) - { - btr_user *user; - for (user = def->uses; user != NULL; user = user->next) - if (BASIC_BLOCK_FOR_FN (cfun, bb) == user->bb) - return 1; - } - return 0; -} - -/* We are removing the def/use web DEF. The target register - used in this web is therefore no longer live in the live range - of this web, so remove it from the live set of all basic blocks - in the live range of the web. - Blocks at the boundary of the live range may contain other live - ranges for the same target register, so we have to be careful - to remove the target register from the live set of these blocks - only if they do not contain other live ranges for the same register. */ -static void -clear_btr_from_live_range (btr_def *def) -{ - unsigned bb; - bitmap_iterator bi; - - EXECUTE_IF_SET_IN_BITMAP (def->live_range, 0, bb, bi) - { - if ((!def->other_btr_uses_before_def - && !def->other_btr_uses_after_use) - || !block_at_edge_of_live_range_p (bb, def)) - { - CLEAR_HARD_REG_BIT (btrs_live[bb], def->btr); - CLEAR_HARD_REG_BIT (btrs_live_at_end[bb], def->btr); - if (dump_file) - dump_btrs_live (bb); - } - } - if (def->own_end) - CLEAR_HARD_REG_BIT (btrs_live_at_end[def->bb->index], def->btr); -} - - -/* We are adding the def/use web DEF. Add the target register used - in this web to the live set of all of the basic blocks that contain - the live range of the web. - If OWN_END is set, also show that the register is live from our - definitions at the end of the basic block where it is defined. */ -static void -add_btr_to_live_range (btr_def *def, int own_end) -{ - unsigned bb; - bitmap_iterator bi; - - EXECUTE_IF_SET_IN_BITMAP (def->live_range, 0, bb, bi) - { - SET_HARD_REG_BIT (btrs_live[bb], def->btr); - SET_HARD_REG_BIT (btrs_live_at_end[bb], def->btr); - if (dump_file) - dump_btrs_live (bb); - } - if (own_end) - { - SET_HARD_REG_BIT (btrs_live_at_end[def->bb->index], def->btr); - def->own_end = 1; - } -} - -/* Update a live range to contain the basic block NEW_BLOCK, and all - blocks on paths between the existing live range and NEW_BLOCK. - HEAD is a block contained in the existing live range that dominates - all other blocks in the existing live range. - Also add to the set BTRS_LIVE_IN_RANGE all target registers that - are live in the blocks that we add to the live range. - If FULL_RANGE is set, include the full live range of NEW_BB; - otherwise, if NEW_BB dominates HEAD_BB, only add registers that - are life at the end of NEW_BB for NEW_BB itself. - It is a precondition that either NEW_BLOCK dominates HEAD,or - HEAD dom NEW_BLOCK. This is used to speed up the - implementation of this function. */ -static void -augment_live_range (bitmap live_range, HARD_REG_SET *btrs_live_in_range, - basic_block head_bb, basic_block new_bb, int full_range) -{ - basic_block *worklist, *tos; - - tos = worklist = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun) + 1); - - if (dominated_by_p (CDI_DOMINATORS, new_bb, head_bb)) - { - if (new_bb == head_bb) - { - if (full_range) - IOR_HARD_REG_SET (*btrs_live_in_range, btrs_live[new_bb->index]); - free (tos); - return; - } - *tos++ = new_bb; - } - else - { - edge e; - edge_iterator ei; - int new_block = new_bb->index; - - gcc_assert (dominated_by_p (CDI_DOMINATORS, head_bb, new_bb)); - - IOR_HARD_REG_SET (*btrs_live_in_range, btrs_live[head_bb->index]); - bitmap_set_bit (live_range, new_block); - /* A previous btr migration could have caused a register to be - live just at the end of new_block which we need in full, so - use trs_live_at_end even if full_range is set. */ - IOR_HARD_REG_SET (*btrs_live_in_range, btrs_live_at_end[new_block]); - if (full_range) - IOR_HARD_REG_SET (*btrs_live_in_range, btrs_live[new_block]); - if (dump_file) - { - fprintf (dump_file, - "Adding end of block %d and rest of %d to live range\n", - new_block, head_bb->index); - fprintf (dump_file,"Now live btrs are "); - dump_hard_reg_set (*btrs_live_in_range); - fprintf (dump_file, "\n"); - } - FOR_EACH_EDGE (e, ei, head_bb->preds) - *tos++ = e->src; - } - - while (tos != worklist) - { - basic_block bb = *--tos; - if (!bitmap_bit_p (live_range, bb->index)) - { - edge e; - edge_iterator ei; - - bitmap_set_bit (live_range, bb->index); - IOR_HARD_REG_SET (*btrs_live_in_range, - btrs_live[bb->index]); - /* A previous btr migration could have caused a register to be - live just at the end of a block which we need in full. */ - IOR_HARD_REG_SET (*btrs_live_in_range, - btrs_live_at_end[bb->index]); - if (dump_file) - { - fprintf (dump_file, - "Adding block %d to live range\n", bb->index); - fprintf (dump_file,"Now live btrs are "); - dump_hard_reg_set (*btrs_live_in_range); - fprintf (dump_file, "\n"); - } - - FOR_EACH_EDGE (e, ei, bb->preds) - { - basic_block pred = e->src; - if (!bitmap_bit_p (live_range, pred->index)) - *tos++ = pred; - } - } - } - - free (worklist); -} - -/* Return the most desirable target register that is not in - the set USED_BTRS. */ -static int -choose_btr (HARD_REG_SET used_btrs) -{ - int i; - - if (!hard_reg_set_subset_p (all_btrs, used_btrs)) - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - { -#ifdef REG_ALLOC_ORDER - int regno = reg_alloc_order[i]; -#else - int regno = i; -#endif - if (TEST_HARD_REG_BIT (all_btrs, regno) - && !TEST_HARD_REG_BIT (used_btrs, regno)) - return regno; - } - return -1; -} - -/* Calculate the set of basic blocks that contain the live range of - the def/use web DEF. - Also calculate the set of target registers that are live at time - in this live range, but ignore the live range represented by DEF - when calculating this set. */ -static void -btr_def_live_range (btr_def *def, HARD_REG_SET *btrs_live_in_range) -{ - if (!def->live_range) - { - btr_user *user; - - def->live_range = BITMAP_ALLOC (NULL); - - bitmap_set_bit (def->live_range, def->bb->index); - COPY_HARD_REG_SET (*btrs_live_in_range, - (flag_btr_bb_exclusive - ? btrs_live : btrs_live_at_end)[def->bb->index]); - - for (user = def->uses; user != NULL; user = user->next) - augment_live_range (def->live_range, btrs_live_in_range, - def->bb, user->bb, - (flag_btr_bb_exclusive - || user->insn != BB_END (def->bb) - || !JUMP_P (user->insn))); - } - else - { - /* def->live_range is accurate, but we need to recompute - the set of target registers live over it, because migration - of other PT instructions may have affected it. - */ - unsigned bb; - unsigned def_bb = flag_btr_bb_exclusive ? -1 : def->bb->index; - bitmap_iterator bi; - - CLEAR_HARD_REG_SET (*btrs_live_in_range); - EXECUTE_IF_SET_IN_BITMAP (def->live_range, 0, bb, bi) - { - IOR_HARD_REG_SET (*btrs_live_in_range, - (def_bb == bb - ? btrs_live_at_end : btrs_live) [bb]); - } - } - if (!def->other_btr_uses_before_def && - !def->other_btr_uses_after_use) - CLEAR_HARD_REG_BIT (*btrs_live_in_range, def->btr); -} - -/* Merge into the def/use web DEF any other def/use webs in the same - group that are dominated by DEF, provided that there is a target - register available to allocate to the merged web. */ -static void -combine_btr_defs (btr_def *def, HARD_REG_SET *btrs_live_in_range) -{ - btr_def *other_def; - - for (other_def = def->group->members; - other_def != NULL; - other_def = other_def->next_this_group) - { - if (other_def != def - && other_def->uses != NULL - && ! other_def->has_ambiguous_use - && dominated_by_p (CDI_DOMINATORS, other_def->bb, def->bb)) - { - /* def->bb dominates the other def, so def and other_def could - be combined. */ - /* Merge their live ranges, and get the set of - target registers live over the merged range. */ - int btr; - HARD_REG_SET combined_btrs_live; - auto_bitmap combined_live_range; - btr_user *user; - - if (other_def->live_range == NULL) - { - HARD_REG_SET dummy_btrs_live_in_range; - btr_def_live_range (other_def, &dummy_btrs_live_in_range); - } - COPY_HARD_REG_SET (combined_btrs_live, *btrs_live_in_range); - bitmap_copy (combined_live_range, def->live_range); - - for (user = other_def->uses; user != NULL; user = user->next) - augment_live_range (combined_live_range, &combined_btrs_live, - def->bb, user->bb, - (flag_btr_bb_exclusive - || user->insn != BB_END (def->bb) - || !JUMP_P (user->insn))); - - btr = choose_btr (combined_btrs_live); - if (btr != -1) - { - /* We can combine them. */ - if (dump_file) - fprintf (dump_file, - "Combining def in insn %d with def in insn %d\n", - INSN_UID (other_def->insn), INSN_UID (def->insn)); - - def->btr = btr; - user = other_def->uses; - while (user != NULL) - { - btr_user *next = user->next; - - user->next = def->uses; - def->uses = user; - user = next; - } - /* Combining def/use webs can make target registers live - after uses where they previously were not. This means - some REG_DEAD notes may no longer be correct. We could - be more precise about this if we looked at the combined - live range, but here I just delete any REG_DEAD notes - in case they are no longer correct. */ - for (user = def->uses; user != NULL; user = user->next) - remove_note (user->insn, - find_regno_note (user->insn, REG_DEAD, - REGNO (user->use))); - clear_btr_from_live_range (other_def); - other_def->uses = NULL; - bitmap_copy (def->live_range, combined_live_range); - if (other_def->btr == btr && other_def->other_btr_uses_after_use) - def->other_btr_uses_after_use = 1; - COPY_HARD_REG_SET (*btrs_live_in_range, combined_btrs_live); - - /* Delete the old target register initialization. */ - delete_insn (other_def->insn); - - } - } - } -} - -/* Move the definition DEF from its current position to basic - block NEW_DEF_BB, and modify it to use branch target register BTR. - Delete the old defining insn, and insert a new one in NEW_DEF_BB. - Update all reaching uses of DEF in the RTL to use BTR. - If this new position means that other defs in the - same group can be combined with DEF then combine them. */ -static void -move_btr_def (basic_block new_def_bb, int btr, btr_def *def, bitmap live_range, - HARD_REG_SET *btrs_live_in_range) -{ - /* We can move the instruction. - Set a target register in block NEW_DEF_BB to the value - needed for this target register definition. - Replace all uses of the old target register definition by - uses of the new definition. Delete the old definition. */ - basic_block b = new_def_bb; - rtx_insn *insp = BB_HEAD (b); - rtx_insn *old_insn = def->insn; - rtx src; - rtx btr_rtx; - rtx_insn *new_insn; - machine_mode btr_mode; - btr_user *user; - rtx set; - - if (dump_file) - fprintf(dump_file, "migrating to basic block %d, using reg %d\n", - new_def_bb->index, btr); - - clear_btr_from_live_range (def); - def->btr = btr; - def->bb = new_def_bb; - def->luid = 0; - def->cost = basic_block_freq (new_def_bb); - bitmap_copy (def->live_range, live_range); - combine_btr_defs (def, btrs_live_in_range); - btr = def->btr; - def->other_btr_uses_before_def - = TEST_HARD_REG_BIT (btrs_live[b->index], btr) ? 1 : 0; - add_btr_to_live_range (def, 1); - if (LABEL_P (insp)) - insp = NEXT_INSN (insp); - /* N.B.: insp is expected to be NOTE_INSN_BASIC_BLOCK now. Some - optimizations can result in insp being both first and last insn of - its basic block. */ - /* ?? some assertions to check that insp is sensible? */ - - if (def->other_btr_uses_before_def) - { - for (insp = BB_END (b); ! INSN_P (insp); insp = PREV_INSN (insp)) - gcc_assert (insp != BB_HEAD (b)); - - if (JUMP_P (insp) || can_throw_internal (insp)) - insp = PREV_INSN (insp); - } - - set = single_set (old_insn); - src = SET_SRC (set); - btr_mode = GET_MODE (SET_DEST (set)); - btr_rtx = gen_rtx_REG (btr_mode, btr); - - new_insn = gen_move_insn (btr_rtx, src); - - /* Insert target register initialization at head of basic block. */ - def->insn = emit_insn_after (new_insn, insp); - - df_set_regs_ever_live (btr, true); - - if (dump_file) - fprintf (dump_file, "New pt is insn %d, inserted after insn %d\n", - INSN_UID (def->insn), INSN_UID (insp)); - - /* Delete the old target register initialization. */ - delete_insn (old_insn); - - /* Replace each use of the old target register by a use of the new target - register. */ - for (user = def->uses; user != NULL; user = user->next) - { - /* Some extra work here to ensure consistent modes, because - it seems that a target register REG rtx can be given a different - mode depending on the context (surely that should not be - the case?). */ - rtx replacement_rtx; - if (GET_MODE (user->use) == GET_MODE (btr_rtx) - || GET_MODE (user->use) == VOIDmode) - replacement_rtx = btr_rtx; - else - replacement_rtx = gen_rtx_REG (GET_MODE (user->use), btr); - validate_replace_rtx (user->use, replacement_rtx, user->insn); - user->use = replacement_rtx; - } -} - -/* We anticipate intra-block scheduling to be done. See if INSN could move - up within BB by N_INSNS. */ -static int -can_move_up (const_basic_block bb, const rtx_insn *insn, int n_insns) -{ - while (insn != BB_HEAD (bb) && n_insns > 0) - { - insn = PREV_INSN (insn); - /* ??? What if we have an anti-dependency that actually prevents the - scheduler from doing the move? We'd like to re-allocate the register, - but not necessarily put the load into another basic block. */ - if (INSN_P (insn)) - n_insns--; - } - return n_insns <= 0; -} - -/* Attempt to migrate the target register definition DEF to an - earlier point in the flowgraph. - - It is a precondition of this function that DEF is migratable: - i.e. it has a constant source, and all uses are unambiguous. - - Only migrations that reduce the cost of DEF will be made. - MIN_COST is the lower bound on the cost of the DEF after migration. - If we migrate DEF so that its cost falls below MIN_COST, - then we do not attempt to migrate further. The idea is that - we migrate definitions in a priority order based on their cost, - when the cost of this definition falls below MIN_COST, then - there is another definition with cost == MIN_COST which now - has a higher priority than this definition. - - Return nonzero if there may be benefit from attempting to - migrate this DEF further (i.e. we have reduced the cost below - MIN_COST, but we may be able to reduce it further). - Return zero if no further migration is possible. */ -static int -migrate_btr_def (btr_def *def, int min_cost) -{ - HARD_REG_SET btrs_live_in_range; - int btr_used_near_def = 0; - int def_basic_block_freq; - basic_block attempt; - int give_up = 0; - int def_moved = 0; - btr_user *user; - int def_latency; - - if (dump_file) - fprintf (dump_file, - "Attempting to migrate pt from insn %d (cost = %d, min_cost = %d) ... ", - INSN_UID (def->insn), def->cost, min_cost); - - if (!def->group || def->has_ambiguous_use) - /* These defs are not migratable. */ - { - if (dump_file) - fprintf (dump_file, "it's not migratable\n"); - return 0; - } - - if (!def->uses) - /* We have combined this def with another in the same group, so - no need to consider it further. - */ - { - if (dump_file) - fprintf (dump_file, "it's already combined with another pt\n"); - return 0; - } - - btr_def_live_range (def, &btrs_live_in_range); - auto_bitmap live_range; - bitmap_copy (live_range, def->live_range); - -#ifdef INSN_SCHEDULING - def_latency = insn_default_latency (def->insn) * issue_rate; -#else - def_latency = issue_rate; -#endif - - for (user = def->uses; user != NULL; user = user->next) - { - if (user->bb == def->bb - && user->luid > def->luid - && (def->luid + def_latency) > user->luid - && ! can_move_up (def->bb, def->insn, - (def->luid + def_latency) - user->luid)) - { - btr_used_near_def = 1; - break; - } - } - - def_basic_block_freq = basic_block_freq (def->bb); - - for (attempt = get_immediate_dominator (CDI_DOMINATORS, def->bb); - !give_up && attempt && attempt != ENTRY_BLOCK_PTR_FOR_FN (cfun) - && def->cost >= min_cost; - attempt = get_immediate_dominator (CDI_DOMINATORS, attempt)) - { - /* Try to move the instruction that sets the target register into - basic block ATTEMPT. */ - int try_freq = basic_block_freq (attempt); - edge_iterator ei; - edge e; - - /* If ATTEMPT has abnormal edges, skip it. */ - FOR_EACH_EDGE (e, ei, attempt->succs) - if (e->flags & EDGE_COMPLEX) - break; - if (e) - continue; - - if (dump_file) - fprintf (dump_file, "trying block %d ...", attempt->index); - - if (try_freq < def_basic_block_freq - || (try_freq == def_basic_block_freq && btr_used_near_def)) - { - int btr; - augment_live_range (live_range, &btrs_live_in_range, def->bb, attempt, - flag_btr_bb_exclusive); - if (dump_file) - { - fprintf (dump_file, "Now btrs live in range are: "); - dump_hard_reg_set (btrs_live_in_range); - fprintf (dump_file, "\n"); - } - btr = choose_btr (btrs_live_in_range); - if (btr != -1) - { - move_btr_def (attempt, btr, def, live_range, &btrs_live_in_range); - bitmap_copy (live_range, def->live_range); - btr_used_near_def = 0; - def_moved = 1; - def_basic_block_freq = basic_block_freq (def->bb); - } - else - { - /* There are no free target registers available to move - this far forward, so give up */ - give_up = 1; - if (dump_file) - fprintf (dump_file, - "giving up because there are no free target registers\n"); - } - - } - } - if (!def_moved) - { - give_up = 1; - if (dump_file) - fprintf (dump_file, "failed to move\n"); - } - - return !give_up; -} - -/* Attempt to move instructions that set target registers earlier - in the flowgraph, away from their corresponding uses. */ -static void -migrate_btr_defs (enum reg_class btr_class, int allow_callee_save) -{ - btr_heap_t all_btr_defs (LONG_MIN); - int reg; - - gcc_obstack_init (&migrate_btrl_obstack); - if (dump_file) - { - int i; - - for (i = NUM_FIXED_BLOCKS; i < last_basic_block_for_fn (cfun); i++) - { - basic_block bb = BASIC_BLOCK_FOR_FN (cfun, i); - fprintf (dump_file, "Basic block %d: count = ", i); - bb->count.dump (dump_file); - fprintf (dump_file, " loop-depth = %d idom = %d\n", - bb_loop_depth (bb), - get_immediate_dominator (CDI_DOMINATORS, bb)->index); - } - } - - CLEAR_HARD_REG_SET (all_btrs); - for (first_btr = -1, reg = 0; reg < FIRST_PSEUDO_REGISTER; reg++) - if (TEST_HARD_REG_BIT (reg_class_contents[(int) btr_class], reg) - && (allow_callee_save || call_used_regs[reg] - || df_regs_ever_live_p (reg))) - { - SET_HARD_REG_BIT (all_btrs, reg); - last_btr = reg; - if (first_btr < 0) - first_btr = reg; - } - - btrs_live = XCNEWVEC (HARD_REG_SET, last_basic_block_for_fn (cfun)); - btrs_live_at_end = XCNEWVEC (HARD_REG_SET, last_basic_block_for_fn (cfun)); - - build_btr_def_use_webs (&all_btr_defs); - - while (!all_btr_defs.empty ()) - { - int min_cost = -all_btr_defs.min_key (); - btr_def *def = all_btr_defs.extract_min (); - if (migrate_btr_def (def, min_cost)) - { - all_btr_defs.insert (-def->cost, def); - if (dump_file) - { - fprintf (dump_file, - "Putting insn %d back on queue with priority %d\n", - INSN_UID (def->insn), def->cost); - } - } - else - BITMAP_FREE (def->live_range); - } - - free (btrs_live); - free (btrs_live_at_end); - obstack_free (&migrate_btrl_obstack, NULL); -} - -static void -branch_target_load_optimize (bool after_prologue_epilogue_gen) -{ - enum reg_class klass - = (enum reg_class) targetm.branch_target_register_class (); - if (klass != NO_REGS) - { - /* Initialize issue_rate. */ - if (targetm.sched.issue_rate) - issue_rate = targetm.sched.issue_rate (); - else - issue_rate = 1; - - if (!after_prologue_epilogue_gen) - { - /* Build the CFG for migrate_btr_defs. */ -#if 1 - /* This may or may not be needed, depending on where we - run this phase. */ - cleanup_cfg (optimize ? CLEANUP_EXPENSIVE : 0); -#endif - } - df_analyze (); - - - /* Dominator info is also needed for migrate_btr_def. */ - calculate_dominance_info (CDI_DOMINATORS); - migrate_btr_defs (klass, - (targetm.branch_target_register_callee_saved - (after_prologue_epilogue_gen))); - - free_dominance_info (CDI_DOMINATORS); - } -} - -namespace { - -const pass_data pass_data_branch_target_load_optimize1 = -{ - RTL_PASS, /* type */ - "btl1", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - TV_NONE, /* tv_id */ - 0, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - 0, /* todo_flags_finish */ -}; - -class pass_branch_target_load_optimize1 : public rtl_opt_pass -{ -public: - pass_branch_target_load_optimize1 (gcc::context *ctxt) - : rtl_opt_pass (pass_data_branch_target_load_optimize1, ctxt) - {} - - /* opt_pass methods: */ - virtual bool gate (function *) { return flag_branch_target_load_optimize; } - virtual unsigned int execute (function *) - { - branch_target_load_optimize (epilogue_completed); - return 0; - } - -}; // class pass_branch_target_load_optimize1 - -} // anon namespace - -rtl_opt_pass * -make_pass_branch_target_load_optimize1 (gcc::context *ctxt) -{ - return new pass_branch_target_load_optimize1 (ctxt); -} - - -namespace { - -const pass_data pass_data_branch_target_load_optimize2 = -{ - RTL_PASS, /* type */ - "btl2", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - TV_NONE, /* tv_id */ - 0, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - 0, /* todo_flags_finish */ -}; - -class pass_branch_target_load_optimize2 : public rtl_opt_pass -{ -public: - pass_branch_target_load_optimize2 (gcc::context *ctxt) - : rtl_opt_pass (pass_data_branch_target_load_optimize2, ctxt) - {} - - /* opt_pass methods: */ - virtual bool gate (function *) - { - return (optimize > 0 && flag_branch_target_load_optimize2); - } - - virtual unsigned int execute (function *); - -}; // class pass_branch_target_load_optimize2 - -unsigned int -pass_branch_target_load_optimize2::execute (function *) -{ - static int warned = 0; - - /* Leave this a warning for now so that it is possible to experiment - with running this pass twice. In 3.6, we should either make this - an error, or use separate dump files. */ - if (flag_branch_target_load_optimize - && flag_branch_target_load_optimize2 - && !warned) - { - warning (0, "branch target register load optimization is not intended " - "to be run twice"); - - warned = 1; - } - - branch_target_load_optimize (epilogue_completed); - return 0; -} - -} // anon namespace - -rtl_opt_pass * -make_pass_branch_target_load_optimize2 (gcc::context *ctxt) -{ - return new pass_branch_target_load_optimize2 (ctxt); -} diff --git a/gcc/common.opt b/gcc/common.opt index f2214ed..0d165f5 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -1076,16 +1076,16 @@ Common Report Var(flag_branch_probabilities) Optimization Use profiling information for branch probabilities. fbranch-target-load-optimize -Common Report Var(flag_branch_target_load_optimize) Optimization -Perform branch target load optimization before prologue / epilogue threading. +Common Ignore +Does nothing. Preserved for backward compatibility. fbranch-target-load-optimize2 -Common Report Var(flag_branch_target_load_optimize2) Optimization -Perform branch target load optimization after prologue / epilogue threading. +Common Ignore +Does nothing. Preserved for backward compatibility. fbtr-bb-exclusive -Common Report Var(flag_btr_bb_exclusive) Optimization -Restrict target load migration not to re-use registers in any basic block. +Common Ignore +Does nothing. Preserved for backward compatibility. fcall-saved- Common Joined RejectNegative Var(common_deferred_options) Defer diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 7bcdfcb..ef23a7d 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -406,8 +406,7 @@ Objective-C and Objective-C++ Dialects}. -falign-loops[=@var{n}[:@var{m}:[@var{n2}[:@var{m2}]]]] @gol -fassociative-math -fauto-profile -fauto-profile[=@var{path}] @gol -fauto-inc-dec -fbranch-probabilities @gol --fbranch-target-load-optimize -fbranch-target-load-optimize2 @gol --fbtr-bb-exclusive -fcaller-saves @gol +-fcaller-saves @gol -fcombine-stack-adjustments -fconserve-stack @gol -fcompare-elim -fcprop-registers -fcrossjumping @gol -fcse-follow-jumps -fcse-skip-blocks -fcx-fortran-rules @gol @@ -11025,24 +11024,6 @@ locations inside a translation unit since the locations are unknown until link time. An example of such an optimization is relaxing calls to short call instructions. -@item -fbranch-target-load-optimize -@opindex fbranch-target-load-optimize -Perform branch target register load optimization before prologue / epilogue -threading. -The use of target registers can typically be exposed only during reload, -thus hoisting loads out of loops and doing inter-block scheduling needs -a separate optimization pass. - -@item -fbranch-target-load-optimize2 -@opindex fbranch-target-load-optimize2 -Perform branch target register load optimization after prologue / epilogue -threading. - -@item -fbtr-bb-exclusive -@opindex fbtr-bb-exclusive -When performing branch target register load optimization, don't reuse -branch target registers within any basic block. - @item -fstdarg-opt @opindex fstdarg-opt Optimize the prologue of variadic argument functions with respect to usage of diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 0b5a08d..7bb8157 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -11755,28 +11755,6 @@ cannot_modify_jumps_past_reload_p () @end smallexample @end deftypefn -@deftypefn {Target Hook} reg_class_t TARGET_BRANCH_TARGET_REGISTER_CLASS (void) -This target hook returns a register class for which branch target register -optimizations should be applied. All registers in this class should be -usable interchangeably. After reload, registers in this class will be -re-allocated and loads will be hoisted out of loops and be subjected -to inter-block scheduling. -@end deftypefn - -@deftypefn {Target Hook} bool TARGET_BRANCH_TARGET_REGISTER_CALLEE_SAVED (bool @var{after_prologue_epilogue_gen}) -Branch target register optimization will by default exclude callee-saved -registers -that are not already live during the current function; if this target hook -returns true, they will be included. The target code must than make sure -that all target registers in the class returned by -@samp{TARGET_BRANCH_TARGET_REGISTER_CLASS} that might need saving are -saved. @var{after_prologue_epilogue_gen} indicates if prologues and -epilogues have already been generated. Note, even if you only return -true when @var{after_prologue_epilogue_gen} is false, you still are likely -to have to make special provisions in @code{INITIAL_ELIMINATION_OFFSET} -to reserve space for caller-saved target registers. -@end deftypefn - @deftypefn {Target Hook} bool TARGET_HAVE_CONDITIONAL_EXECUTION (void) This target hook returns true if the target supports conditional execution. This target hook is required only when the target has several different diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index a920055..e926c10 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -8001,10 +8001,6 @@ build_type_attribute_variant (@var{mdecl}, @hook TARGET_CANNOT_MODIFY_JUMPS_P -@hook TARGET_BRANCH_TARGET_REGISTER_CLASS - -@hook TARGET_BRANCH_TARGET_REGISTER_CALLEE_SAVED - @hook TARGET_HAVE_CONDITIONAL_EXECUTION @hook TARGET_GEN_CCMP_FIRST diff --git a/gcc/opt-suggestions.c b/gcc/opt-suggestions.c index a820c78..1ec9420 100644 --- a/gcc/opt-suggestions.c +++ b/gcc/opt-suggestions.c @@ -307,7 +307,6 @@ test_completion_valid_options (option_proposer &proposer) "-Wassign-intercept", "-Wno-format-security", "-fno-sched-stalled-insns", - "-fbtr-bb-exclusive", "-fno-tree-tail-merge", "-Wlong-long", "-Wno-unused-but-set-parameter", diff --git a/gcc/passes.def b/gcc/passes.def index e50cf62..9387922 100644 --- a/gcc/passes.def +++ b/gcc/passes.def @@ -461,7 +461,6 @@ along with GCC; see the file COPYING3. If not see NEXT_PASS (pass_split_after_reload); NEXT_PASS (pass_ree); NEXT_PASS (pass_compare_elim_after_reload); - NEXT_PASS (pass_branch_target_load_optimize1); NEXT_PASS (pass_thread_prologue_and_epilogue); NEXT_PASS (pass_rtl_dse2); NEXT_PASS (pass_stack_adjustments); @@ -474,7 +473,6 @@ along with GCC; see the file COPYING3. If not see NEXT_PASS (pass_cprop_hardreg); NEXT_PASS (pass_fast_rtl_dce); NEXT_PASS (pass_reorder_blocks); - NEXT_PASS (pass_branch_target_load_optimize2); NEXT_PASS (pass_leaf_regs); NEXT_PASS (pass_split_before_sched2); NEXT_PASS (pass_sched2); diff --git a/gcc/target.def b/gcc/target.def index ca7e7ad..825c1e6 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -2597,38 +2597,6 @@ DEFHOOK bool, (const rtx_insn *follower, const rtx_insn *followee), hook_bool_const_rtx_insn_const_rtx_insn_true) -/* Return a register class for which branch target register - optimizations should be applied. */ -DEFHOOK -(branch_target_register_class, - "This target hook returns a register class for which branch target register\n\ -optimizations should be applied. All registers in this class should be\n\ -usable interchangeably. After reload, registers in this class will be\n\ -re-allocated and loads will be hoisted out of loops and be subjected\n\ -to inter-block scheduling.", - reg_class_t, (void), - default_branch_target_register_class) - -/* Return true if branch target register optimizations should include - callee-saved registers that are not already live during the current - function. AFTER_PE_GEN is true if prologues and epilogues have - already been generated. */ -DEFHOOK -(branch_target_register_callee_saved, - "Branch target register optimization will by default exclude callee-saved\n\ -registers\n\ -that are not already live during the current function; if this target hook\n\ -returns true, they will be included. The target code must than make sure\n\ -that all target registers in the class returned by\n\ -@samp{TARGET_BRANCH_TARGET_REGISTER_CLASS} that might need saving are\n\ -saved. @var{after_prologue_epilogue_gen} indicates if prologues and\n\ -epilogues have already been generated. Note, even if you only return\n\ -true when @var{after_prologue_epilogue_gen} is false, you still are likely\n\ -to have to make special provisions in @code{INITIAL_ELIMINATION_OFFSET}\n\ -to reserve space for caller-saved target registers.", - bool, (bool after_prologue_epilogue_gen), - hook_bool_bool_false) - /* Return true if the target supports conditional execution. */ DEFHOOK (have_conditional_execution, diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 1d12ec5..ed77afb 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -1054,12 +1054,6 @@ default_return_pops_args (tree, tree, poly_int64) } reg_class_t -default_branch_target_register_class (void) -{ - return NO_REGS; -} - -reg_class_t default_ira_change_pseudo_allocno_class (int regno ATTRIBUTE_UNUSED, reg_class_t cl, reg_class_t best_cl ATTRIBUTE_UNUSED) diff --git a/gcc/targhooks.h b/gcc/targhooks.h index 20a6e79..5aba676 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -164,7 +164,6 @@ extern rtx default_internal_arg_pointer (void); extern rtx default_static_chain (const_tree, bool); extern void default_trampoline_init (rtx, tree, rtx); extern poly_int64 default_return_pops_args (tree, tree, poly_int64); -extern reg_class_t default_branch_target_register_class (void); extern reg_class_t default_ira_change_pseudo_allocno_class (int, reg_class_t, reg_class_t); extern bool default_lra_p (void); diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index be7603a..7106eba 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -585,8 +585,6 @@ extern rtl_opt_pass *make_pass_postreload_jump (gcc::context *ctxt); extern rtl_opt_pass *make_pass_postreload_cse (gcc::context *ctxt); extern rtl_opt_pass *make_pass_gcse2 (gcc::context *ctxt); extern rtl_opt_pass *make_pass_split_after_reload (gcc::context *ctxt); -extern rtl_opt_pass *make_pass_branch_target_load_optimize1 (gcc::context - *ctxt); extern rtl_opt_pass *make_pass_thread_prologue_and_epilogue (gcc::context *ctxt); extern rtl_opt_pass *make_pass_stack_adjustments (gcc::context *ctxt); @@ -596,8 +594,6 @@ extern rtl_opt_pass *make_pass_if_after_reload (gcc::context *ctxt); extern rtl_opt_pass *make_pass_regrename (gcc::context *ctxt); extern rtl_opt_pass *make_pass_cprop_hardreg (gcc::context *ctxt); extern rtl_opt_pass *make_pass_reorder_blocks (gcc::context *ctxt); -extern rtl_opt_pass *make_pass_branch_target_load_optimize2 (gcc::context - *ctxt); extern rtl_opt_pass *make_pass_leaf_regs (gcc::context *ctxt); extern rtl_opt_pass *make_pass_split_before_sched2 (gcc::context *ctxt); extern rtl_opt_pass *make_pass_compare_elim_after_reload (gcc::context *ctxt); -- cgit v1.1 From 812b3c62a7c8b3c006196635d0da08acc5674d98 Mon Sep 17 00:00:00 2001 From: Segher Boessenkool Date: Mon, 9 Sep 2019 19:57:39 +0200 Subject: rs6000: Update rlwinm-[012].c gcc/testsuite/ * gcc.target/powerpc/rlwinm-0.c: Adjust expected instruction counts. * gcc.target/powerpc/rlwinm-1.c: Ditto. * gcc.target/powerpc/rlwinm-2.c: Ditto. From-SVN: r275525 --- gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/gcc.target/powerpc/rlwinm-0.c | 8 ++++---- gcc/testsuite/gcc.target/powerpc/rlwinm-1.c | 8 ++++---- gcc/testsuite/gcc.target/powerpc/rlwinm-2.c | 8 ++++---- 4 files changed, 18 insertions(+), 12 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6129f91..3d4ada8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2019-09-09 Segher Boessenkool + + * gcc.target/powerpc/rlwinm-0.c: Adjust expected instruction counts. + * gcc.target/powerpc/rlwinm-1.c: Ditto. + * gcc.target/powerpc/rlwinm-2.c: Ditto. + 2019-09-09 Barnaby Wilks * gcc.dg/fold-binary-math-casts.c: New test. diff --git a/gcc/testsuite/gcc.target/powerpc/rlwinm-0.c b/gcc/testsuite/gcc.target/powerpc/rlwinm-0.c index 2940b62..4f4fca2 100644 --- a/gcc/testsuite/gcc.target/powerpc/rlwinm-0.c +++ b/gcc/testsuite/gcc.target/powerpc/rlwinm-0.c @@ -2,15 +2,15 @@ /* { dg-options "-O2" } */ /* { dg-final { scan-assembler-times {(?n)^\s+[a-z]} 6739 { target ilp32 } } } */ -/* { dg-final { scan-assembler-times {(?n)^\s+[a-z]} 9730 { target lp64 } } } */ +/* { dg-final { scan-assembler-times {(?n)^\s+[a-z]} 9716 { target lp64 } } } */ /* { dg-final { scan-assembler-times {(?n)^\s+blr} 3375 } } */ -/* { dg-final { scan-assembler-times {(?n)^\s+rldicl} 3095 { target lp64 } } } */ +/* { dg-final { scan-assembler-times {(?n)^\s+rldicl} 3081 { target lp64 } } } */ /* { dg-final { scan-assembler-times {(?n)^\s+rlwinm} 3197 { target ilp32 } } } */ -/* { dg-final { scan-assembler-times {(?n)^\s+rlwinm} 3094 { target lp64 } } } */ +/* { dg-final { scan-assembler-times {(?n)^\s+rlwinm} 3093 { target lp64 } } } */ /* { dg-final { scan-assembler-times {(?n)^\s+rotlwi} 154 } } */ /* { dg-final { scan-assembler-times {(?n)^\s+srwi} 13 { target ilp32 } } } */ -/* { dg-final { scan-assembler-times {(?n)^\s+srdi} 12 { target lp64 } } } */ +/* { dg-final { scan-assembler-times {(?n)^\s+srdi} 13 { target lp64 } } } */ #define SL diff --git a/gcc/testsuite/gcc.target/powerpc/rlwinm-1.c b/gcc/testsuite/gcc.target/powerpc/rlwinm-1.c index 0fc08a6..4dfbd2e 100644 --- a/gcc/testsuite/gcc.target/powerpc/rlwinm-1.c +++ b/gcc/testsuite/gcc.target/powerpc/rlwinm-1.c @@ -2,14 +2,14 @@ /* { dg-options "-O2" } */ /* { dg-final { scan-assembler-times {(?n)^\s+[a-z]} 6739 { target ilp32 } } } */ -/* { dg-final { scan-assembler-times {(?n)^\s+[a-z]} 9606 { target lp64 } } } */ +/* { dg-final { scan-assembler-times {(?n)^\s+[a-z]} 9496 { target lp64 } } } */ /* { dg-final { scan-assembler-times {(?n)^\s+blr} 3375 } } */ -/* { dg-final { scan-assembler-times {(?n)^\s+rldic} 2946 { target lp64 } } } */ +/* { dg-final { scan-assembler-times {(?n)^\s+rldic} 2847 { target lp64 } } } */ /* { dg-final { scan-assembler-times {(?n)^\s+rlwinm} 691 { target ilp32 } } } */ -/* { dg-final { scan-assembler-times {(?n)^\s+rlwinm} 622 { target lp64 } } } */ +/* { dg-final { scan-assembler-times {(?n)^\s+rlwinm} 612 { target lp64 } } } */ /* { dg-final { scan-assembler-times {(?n)^\s+slwi} 11 { target ilp32 } } } */ -/* { dg-final { scan-assembler-times {(?n)^\s+slwi} 1 { target lp64 } } } */ +/* { dg-final { scan-assembler-times {(?n)^\s+slwi} 0 { target lp64 } } } */ /* { dg-final { scan-assembler-times {(?n)^\s+mulli} 2662 { target ilp32 } } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/rlwinm-2.c b/gcc/testsuite/gcc.target/powerpc/rlwinm-2.c index 4087ac0..bddcfe2 100644 --- a/gcc/testsuite/gcc.target/powerpc/rlwinm-2.c +++ b/gcc/testsuite/gcc.target/powerpc/rlwinm-2.c @@ -2,14 +2,14 @@ /* { dg-options "-O2" } */ /* { dg-final { scan-assembler-times {(?n)^\s+[a-z]} 6739 { target ilp32 } } } */ -/* { dg-final { scan-assembler-times {(?n)^\s+[a-z]} 9466 { target lp64 } } } */ +/* { dg-final { scan-assembler-times {(?n)^\s+[a-z]} 9352 { target lp64 } } } */ /* { dg-final { scan-assembler-times {(?n)^\s+blr} 3375 } } */ -/* { dg-final { scan-assembler-times {(?n)^\s+rldic} 2840 { target lp64 } } } */ +/* { dg-final { scan-assembler-times {(?n)^\s+rldic} 2726 { target lp64 } } } */ /* { dg-final { scan-assembler-times {(?n)^\s+rlwinm} 833 { target ilp32 } } } */ -/* { dg-final { scan-assembler-times {(?n)^\s+rlwinm} 721 { target lp64 } } } */ +/* { dg-final { scan-assembler-times {(?n)^\s+rlwinm} 720 { target lp64 } } } */ /* { dg-final { scan-assembler-times {(?n)^\s+srwi} 13 { target ilp32 } } } */ -/* { dg-final { scan-assembler-times {(?n)^\s+srdi} 12 { target lp64 } } } */ +/* { dg-final { scan-assembler-times {(?n)^\s+srdi} 13 { target lp64 } } } */ /* { dg-final { scan-assembler-times {(?n)^\s+mulli} 2518 } } */ -- cgit v1.1 From 504279ae0a0ce28ad37f820dcdb7f6557aabef7c Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Mon, 9 Sep 2019 17:58:36 +0000 Subject: Simplify the implementation of HARD_REG_SET We have two styles of HARD_REG_SET: a single integer based on HOST_WIDEST_FAST_INT (used when FIRST_PSEUDO_REGISTER is small enough) or an array of integers. One of the nice properties of this arrangement is that: void foo (const HARD_REG_SET); is passed by value as an integer when the set is small enough and by reference otherwise. (This is in constrast to "const HARD_REG_SET &", which would always be passed by reference, and in contrast to passing a structure wrapper like "struct s { T elts[1]; }" by value, where the structure might be passed like a T or by reference, depending on the ABI.) However, one of the disadvantages of using an array is that simple assignment doesn't work. We need to use COPY_HARD_REG_SET instead. This patch uses a structure wrapper around the array, and preserves the above "nice property" using a new const_hard_reg_set typedef. The patch also removes the manual unrolling for small array sizes; I think these days we can rely on the compiler to do that for us. This meant fixing two port-specific quirks: - epiphany passed NULL as a HARD_REG_SET whose value doesn't matter. The patch passes the NO_REGS set instead. - ia64 reused TEST_HARD_REG_BIT and SET_HARD_REG_BIT for arrays that are bigger than HARD_REG_SET. The patch just open-codes them. The patch is probably being too conservative. Very few places actually take advantage of the "nice property" above, and we could have a cleaner interface if we used a structure wrapper for all cases. 2019-09-09 Richard Sandiford gcc/ * hard-reg-set.h (HARD_REG_SET): Define using a typedef rather than a #define. Use a structure rather than an array as the fallback definition. Remove special cases for low array sizes. (const_hard_reg_set): New typedef. (hard_reg_set_subset_p): Use it instead of "const HARD_REG_SET". (hard_reg_set_equal_p, hard_reg_set_intersect_p): Likewise. (hard_reg_set_empty_p): Likewise. (SET_HARD_REG_BIT): Use a function rather than a macro to handle the case in which HARD_REG_SET is a structure. (CLEAR_HARD_REG_BIT, TEST_HARD_REG_BIT, CLEAR_HARD_REG_SET) (SET_HARD_REG_SET, COPY_HARD_REG_SET, COMPL_HARD_REG_SET) (AND_HARD_REG_SET, AND_COMPL_HARD_REG_SET, IOR_HARD_REG_SET) (IOR_COMPL_HARD_REG_SET): Likewise. (hard_reg_set_iterator::pset): Constify the pointer target. (hard_reg_set_iter_init): Take a const_hard_reg_set instead of a "const HARD_REG_SET". Update the handling of non-integer HARD_REG_SETs. * recog.h: Test HARD_CONST instead of CLEAR_HARD_REG_SET. * reload.h: Likewise. * rtl.h (choose_hard_reg_mode): Remove unnecessary line break. * regs.h (in_hard_reg_set_p): Take a const_hard_reg_set instead of a "const HARD_REG_SET". (overlaps_hard_reg_set_p, range_overlaps_hard_reg_set_p): Likewise. (range_in_hard_reg_set_p): Likewise. * ira-costs.c (restrict_cost_classes): Likewise. * shrink-wrap.c (move_insn_for_shrink_wrap): Likewise. * config/epiphany/resolve-sw-modes.c (pass_resolve_sw_modes::execute): Pass a NO_REGS HARD_REG_SET rather than NULL to emit_set_fp_mode. * config/ia64/ia64.c (rws_insn): In the CHECKING_P version, use unsigned HOST_WIDEST_FAST_INT rather than HARD_REG_ELT_TYPE. (rws_insn_set, rws_insn_test): In the CHECKING_P version, take an unsigned int and open-code the HARD_REG_SET operations. From-SVN: r275526 --- gcc/ChangeLog | 35 +++ gcc/config/epiphany/resolve-sw-modes.c | 3 +- gcc/config/ia64/ia64.c | 19 +- gcc/hard-reg-set.h | 405 +++++++-------------------------- gcc/ira-costs.c | 2 +- gcc/recog.h | 2 +- gcc/regs.h | 8 +- gcc/reload.h | 4 +- gcc/rtl.h | 3 +- gcc/shrink-wrap.c | 4 +- 10 files changed, 139 insertions(+), 346 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f640d89..482a50f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,40 @@ 2019-09-09 Richard Sandiford + * hard-reg-set.h (HARD_REG_SET): Define using a typedef rather + than a #define. Use a structure rather than an array as the + fallback definition. Remove special cases for low array sizes. + (const_hard_reg_set): New typedef. + (hard_reg_set_subset_p): Use it instead of "const HARD_REG_SET". + (hard_reg_set_equal_p, hard_reg_set_intersect_p): Likewise. + (hard_reg_set_empty_p): Likewise. + (SET_HARD_REG_BIT): Use a function rather than a macro to + handle the case in which HARD_REG_SET is a structure. + (CLEAR_HARD_REG_BIT, TEST_HARD_REG_BIT, CLEAR_HARD_REG_SET) + (SET_HARD_REG_SET, COPY_HARD_REG_SET, COMPL_HARD_REG_SET) + (AND_HARD_REG_SET, AND_COMPL_HARD_REG_SET, IOR_HARD_REG_SET) + (IOR_COMPL_HARD_REG_SET): Likewise. + (hard_reg_set_iterator::pset): Constify the pointer target. + (hard_reg_set_iter_init): Take a const_hard_reg_set instead + of a "const HARD_REG_SET". Update the handling of non-integer + HARD_REG_SETs. + * recog.h: Test HARD_CONST instead of CLEAR_HARD_REG_SET. + * reload.h: Likewise. + * rtl.h (choose_hard_reg_mode): Remove unnecessary line break. + * regs.h (in_hard_reg_set_p): Take a const_hard_reg_set instead + of a "const HARD_REG_SET". + (overlaps_hard_reg_set_p, range_overlaps_hard_reg_set_p): Likewise. + (range_in_hard_reg_set_p): Likewise. + * ira-costs.c (restrict_cost_classes): Likewise. + * shrink-wrap.c (move_insn_for_shrink_wrap): Likewise. + * config/epiphany/resolve-sw-modes.c (pass_resolve_sw_modes::execute): + Pass a NO_REGS HARD_REG_SET rather than NULL to emit_set_fp_mode. + * config/ia64/ia64.c (rws_insn): In the CHECKING_P version, + use unsigned HOST_WIDEST_FAST_INT rather than HARD_REG_ELT_TYPE. + (rws_insn_set, rws_insn_test): In the CHECKING_P version, + take an unsigned int and open-code the HARD_REG_SET operations. + +2019-09-09 Richard Sandiford + * Makefile.in (OBJS): Remove bt-load.o. * doc/invoke.texi (fbranch-target-load-optimize): Delete. (fbranch-target-load-optimize2, fbtr-bb-exclusive): Likewise. diff --git a/gcc/config/epiphany/resolve-sw-modes.c b/gcc/config/epiphany/resolve-sw-modes.c index c1d343b..9ecdf63 100644 --- a/gcc/config/epiphany/resolve-sw-modes.c +++ b/gcc/config/epiphany/resolve-sw-modes.c @@ -167,7 +167,8 @@ pass_resolve_sw_modes::execute (function *fun) } start_sequence (); emit_set_fp_mode (EPIPHANY_MSW_ENTITY_ROUND_UNKNOWN, - jilted_mode, FP_MODE_NONE, NULL); + jilted_mode, FP_MODE_NONE, + reg_class_contents[NO_REGS]); seq = get_insns (); end_sequence (); need_commit = true; diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index bfec69b..3768c8b 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -6230,20 +6230,25 @@ struct reg_write_state struct reg_write_state rws_sum[NUM_REGS]; #if CHECKING_P /* Bitmap whether a register has been written in the current insn. */ -HARD_REG_ELT_TYPE rws_insn[(NUM_REGS + HOST_BITS_PER_WIDEST_FAST_INT - 1) - / HOST_BITS_PER_WIDEST_FAST_INT]; +unsigned HOST_WIDEST_FAST_INT rws_insn + [(NUM_REGS + HOST_BITS_PER_WIDEST_FAST_INT - 1) + / HOST_BITS_PER_WIDEST_FAST_INT]; static inline void -rws_insn_set (int regno) +rws_insn_set (unsigned int regno) { - gcc_assert (!TEST_HARD_REG_BIT (rws_insn, regno)); - SET_HARD_REG_BIT (rws_insn, regno); + unsigned int elt = regno / HOST_BITS_PER_WIDEST_FAST_INT; + unsigned int bit = regno % HOST_BITS_PER_WIDEST_FAST_INT; + gcc_assert (!((rws_insn[elt] >> bit) & 1)); + rws_insn[elt] |= (unsigned HOST_WIDEST_FAST_INT) 1 << bit; } static inline int -rws_insn_test (int regno) +rws_insn_test (unsigned int regno) { - return TEST_HARD_REG_BIT (rws_insn, regno); + unsigned int elt = regno / HOST_BITS_PER_WIDEST_FAST_INT; + unsigned int bit = regno % HOST_BITS_PER_WIDEST_FAST_INT; + return (rws_insn[elt] >> bit) & 1; } #else /* When not checking, track just REG_AR_CFM and REG_VOLATILE. */ diff --git a/gcc/hard-reg-set.h b/gcc/hard-reg-set.h index bd4249b..32626ba 100644 --- a/gcc/hard-reg-set.h +++ b/gcc/hard-reg-set.h @@ -42,14 +42,20 @@ typedef unsigned HOST_WIDEST_FAST_INT HARD_REG_ELT_TYPE; #if FIRST_PSEUDO_REGISTER <= HOST_BITS_PER_WIDEST_FAST_INT -#define HARD_REG_SET HARD_REG_ELT_TYPE +typedef HARD_REG_ELT_TYPE HARD_REG_SET; +typedef const HARD_REG_SET const_hard_reg_set; #else #define HARD_REG_SET_LONGS \ ((FIRST_PSEUDO_REGISTER + HOST_BITS_PER_WIDEST_FAST_INT - 1) \ / HOST_BITS_PER_WIDEST_FAST_INT) -typedef HARD_REG_ELT_TYPE HARD_REG_SET[HARD_REG_SET_LONGS]; + +struct HARD_REG_SET +{ + HARD_REG_ELT_TYPE elts[HARD_REG_SET_LONGS]; +}; +typedef const HARD_REG_SET &const_hard_reg_set; #endif @@ -98,7 +104,7 @@ struct hard_reg_set_container #define UHOST_BITS_PER_WIDE_INT ((unsigned) HOST_BITS_PER_WIDEST_FAST_INT) -#ifdef HARD_REG_SET +#if FIRST_PSEUDO_REGISTER <= HOST_BITS_PER_WIDEST_FAST_INT #define SET_HARD_REG_BIT(SET, BIT) \ ((SET) |= HARD_CONST (1) << (BIT)) @@ -119,395 +125,142 @@ struct hard_reg_set_container #define AND_COMPL_HARD_REG_SET(TO, FROM) ((TO) &= ~ (FROM)) static inline bool -hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y) +hard_reg_set_subset_p (const_hard_reg_set x, const_hard_reg_set y) { return (x & ~y) == HARD_CONST (0); } static inline bool -hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y) +hard_reg_set_equal_p (const_hard_reg_set x, const_hard_reg_set y) { return x == y; } static inline bool -hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y) +hard_reg_set_intersect_p (const_hard_reg_set x, const_hard_reg_set y) { return (x & y) != HARD_CONST (0); } static inline bool -hard_reg_set_empty_p (const HARD_REG_SET x) +hard_reg_set_empty_p (const_hard_reg_set x) { return x == HARD_CONST (0); } #else -#define SET_HARD_REG_BIT(SET, BIT) \ - ((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT] \ - |= HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT)) - -#define CLEAR_HARD_REG_BIT(SET, BIT) \ - ((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT] \ - &= ~(HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT))) - -#define TEST_HARD_REG_BIT(SET, BIT) \ - (!!((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT] \ - & (HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT)))) - -#if FIRST_PSEUDO_REGISTER <= 2*HOST_BITS_PER_WIDEST_FAST_INT -#define CLEAR_HARD_REG_SET(TO) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - scan_tp_[0] = 0; \ - scan_tp_[1] = 0; } while (0) - -#define SET_HARD_REG_SET(TO) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - scan_tp_[0] = -1; \ - scan_tp_[1] = -1; } while (0) - -#define COPY_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - const HARD_REG_ELT_TYPE *scan_fp_ = (FROM); \ - scan_tp_[0] = scan_fp_[0]; \ - scan_tp_[1] = scan_fp_[1]; } while (0) - -#define COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - const HARD_REG_ELT_TYPE *scan_fp_ = (FROM); \ - scan_tp_[0] = ~ scan_fp_[0]; \ - scan_tp_[1] = ~ scan_fp_[1]; } while (0) - -#define AND_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - const HARD_REG_ELT_TYPE *scan_fp_ = (FROM); \ - scan_tp_[0] &= scan_fp_[0]; \ - scan_tp_[1] &= scan_fp_[1]; } while (0) - -#define AND_COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - const HARD_REG_ELT_TYPE *scan_fp_ = (FROM); \ - scan_tp_[0] &= ~ scan_fp_[0]; \ - scan_tp_[1] &= ~ scan_fp_[1]; } while (0) - -#define IOR_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - const HARD_REG_ELT_TYPE *scan_fp_ = (FROM); \ - scan_tp_[0] |= scan_fp_[0]; \ - scan_tp_[1] |= scan_fp_[1]; } while (0) - -#define IOR_COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - const HARD_REG_ELT_TYPE *scan_fp_ = (FROM); \ - scan_tp_[0] |= ~ scan_fp_[0]; \ - scan_tp_[1] |= ~ scan_fp_[1]; } while (0) - -static inline bool -hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y) +inline void +SET_HARD_REG_BIT (HARD_REG_SET &set, unsigned int bit) { - return (x[0] & ~y[0]) == 0 && (x[1] & ~y[1]) == 0; + set.elts[bit / UHOST_BITS_PER_WIDE_INT] + |= HARD_CONST (1) << (bit % UHOST_BITS_PER_WIDE_INT); } -static inline bool -hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y) +inline void +CLEAR_HARD_REG_BIT (HARD_REG_SET &set, unsigned int bit) { - return x[0] == y[0] && x[1] == y[1]; + set.elts[bit / UHOST_BITS_PER_WIDE_INT] + &= ~(HARD_CONST (1) << (bit % UHOST_BITS_PER_WIDE_INT)); } -static inline bool -hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y) +inline bool +TEST_HARD_REG_BIT (const_hard_reg_set set, unsigned int bit) { - return (x[0] & y[0]) != 0 || (x[1] & y[1]) != 0; + return (set.elts[bit / UHOST_BITS_PER_WIDE_INT] + & (HARD_CONST (1) << (bit % UHOST_BITS_PER_WIDE_INT))); } -static inline bool -hard_reg_set_empty_p (const HARD_REG_SET x) +inline void +CLEAR_HARD_REG_SET (HARD_REG_SET &set) { - return x[0] == 0 && x[1] == 0; + for (unsigned int i = 0; i < ARRAY_SIZE (set.elts); ++i) + set.elts[i] = 0; } -#else -#if FIRST_PSEUDO_REGISTER <= 3*HOST_BITS_PER_WIDEST_FAST_INT -#define CLEAR_HARD_REG_SET(TO) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - scan_tp_[0] = 0; \ - scan_tp_[1] = 0; \ - scan_tp_[2] = 0; } while (0) - -#define SET_HARD_REG_SET(TO) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - scan_tp_[0] = -1; \ - scan_tp_[1] = -1; \ - scan_tp_[2] = -1; } while (0) - -#define COPY_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - const HARD_REG_ELT_TYPE *scan_fp_ = (FROM); \ - scan_tp_[0] = scan_fp_[0]; \ - scan_tp_[1] = scan_fp_[1]; \ - scan_tp_[2] = scan_fp_[2]; } while (0) - -#define COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - const HARD_REG_ELT_TYPE *scan_fp_ = (FROM); \ - scan_tp_[0] = ~ scan_fp_[0]; \ - scan_tp_[1] = ~ scan_fp_[1]; \ - scan_tp_[2] = ~ scan_fp_[2]; } while (0) - -#define AND_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - const HARD_REG_ELT_TYPE *scan_fp_ = (FROM); \ - scan_tp_[0] &= scan_fp_[0]; \ - scan_tp_[1] &= scan_fp_[1]; \ - scan_tp_[2] &= scan_fp_[2]; } while (0) - -#define AND_COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - const HARD_REG_ELT_TYPE *scan_fp_ = (FROM); \ - scan_tp_[0] &= ~ scan_fp_[0]; \ - scan_tp_[1] &= ~ scan_fp_[1]; \ - scan_tp_[2] &= ~ scan_fp_[2]; } while (0) - -#define IOR_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - const HARD_REG_ELT_TYPE *scan_fp_ = (FROM); \ - scan_tp_[0] |= scan_fp_[0]; \ - scan_tp_[1] |= scan_fp_[1]; \ - scan_tp_[2] |= scan_fp_[2]; } while (0) - -#define IOR_COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - const HARD_REG_ELT_TYPE *scan_fp_ = (FROM); \ - scan_tp_[0] |= ~ scan_fp_[0]; \ - scan_tp_[1] |= ~ scan_fp_[1]; \ - scan_tp_[2] |= ~ scan_fp_[2]; } while (0) - -static inline bool -hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y) +inline void +SET_HARD_REG_SET (HARD_REG_SET &set) { - return ((x[0] & ~y[0]) == 0 - && (x[1] & ~y[1]) == 0 - && (x[2] & ~y[2]) == 0); + for (unsigned int i = 0; i < ARRAY_SIZE (set.elts); ++i) + set.elts[i] = -1; } -static inline bool -hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y) +inline void +COPY_HARD_REG_SET (HARD_REG_SET &to, const_hard_reg_set from) { - return x[0] == y[0] && x[1] == y[1] && x[2] == y[2]; + to = from; } -static inline bool -hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y) +inline void +COMPL_HARD_REG_SET (HARD_REG_SET &to, const_hard_reg_set from) { - return ((x[0] & y[0]) != 0 - || (x[1] & y[1]) != 0 - || (x[2] & y[2]) != 0); + for (unsigned int i = 0; i < ARRAY_SIZE (to.elts); ++i) + to.elts[i] = ~from.elts[i]; } -static inline bool -hard_reg_set_empty_p (const HARD_REG_SET x) +inline void +AND_HARD_REG_SET (HARD_REG_SET &to, const_hard_reg_set from) { - return x[0] == 0 && x[1] == 0 && x[2] == 0; + for (unsigned int i = 0; i < ARRAY_SIZE (to.elts); ++i) + to.elts[i] &= from.elts[i]; } -#else -#if FIRST_PSEUDO_REGISTER <= 4*HOST_BITS_PER_WIDEST_FAST_INT -#define CLEAR_HARD_REG_SET(TO) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - scan_tp_[0] = 0; \ - scan_tp_[1] = 0; \ - scan_tp_[2] = 0; \ - scan_tp_[3] = 0; } while (0) - -#define SET_HARD_REG_SET(TO) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - scan_tp_[0] = -1; \ - scan_tp_[1] = -1; \ - scan_tp_[2] = -1; \ - scan_tp_[3] = -1; } while (0) - -#define COPY_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - const HARD_REG_ELT_TYPE *scan_fp_ = (FROM); \ - scan_tp_[0] = scan_fp_[0]; \ - scan_tp_[1] = scan_fp_[1]; \ - scan_tp_[2] = scan_fp_[2]; \ - scan_tp_[3] = scan_fp_[3]; } while (0) - -#define COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - const HARD_REG_ELT_TYPE *scan_fp_ = (FROM); \ - scan_tp_[0] = ~ scan_fp_[0]; \ - scan_tp_[1] = ~ scan_fp_[1]; \ - scan_tp_[2] = ~ scan_fp_[2]; \ - scan_tp_[3] = ~ scan_fp_[3]; } while (0) - -#define AND_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - const HARD_REG_ELT_TYPE *scan_fp_ = (FROM); \ - scan_tp_[0] &= scan_fp_[0]; \ - scan_tp_[1] &= scan_fp_[1]; \ - scan_tp_[2] &= scan_fp_[2]; \ - scan_tp_[3] &= scan_fp_[3]; } while (0) - -#define AND_COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - const HARD_REG_ELT_TYPE *scan_fp_ = (FROM); \ - scan_tp_[0] &= ~ scan_fp_[0]; \ - scan_tp_[1] &= ~ scan_fp_[1]; \ - scan_tp_[2] &= ~ scan_fp_[2]; \ - scan_tp_[3] &= ~ scan_fp_[3]; } while (0) - -#define IOR_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - const HARD_REG_ELT_TYPE *scan_fp_ = (FROM); \ - scan_tp_[0] |= scan_fp_[0]; \ - scan_tp_[1] |= scan_fp_[1]; \ - scan_tp_[2] |= scan_fp_[2]; \ - scan_tp_[3] |= scan_fp_[3]; } while (0) - -#define IOR_COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - const HARD_REG_ELT_TYPE *scan_fp_ = (FROM); \ - scan_tp_[0] |= ~ scan_fp_[0]; \ - scan_tp_[1] |= ~ scan_fp_[1]; \ - scan_tp_[2] |= ~ scan_fp_[2]; \ - scan_tp_[3] |= ~ scan_fp_[3]; } while (0) - -static inline bool -hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y) -{ - return ((x[0] & ~y[0]) == 0 - && (x[1] & ~y[1]) == 0 - && (x[2] & ~y[2]) == 0 - && (x[3] & ~y[3]) == 0); -} - -static inline bool -hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y) +inline void +AND_COMPL_HARD_REG_SET (HARD_REG_SET &to, const_hard_reg_set from) { - return x[0] == y[0] && x[1] == y[1] && x[2] == y[2] && x[3] == y[3]; + for (unsigned int i = 0; i < ARRAY_SIZE (to.elts); ++i) + to.elts[i] &= ~from.elts[i]; } -static inline bool -hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y) +inline void +IOR_HARD_REG_SET (HARD_REG_SET &to, const_hard_reg_set from) { - return ((x[0] & y[0]) != 0 - || (x[1] & y[1]) != 0 - || (x[2] & y[2]) != 0 - || (x[3] & y[3]) != 0); + for (unsigned int i = 0; i < ARRAY_SIZE (to.elts); ++i) + to.elts[i] |= from.elts[i]; } -static inline bool -hard_reg_set_empty_p (const HARD_REG_SET x) +inline void +IOR_COMPL_HARD_REG_SET (HARD_REG_SET &to, const_hard_reg_set from) { - return x[0] == 0 && x[1] == 0 && x[2] == 0 && x[3] == 0; + for (unsigned int i = 0; i < ARRAY_SIZE (to.elts); ++i) + to.elts[i] |= ~from.elts[i]; } -#else /* FIRST_PSEUDO_REGISTER > 4*HOST_BITS_PER_WIDEST_FAST_INT */ - -#define CLEAR_HARD_REG_SET(TO) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - int i; \ - for (i = 0; i < HARD_REG_SET_LONGS; i++) \ - *scan_tp_++ = 0; } while (0) - -#define SET_HARD_REG_SET(TO) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - int i; \ - for (i = 0; i < HARD_REG_SET_LONGS; i++) \ - *scan_tp_++ = -1; } while (0) - -#define COPY_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - const HARD_REG_ELT_TYPE *scan_fp_ = (FROM); \ - int i; \ - for (i = 0; i < HARD_REG_SET_LONGS; i++) \ - *scan_tp_++ = *scan_fp_++; } while (0) - -#define COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - const HARD_REG_ELT_TYPE *scan_fp_ = (FROM); \ - int i; \ - for (i = 0; i < HARD_REG_SET_LONGS; i++) \ - *scan_tp_++ = ~ *scan_fp_++; } while (0) - -#define AND_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - const HARD_REG_ELT_TYPE *scan_fp_ = (FROM); \ - int i; \ - for (i = 0; i < HARD_REG_SET_LONGS; i++) \ - *scan_tp_++ &= *scan_fp_++; } while (0) - -#define AND_COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - const HARD_REG_ELT_TYPE *scan_fp_ = (FROM); \ - int i; \ - for (i = 0; i < HARD_REG_SET_LONGS; i++) \ - *scan_tp_++ &= ~ *scan_fp_++; } while (0) - -#define IOR_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - const HARD_REG_ELT_TYPE *scan_fp_ = (FROM); \ - int i; \ - for (i = 0; i < HARD_REG_SET_LONGS; i++) \ - *scan_tp_++ |= *scan_fp_++; } while (0) - -#define IOR_COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - const HARD_REG_ELT_TYPE *scan_fp_ = (FROM); \ - int i; \ - for (i = 0; i < HARD_REG_SET_LONGS; i++) \ - *scan_tp_++ |= ~ *scan_fp_++; } while (0) - static inline bool -hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y) +hard_reg_set_subset_p (const_hard_reg_set x, const_hard_reg_set y) { - int i; - - for (i = 0; i < HARD_REG_SET_LONGS; i++) - if ((x[i] & ~y[i]) != 0) - return false; - return true; + HARD_REG_ELT_TYPE bad = 0; + for (unsigned int i = 0; i < ARRAY_SIZE (x.elts); ++i) + bad |= (x.elts[i] & ~y.elts[i]); + return bad == 0; } static inline bool -hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y) +hard_reg_set_equal_p (const_hard_reg_set x, const_hard_reg_set y) { - int i; - - for (i = 0; i < HARD_REG_SET_LONGS; i++) - if (x[i] != y[i]) - return false; - return true; + HARD_REG_ELT_TYPE bad = 0; + for (unsigned int i = 0; i < ARRAY_SIZE (x.elts); ++i) + bad |= (x.elts[i] ^ y.elts[i]); + return bad == 0; } static inline bool -hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y) +hard_reg_set_intersect_p (const_hard_reg_set x, const_hard_reg_set y) { - int i; - - for (i = 0; i < HARD_REG_SET_LONGS; i++) - if ((x[i] & y[i]) != 0) - return true; - return false; + HARD_REG_ELT_TYPE good = 0; + for (unsigned int i = 0; i < ARRAY_SIZE (x.elts); ++i) + good |= (x.elts[i] & y.elts[i]); + return good != 0; } static inline bool -hard_reg_set_empty_p (const HARD_REG_SET x) +hard_reg_set_empty_p (const_hard_reg_set x) { - int i; - - for (i = 0; i < HARD_REG_SET_LONGS; i++) - if (x[i] != 0) - return false; - return true; + HARD_REG_ELT_TYPE bad = 0; + for (unsigned int i = 0; i < ARRAY_SIZE (x.elts); ++i) + bad |= x.elts[i]; + return bad == 0; } - -#endif -#endif -#endif #endif /* Iterator for hard register sets. */ @@ -515,7 +268,7 @@ hard_reg_set_empty_p (const HARD_REG_SET x) struct hard_reg_set_iterator { /* Pointer to the current element. */ - HARD_REG_ELT_TYPE *pelt; + const HARD_REG_ELT_TYPE *pelt; /* The length of the set. */ unsigned short length; @@ -534,11 +287,11 @@ struct hard_reg_set_iterator /* The implementation of the iterator functions is fully analogous to the bitmap iterators. */ static inline void -hard_reg_set_iter_init (hard_reg_set_iterator *iter, HARD_REG_SET set, +hard_reg_set_iter_init (hard_reg_set_iterator *iter, const_hard_reg_set set, unsigned min, unsigned *regno) { #ifdef HARD_REG_SET_LONGS - iter->pelt = set; + iter->pelt = set.elts; iter->length = HARD_REG_SET_LONGS; #else iter->pelt = &set; diff --git a/gcc/ira-costs.c b/gcc/ira-costs.c index c7feaba..3d81c90 100644 --- a/gcc/ira-costs.c +++ b/gcc/ira-costs.c @@ -237,7 +237,7 @@ setup_cost_classes (cost_classes_t from) allocated. */ static cost_classes_t restrict_cost_classes (cost_classes_t full, machine_mode mode, - const HARD_REG_SET ®s) + const_hard_reg_set regs) { static struct cost_classes narrow; int map[N_REG_CLASSES]; diff --git a/gcc/recog.h b/gcc/recog.h index e09b27c..71d88e3 100644 --- a/gcc/recog.h +++ b/gcc/recog.h @@ -142,7 +142,7 @@ extern void preprocess_constraints (rtx_insn *); extern rtx_insn *peep2_next_insn (int); extern int peep2_regno_dead_p (int, int); extern int peep2_reg_dead_p (int, rtx); -#ifdef CLEAR_HARD_REG_SET +#ifdef HARD_CONST extern rtx peep2_find_free_register (int, int, const char *, machine_mode, HARD_REG_SET *); #endif diff --git a/gcc/regs.h b/gcc/regs.h index 48b2e70..4634abc 100644 --- a/gcc/regs.h +++ b/gcc/regs.h @@ -298,7 +298,7 @@ remove_from_hard_reg_set (HARD_REG_SET *regs, machine_mode mode, /* Return true if REGS contains the whole of (reg:MODE REGNO). */ static inline bool -in_hard_reg_set_p (const HARD_REG_SET regs, machine_mode mode, +in_hard_reg_set_p (const_hard_reg_set regs, machine_mode mode, unsigned int regno) { unsigned int end_regno; @@ -323,7 +323,7 @@ in_hard_reg_set_p (const HARD_REG_SET regs, machine_mode mode, /* Return true if (reg:MODE REGNO) includes an element of REGS. */ static inline bool -overlaps_hard_reg_set_p (const HARD_REG_SET regs, machine_mode mode, +overlaps_hard_reg_set_p (const_hard_reg_set regs, machine_mode mode, unsigned int regno) { unsigned int end_regno; @@ -363,7 +363,7 @@ remove_range_from_hard_reg_set (HARD_REG_SET *regs, unsigned int regno, /* Like overlaps_hard_reg_set_p, but use a REGNO/NREGS range instead of REGNO and MODE. */ static inline bool -range_overlaps_hard_reg_set_p (const HARD_REG_SET set, unsigned regno, +range_overlaps_hard_reg_set_p (const_hard_reg_set set, unsigned regno, int nregs) { while (nregs-- > 0) @@ -375,7 +375,7 @@ range_overlaps_hard_reg_set_p (const HARD_REG_SET set, unsigned regno, /* Like in_hard_reg_set_p, but use a REGNO/NREGS range instead of REGNO and MODE. */ static inline bool -range_in_hard_reg_set_p (const HARD_REG_SET set, unsigned regno, int nregs) +range_in_hard_reg_set_p (const_hard_reg_set set, unsigned regno, int nregs) { while (nregs-- > 0) if (!TEST_HARD_REG_BIT (set, regno + nregs)) diff --git a/gcc/reload.h b/gcc/reload.h index eb49771..86f0fff 100644 --- a/gcc/reload.h +++ b/gcc/reload.h @@ -274,7 +274,7 @@ extern int reload_first_uid; extern int num_not_at_initial_offset; -#if defined SET_HARD_REG_BIT && defined CLEAR_REG_SET +#if defined HARD_CONST && defined CLEAR_REG_SET /* This structure describes instructions which are relevant for reload. Apart from all regular insns, this also includes CODE_LABELs, since they must be examined for register elimination. */ @@ -326,7 +326,7 @@ extern class insn_chain *reload_insn_chain; extern class insn_chain *new_insn_chain (void); #endif -#if defined SET_HARD_REG_BIT +#if defined HARD_CONST extern void compute_use_by_pseudos (HARD_REG_SET *, bitmap); #endif diff --git a/gcc/rtl.h b/gcc/rtl.h index efb9b3c..b9e1fe7 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -3377,8 +3377,7 @@ extern bool val_signbit_known_clear_p (machine_mode, unsigned HOST_WIDE_INT); /* In reginfo.c */ -extern machine_mode choose_hard_reg_mode (unsigned int, unsigned int, - bool); +extern machine_mode choose_hard_reg_mode (unsigned int, unsigned int, bool); extern const HARD_REG_SET &simplifiable_subregs (const subreg_shape &); /* In emit-rtl.c */ diff --git a/gcc/shrink-wrap.c b/gcc/shrink-wrap.c index 57124db..257422c 100644 --- a/gcc/shrink-wrap.c +++ b/gcc/shrink-wrap.c @@ -151,8 +151,8 @@ live_edge_for_reg (basic_block bb, int regno, int end_regno) static bool move_insn_for_shrink_wrap (basic_block bb, rtx_insn *insn, - const HARD_REG_SET uses, - const HARD_REG_SET defs, + const_hard_reg_set uses, + const_hard_reg_set defs, bool *split_p, struct dead_debug_local *debug) { -- cgit v1.1 From e8448ba5300e32917fb12f877ae40711c2b452a3 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Mon, 9 Sep 2019 17:58:59 +0000 Subject: Make note_stores take an rtx_insn I have a series of patches that (as a side effect) makes all rtl passes use the information collected by -fipa-ra. This showed up a latent bug in the liveness tracking in regrename.c, which doesn't take CALL_INSN_FUNCTION_USAGE into account when processing clobbers. This actually seems to be quite a common problem with passes that use note_stores; only a handful remember to walk CALL_INSN_FUNCTION_USAGE too. I think it was just luck that I saw it with regrename first. This patch tries to make things more robust by passing an insn rather than a pattern to note_stores. The old function is still available as note_pattern_stores for the few places that need it. When updating callers, I've erred on the side of using note_stores rather than note_pattern_stores, because IMO note_stores should be the default choice and we should only use note_pattern_stores if there's a specific reason. Specifically: * For cselib.c, "body" may be a COND_EXEC_CODE instead of the main insn pattern. * For ira.c, I wasn't sure whether extending no_equiv to CALL_INSN_FUNCTION_USAGE really made sense, since we don't do that for normal call-clobbered registers. Same for mark_not_eliminable in reload1.c * Some other places only have a pattern available, and since those places wouldn't benefit from walking CALL_INSN_FUNCTION_USAGE, it seemed better to alter the code as little as possible. * In the config/ changes, quite a few callers have already weeded out CALL insns. It still seemed better to use note_stores rather than prematurely optimise. (note_stores should tail call to note_pattern_stores once it sees that the insn isn't a call.) The patch also documents what SETs mean in CALL_INSN_FUNCTION_USAGE. 2019-09-09 Richard Sandiford gcc/ * rtl.h (CALL_INSN_FUNCTION_USAGE): Document what SETs mean. (note_pattern_stores): Declare. (note_stores): Take an rtx_insn *. * rtlanal.c (set_of): Use note_pattern_stores instead of note_stores. (find_all_hard_reg_sets): Pass the insn rather than its pattern to note_stores. Remove explicit handling of CALL_INSN_FUNCTION_USAGE. (note_stores): Take an rtx_insn * as argument and process CALL_INSN_FUNCTION_USAGE. Rename old function to... (note_pattern_stores): ...this. (find_first_parameter_load): Pass the insn rather than its pattern to note_stores. * alias.c (memory_modified_in_insn_p, init_alias_analysis): Likewise. * caller-save.c (setup_save_areas, save_call_clobbered_regs) (insert_one_insn): Likewise. * combine.c (combine_instructions): Likewise. (likely_spilled_retval_p): Likewise. (try_combine): Use note_pattern_stores instead of note_stores. (record_dead_and_set_regs): Pass the insn rather than its pattern to note_stores. (reg_dead_at_p): Likewise. * config/bfin/bfin.c (workaround_speculation): Likewise. * config/c6x/c6x.c (maybe_clobber_cond): Likewise. Take an rtx_insn * rather than an rtx. * config/frv/frv.c (frv_registers_update): Use note_pattern_stores instead of note_stores. (frv_optimize_membar_local): Pass the insn rather than its pattern to note_stores. * config/gcn/gcn.c (gcn_md_reorg): Likewise. * config/i386/i386.c (ix86_avx_u128_mode_after): Likewise. * config/mips/mips.c (vr4130_true_reg_dependence_p): Likewise. (r10k_needs_protection_p, mips_sim_issue_insn): Likewise. (mips_reorg_process_insns): Likewise. * config/s390/s390.c (s390_regs_ever_clobbered): Likewise. * config/sh/sh.c (flow_dependent_p): Likewise. Take rtx_insn *s rather than rtxes. * cse.c (delete_trivially_dead_insns): Pass the insn rather than its pattern to note_stores. * cselib.c (cselib_record_sets): Use note_pattern_stores instead of note_stores. * dce.c (mark_nonreg_stores): Remove the "body" parameter and pass the insn to note_stores. (prescan_insns_for_dce): Update call accordingly. * ddg.c (mem_write_insn_p): Pass the insn rather than its pattern to note_stores. * df-problems.c (can_move_insns_across): Likewise. * dse.c (emit_inc_dec_insn_before, replace_read): Likewise. * function.c (assign_parm_setup_reg): Likewise. * gcse-common.c (record_last_mem_set_info_common): Likewise. * gcse.c (load_killed_in_block_p, compute_hash_table_work): Likewise. (single_set_gcse): Likewise. * ira.c (validate_equiv_mem): Likewise. (update_equiv_regs): Use note_pattern_stores rather than note_stores for no_equiv. * loop-doloop.c (doloop_optimize): Pass the insn rather than its pattern to note_stores. * loop-invariant.c (calculate_loop_reg_pressure): Likewise. * loop-iv.c (simplify_using_initial_values): Likewise. * mode-switching.c (optimize_mode_switching): Likewise. * optabs.c (emit_libcall_block_1): Likewise. (expand_atomic_compare_and_swap): Likewise. * postreload-gcse.c (load_killed_in_block_p): Likewise. (record_opr_changes): Likewise. Remove explicit handling of CALL_INSN_FUNCTION_USAGE. * postreload.c (reload_combine, reload_cse_move2add): Likewise. * regcprop.c (kill_clobbered_values): Likewise. (copyprop_hardreg_forward_1): Pass the insn rather than its pattern to note_stores. * regrename.c (build_def_use): Likewise. * reload1.c (reload): Use note_pattern_stores instead of note_stores for mark_not_eliminable. (reload_as_needed): Pass the insn rather than its pattern to note_stores. (emit_output_reload_insns): Likewise. * resource.c (mark_target_live_regs): Likewise. * sched-deps.c (init_insn_reg_pressure_info): Likewise. * sched-rgn.c (sets_likely_spilled): Use note_pattern_stores instead of note_stores. * shrink-wrap.c (try_shrink_wrapping): Pass the insn rather than its pattern to note_stores. * stack-ptr-mod.c (pass_stack_ptr_mod::execute): Likewise. * var-tracking.c (adjust_insn, add_with_sets): Likewise. From-SVN: r275527 --- gcc/ChangeLog | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++ gcc/alias.c | 5 +-- gcc/caller-save.c | 11 +++---- gcc/combine.c | 15 +++++---- gcc/config/bfin/bfin.c | 2 +- gcc/config/c6x/c6x.c | 4 +-- gcc/config/frv/frv.c | 7 ++--- gcc/config/gcn/gcn.c | 4 +-- gcc/config/i386/i386.c | 2 +- gcc/config/mips/mips.c | 12 +++----- gcc/config/s390/s390.c | 2 +- gcc/config/sh/sh.c | 6 ++-- gcc/cse.c | 2 +- gcc/cselib.c | 2 +- gcc/dce.c | 10 +++--- gcc/ddg.c | 2 +- gcc/df-problems.c | 5 ++- gcc/dse.c | 4 +-- gcc/function.c | 3 +- gcc/gcse-common.c | 2 +- gcc/gcse.c | 6 ++-- gcc/ira.c | 10 +++--- gcc/loop-doloop.c | 2 +- gcc/loop-invariant.c | 4 +-- gcc/loop-iv.c | 2 +- gcc/mode-switching.c | 2 +- gcc/optabs.c | 4 +-- gcc/postreload-gcse.c | 19 ++---------- gcc/postreload.c | 38 +++-------------------- gcc/regcprop.c | 16 ++-------- gcc/regrename.c | 4 +-- gcc/reload1.c | 8 ++--- gcc/resource.c | 2 +- gcc/rtl.h | 13 ++++++-- gcc/rtlanal.c | 36 ++++++++++++++-------- gcc/sched-deps.c | 4 +-- gcc/sched-rgn.c | 2 +- gcc/shrink-wrap.c | 2 +- gcc/stack-ptr-mod.c | 4 +-- gcc/var-tracking.c | 4 +-- 40 files changed, 202 insertions(+), 164 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 482a50f..338f404 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,89 @@ 2019-09-09 Richard Sandiford + * rtl.h (CALL_INSN_FUNCTION_USAGE): Document what SETs mean. + (note_pattern_stores): Declare. + (note_stores): Take an rtx_insn *. + * rtlanal.c (set_of): Use note_pattern_stores instead of note_stores. + (find_all_hard_reg_sets): Pass the insn rather than its pattern to + note_stores. Remove explicit handling of CALL_INSN_FUNCTION_USAGE. + (note_stores): Take an rtx_insn * as argument and process + CALL_INSN_FUNCTION_USAGE. Rename old function to... + (note_pattern_stores): ...this. + (find_first_parameter_load): Pass the insn rather than + its pattern to note_stores. + * alias.c (memory_modified_in_insn_p, init_alias_analysis): Likewise. + * caller-save.c (setup_save_areas, save_call_clobbered_regs) + (insert_one_insn): Likewise. + * combine.c (combine_instructions): Likewise. + (likely_spilled_retval_p): Likewise. + (try_combine): Use note_pattern_stores instead of note_stores. + (record_dead_and_set_regs): Pass the insn rather than its pattern + to note_stores. + (reg_dead_at_p): Likewise. + * config/bfin/bfin.c (workaround_speculation): Likewise. + * config/c6x/c6x.c (maybe_clobber_cond): Likewise. Take an rtx_insn * + rather than an rtx. + * config/frv/frv.c (frv_registers_update): Use note_pattern_stores + instead of note_stores. + (frv_optimize_membar_local): Pass the insn rather than its pattern + to note_stores. + * config/gcn/gcn.c (gcn_md_reorg): Likewise. + * config/i386/i386.c (ix86_avx_u128_mode_after): Likewise. + * config/mips/mips.c (vr4130_true_reg_dependence_p): Likewise. + (r10k_needs_protection_p, mips_sim_issue_insn): Likewise. + (mips_reorg_process_insns): Likewise. + * config/s390/s390.c (s390_regs_ever_clobbered): Likewise. + * config/sh/sh.c (flow_dependent_p): Likewise. Take rtx_insn *s + rather than rtxes. + * cse.c (delete_trivially_dead_insns): Pass the insn rather than + its pattern to note_stores. + * cselib.c (cselib_record_sets): Use note_pattern_stores instead + of note_stores. + * dce.c (mark_nonreg_stores): Remove the "body" parameter and pass + the insn to note_stores. + (prescan_insns_for_dce): Update call accordingly. + * ddg.c (mem_write_insn_p): Pass the insn rather than its pattern + to note_stores. + * df-problems.c (can_move_insns_across): Likewise. + * dse.c (emit_inc_dec_insn_before, replace_read): Likewise. + * function.c (assign_parm_setup_reg): Likewise. + * gcse-common.c (record_last_mem_set_info_common): Likewise. + * gcse.c (load_killed_in_block_p, compute_hash_table_work): Likewise. + (single_set_gcse): Likewise. + * ira.c (validate_equiv_mem): Likewise. + (update_equiv_regs): Use note_pattern_stores rather than note_stores + for no_equiv. + * loop-doloop.c (doloop_optimize): Pass the insn rather than its + pattern to note_stores. + * loop-invariant.c (calculate_loop_reg_pressure): Likewise. + * loop-iv.c (simplify_using_initial_values): Likewise. + * mode-switching.c (optimize_mode_switching): Likewise. + * optabs.c (emit_libcall_block_1): Likewise. + (expand_atomic_compare_and_swap): Likewise. + * postreload-gcse.c (load_killed_in_block_p): Likewise. + (record_opr_changes): Likewise. Remove explicit handling of + CALL_INSN_FUNCTION_USAGE. + * postreload.c (reload_combine, reload_cse_move2add): Likewise. + * regcprop.c (kill_clobbered_values): Likewise. + (copyprop_hardreg_forward_1): Pass the insn rather than its pattern + to note_stores. + * regrename.c (build_def_use): Likewise. + * reload1.c (reload): Use note_pattern_stores instead of note_stores + for mark_not_eliminable. + (reload_as_needed): Pass the insn rather than its pattern + to note_stores. + (emit_output_reload_insns): Likewise. + * resource.c (mark_target_live_regs): Likewise. + * sched-deps.c (init_insn_reg_pressure_info): Likewise. + * sched-rgn.c (sets_likely_spilled): Use note_pattern_stores + instead of note_stores. + * shrink-wrap.c (try_shrink_wrapping): Pass the insn rather than + its pattern to note_stores. + * stack-ptr-mod.c (pass_stack_ptr_mod::execute): Likewise. + * var-tracking.c (adjust_insn, add_with_sets): Likewise. + +2019-09-09 Richard Sandiford + * hard-reg-set.h (HARD_REG_SET): Define using a typedef rather than a #define. Use a structure rather than an array as the fallback definition. Remove special cases for low array sizes. diff --git a/gcc/alias.c b/gcc/alias.c index 1579dfa..0ed1cbe 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -3268,7 +3268,8 @@ memory_modified_in_insn_p (const_rtx mem, const_rtx insn) if (CALL_P (insn)) return true; memory_modified = false; - note_stores (PATTERN (insn), memory_modified_1, CONST_CAST_RTX(mem)); + note_stores (as_a (insn), memory_modified_1, + CONST_CAST_RTX(mem)); return memory_modified; } @@ -3396,7 +3397,7 @@ init_alias_analysis (void) && find_reg_note (insn, REG_NOALIAS, NULL_RTX)) record_set (SET_DEST (PATTERN (insn)), NULL_RTX, NULL); else - note_stores (PATTERN (insn), record_set, NULL); + note_stores (insn, record_set, NULL); set = single_set (insn); diff --git a/gcc/caller-save.c b/gcc/caller-save.c index 7c1de89..5edbcc9 100644 --- a/gcc/caller-save.c +++ b/gcc/caller-save.c @@ -450,7 +450,7 @@ setup_save_areas (void) live during the call, but the subreg that is set isn't. */ CLEAR_HARD_REG_SET (this_insn_sets); - note_stores (PATTERN (insn), mark_set_regs, &this_insn_sets); + note_stores (insn, mark_set_regs, &this_insn_sets); /* Sibcalls are considered to set the return value. */ if (SIBLING_CALL_P (insn) && crtl->return_rtx) mark_set_regs (crtl->return_rtx, NULL_RTX, &this_insn_sets); @@ -534,7 +534,7 @@ setup_save_areas (void) live during the call, but the subreg that is set isn't. */ CLEAR_HARD_REG_SET (this_insn_sets); - note_stores (PATTERN (insn), mark_set_regs, &this_insn_sets); + note_stores (insn, mark_set_regs, &this_insn_sets); /* Sibcalls are considered to set the return value, compare df-scan.c:df_get_call_refs. */ if (SIBLING_CALL_P (insn) && crtl->return_rtx) @@ -795,7 +795,7 @@ save_call_clobbered_regs (void) be live across the call, while the other is set afterwards. */ CLEAR_HARD_REG_SET (this_insn_sets); - note_stores (PATTERN (insn), mark_set_regs, &this_insn_sets); + note_stores (insn, mark_set_regs, &this_insn_sets); AND_COMPL_HARD_REG_SET (hard_regs_saved, this_insn_sets); } @@ -849,7 +849,7 @@ save_call_clobbered_regs (void) multi-hard-reg pseudo; then the pseudo is considered live during the call, but the subreg that is set isn't. */ CLEAR_HARD_REG_SET (this_insn_sets); - note_stores (PATTERN (insn), mark_set_regs, &this_insn_sets); + note_stores (insn, mark_set_regs, &this_insn_sets); /* Compute which hard regs must be saved before this call. */ AND_COMPL_HARD_REG_SET (hard_regs_to_save, call_fixed_reg_set); @@ -1414,8 +1414,7 @@ insert_one_insn (class insn_chain *chain, int before_p, int code, rtx pat) /* Registers that are set in CHAIN->INSN live in the new insn. (Unless there is a REG_UNUSED note for them, but we don't look for them here.) */ - note_stores (PATTERN (chain->insn), add_stored_regs, - &new_chain->live_throughout); + note_stores (chain->insn, add_stored_regs, &new_chain->live_throughout); CLEAR_REG_SET (&new_chain->dead_or_set); if (chain->insn == BB_END (BASIC_BLOCK_FOR_FN (cfun, chain->block))) BB_END (BASIC_BLOCK_FOR_FN (cfun, chain->block)) = new_chain->insn; diff --git a/gcc/combine.c b/gcc/combine.c index f7b1ebc..981e7b0 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -1224,8 +1224,7 @@ combine_instructions (rtx_insn *f, unsigned int nregs) subst_low_luid = DF_INSN_LUID (insn); subst_insn = insn; - note_stores (PATTERN (insn), set_nonzero_bits_and_sign_copies, - insn); + note_stores (insn, set_nonzero_bits_and_sign_copies, insn); record_dead_and_set_regs (insn); if (AUTO_INC_DEC) @@ -2439,7 +2438,7 @@ likely_spilled_retval_p (rtx_insn *insn) info.mask = mask; for (p = PREV_INSN (use); info.mask && p != insn; p = PREV_INSN (p)) if (INSN_P (p)) - note_stores (PATTERN (p), likely_spilled_retval_1, &info); + note_stores (p, likely_spilled_retval_1, &info); mask = info.mask; /* Check if any of the (probably) live return value registers is @@ -4741,8 +4740,8 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, been made to this insn. The order is important, because newi2pat can affect nonzero_bits of newpat. */ if (newi2pat) - note_stores (newi2pat, set_nonzero_bits_and_sign_copies, NULL); - note_stores (newpat, set_nonzero_bits_and_sign_copies, NULL); + note_pattern_stores (newi2pat, set_nonzero_bits_and_sign_copies, NULL); + note_pattern_stores (newpat, set_nonzero_bits_and_sign_copies, NULL); } if (undobuf.other_insn != NULL_RTX) @@ -13487,10 +13486,10 @@ record_dead_and_set_regs (rtx_insn *insn) the return value register is set at this LUID. We could still replace a register with the return value from the wrong subroutine call! */ - note_stores (PATTERN (insn), record_dead_and_set_regs_1, NULL_RTX); + note_stores (insn, record_dead_and_set_regs_1, NULL_RTX); } else - note_stores (PATTERN (insn), record_dead_and_set_regs_1, insn); + note_stores (insn, record_dead_and_set_regs_1, insn); } /* If a SUBREG has the promoted bit set, it is in fact a property of the @@ -13904,7 +13903,7 @@ reg_dead_at_p (rtx reg, rtx_insn *insn) if (find_regno_note (insn, REG_UNUSED, reg_dead_regno)) return 1; - note_stores (PATTERN (insn), reg_dead_at_p_1, NULL); + note_stores (insn, reg_dead_at_p_1, NULL); if (reg_dead_flag) return reg_dead_flag == 1 ? 1 : 0; diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c index 80ab777..49f18b6 100644 --- a/gcc/config/bfin/bfin.c +++ b/gcc/config/bfin/bfin.c @@ -4419,7 +4419,7 @@ workaround_speculation (void) we found earlier. */ if (recog_memoized (insn) != CODE_FOR_compare_eq) { - note_stores (PATTERN (insn), note_np_check_stores, NULL); + note_stores (insn, note_np_check_stores, NULL); if (np_check_regno != -1) { if (find_regno_note (insn, REG_INC, np_check_regno)) diff --git a/gcc/config/c6x/c6x.c b/gcc/config/c6x/c6x.c index 8477d35..05b111e 100644 --- a/gcc/config/c6x/c6x.c +++ b/gcc/config/c6x/c6x.c @@ -4308,7 +4308,7 @@ clobber_cond_1 (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data1) only those jumps which are still in flight. */ static void -maybe_clobber_cond (rtx insn, int clock_var) +maybe_clobber_cond (rtx_insn *insn, int clock_var) { int n, idx; idx = ss.jump_cycle_index; @@ -4333,7 +4333,7 @@ maybe_clobber_cond (rtx insn, int clock_var) continue; } - note_stores (PATTERN (insn), clobber_cond_1, ss.jump_cond + idx); + note_stores (insn, clobber_cond_1, ss.jump_cond + idx); for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) if (REG_NOTE_KIND (link) == REG_INC) clobber_cond_1 (XEXP (link, 0), NULL_RTX, ss.jump_cond + idx); diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c index c1b3c9e..6008e9a 100644 --- a/gcc/config/frv/frv.c +++ b/gcc/config/frv/frv.c @@ -7136,7 +7136,7 @@ frv_registers_update (rtx x) flags |= frv_cond_flags (XEXP (x, 0)); x = XEXP (x, 1); } - note_stores (x, frv_registers_update_1, &flags); + note_pattern_stores (x, frv_registers_update_1, &flags); } @@ -7770,8 +7770,7 @@ frv_optimize_membar_local (basic_block bb, struct frv_io *next_io, /* Invalidate NEXT_IO's address if it depends on something that is clobbered by INSN. */ if (next_io->var_address) - note_stores (PATTERN (insn), frv_io_check_address, - &next_io->var_address); + note_stores (insn, frv_io_check_address, &next_io->var_address); /* If the next membar is associated with a __builtin_read, see if INSN reads from that address. If it does, and if @@ -7814,7 +7813,7 @@ frv_optimize_membar_local (basic_block bb, struct frv_io *next_io, if (volatile_refs_p (PATTERN (insn))) CLEAR_HARD_REG_SET (used_regs); else - note_stores (PATTERN (insn), frv_io_handle_set, &used_regs); + note_stores (insn, frv_io_handle_set, &used_regs); note_uses (&PATTERN (insn), frv_io_handle_use, &used_regs); break; diff --git a/gcc/config/gcn/gcn.c b/gcc/config/gcn/gcn.c index 8645ecc..cdb1c6e 100644 --- a/gcc/config/gcn/gcn.c +++ b/gcc/config/gcn/gcn.c @@ -4345,7 +4345,7 @@ gcn_md_reorg (void) HARD_REG_SET defs, uses; CLEAR_HARD_REG_SET (defs); CLEAR_HARD_REG_SET (uses); - note_stores (PATTERN (insn), record_hard_reg_sets, &defs); + note_stores (insn, record_hard_reg_sets, &defs); note_uses (&PATTERN (insn), record_hard_reg_uses, &uses); bool exec_lo_def_p = TEST_HARD_REG_BIT (defs, EXEC_LO_REG); @@ -4533,7 +4533,7 @@ gcn_md_reorg (void) HARD_REG_SET ireads, iwrites; CLEAR_HARD_REG_SET (ireads); CLEAR_HARD_REG_SET (iwrites); - note_stores (PATTERN (insn), record_hard_reg_sets, &iwrites); + note_stores (insn, record_hard_reg_sets, &iwrites); note_uses (&PATTERN (insn), record_hard_reg_uses, &ireads); /* Scan recent previous instructions for dependencies not handled in diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 50571a0..f6de6e9 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -13635,7 +13635,7 @@ ix86_avx_u128_mode_after (int mode, rtx_insn *insn) if (CALL_P (insn)) { bool avx_upper_reg_found = false; - note_stores (pat, ix86_check_avx_upper_stores, &avx_upper_reg_found); + note_stores (insn, ix86_check_avx_upper_stores, &avx_upper_reg_found); return avx_upper_reg_found ? AVX_U128_DIRTY : AVX_U128_CLEAN; } diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index c24dc71..c5389d2 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -14889,8 +14889,7 @@ vr4130_true_reg_dependence_p_1 (rtx x, const_rtx pat ATTRIBUTE_UNUSED, static bool vr4130_true_reg_dependence_p (rtx insn) { - note_stores (PATTERN (vr4130_last_insn), - vr4130_true_reg_dependence_p_1, &insn); + note_stores (vr4130_last_insn, vr4130_true_reg_dependence_p_1, &insn); return insn == 0; } @@ -17787,7 +17786,7 @@ r10k_needs_protection_p (rtx_insn *insn) if (mips_r10k_cache_barrier == R10K_CACHE_BARRIER_STORE) { - note_stores (PATTERN (insn), r10k_needs_protection_p_store, &insn); + note_stores (insn, r10k_needs_protection_p_store, &insn); return insn == NULL_RTX; } @@ -18296,7 +18295,7 @@ mips_sim_issue_insn (struct mips_sim *state, rtx_insn *insn) state->insns_left); mips_sim_insn = insn; - note_stores (PATTERN (insn), mips_sim_record_set, state); + note_stores (insn, mips_sim_record_set, state); } /* Simulate issuing a NOP in state STATE. */ @@ -19026,7 +19025,7 @@ mips_reorg_process_insns (void) &uses); HARD_REG_SET delay_sets; CLEAR_HARD_REG_SET (delay_sets); - note_stores (PATTERN (SEQ_END (insn)), record_hard_reg_sets, + note_stores (SEQ_END (insn), record_hard_reg_sets, &delay_sets); rtx_insn *prev = prev_active_insn (insn); @@ -19036,8 +19035,7 @@ mips_reorg_process_insns (void) { HARD_REG_SET sets; CLEAR_HARD_REG_SET (sets); - note_stores (PATTERN (prev), record_hard_reg_sets, - &sets); + note_stores (prev, record_hard_reg_sets, &sets); /* Re-order if safe. */ if (!hard_reg_set_intersect_p (delay_sets, uses) diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 2478426..389fca8 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -9474,7 +9474,7 @@ s390_regs_ever_clobbered (char regs_ever_clobbered[]) continue; } - note_stores (pat, + note_stores (cur_insn, s390_reg_clobbered_rtx, regs_ever_clobbered); } diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 3b22d96..04c56aa 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -249,7 +249,7 @@ static void sh_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree); static void sh_file_start (void); static bool sh_assemble_integer (rtx, unsigned int, int); -static bool flow_dependent_p (rtx, rtx); +static bool flow_dependent_p (rtx_insn *, rtx_insn *); static void flow_dependent_p_1 (rtx, const_rtx, void *); static int shiftcosts (rtx); static int and_xor_ior_costs (rtx, int); @@ -9633,11 +9633,11 @@ sh_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep_insn, int cost, /* Check if INSN is flow-dependent on DEP_INSN. Can also be used to check if DEP_INSN is anti-flow dependent on INSN. */ static bool -flow_dependent_p (rtx insn, rtx dep_insn) +flow_dependent_p (rtx_insn *insn, rtx_insn *dep_insn) { rtx tmp = PATTERN (insn); - note_stores (PATTERN (dep_insn), flow_dependent_p_1, &tmp); + note_stores (dep_insn, flow_dependent_p_1, &tmp); return tmp == NULL_RTX; } diff --git a/gcc/cse.c b/gcc/cse.c index 35840a6d..098671c 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -7158,7 +7158,7 @@ delete_trivially_dead_insns (rtx_insn *insns, int nreg) else if (INSN_P (insn)) { count_reg_usage (insn, counts, NULL_RTX, 1); - note_stores (PATTERN (insn), count_stores, counts + nreg * 2); + note_stores (insn, count_stores, counts + nreg * 2); } /* If there can be debug insns, COUNTS are 3 consecutive arrays. First one counts how many times each pseudo is used outside diff --git a/gcc/cselib.c b/gcc/cselib.c index 7b0545e..87b3d33 100644 --- a/gcc/cselib.c +++ b/gcc/cselib.c @@ -2659,7 +2659,7 @@ cselib_record_sets (rtx_insn *insn) /* Invalidate all locations written by this insn. Note that the elts we looked up in the previous loop aren't affected, just some of their locations may go away. */ - note_stores (body, cselib_invalidate_rtx_note_stores, NULL); + note_pattern_stores (body, cselib_invalidate_rtx_note_stores, NULL); for (i = n_sets_before_autoinc; i < n_sets; i++) cselib_invalidate_rtx (sets[i].dest); diff --git a/gcc/dce.c b/gcc/dce.c index 68d3713b..af22eb3 100644 --- a/gcc/dce.c +++ b/gcc/dce.c @@ -265,15 +265,15 @@ mark_nonreg_stores_2 (rtx dest, const_rtx pattern, void *data) } -/* Mark INSN if BODY stores to a non-register destination. */ +/* Mark INSN if it stores to a non-register destination. */ static void -mark_nonreg_stores (rtx body, rtx_insn *insn, bool fast) +mark_nonreg_stores (rtx_insn *insn, bool fast) { if (fast) - note_stores (body, mark_nonreg_stores_1, insn); + note_stores (insn, mark_nonreg_stores_1, insn); else - note_stores (body, mark_nonreg_stores_2, insn); + note_stores (insn, mark_nonreg_stores_2, insn); } @@ -691,7 +691,7 @@ prescan_insns_for_dce (bool fast) if (arg_stores && bitmap_bit_p (arg_stores, INSN_UID (insn))) continue; if (deletable_insn_p (insn, fast, arg_stores)) - mark_nonreg_stores (PATTERN (insn), insn, fast); + mark_nonreg_stores (insn, fast); else mark_insn (insn, fast); } diff --git a/gcc/ddg.c b/gcc/ddg.c index 28b2be9..68cba60 100644 --- a/gcc/ddg.c +++ b/gcc/ddg.c @@ -84,7 +84,7 @@ static bool mem_write_insn_p (rtx_insn *insn) { mem_ref_p = false; - note_stores (PATTERN (insn), mark_mem_store, NULL); + note_stores (insn, mark_mem_store, NULL); return mem_ref_p; } diff --git a/gcc/df-problems.c b/gcc/df-problems.c index d32c688..e8a45ae 100644 --- a/gcc/df-problems.c +++ b/gcc/df-problems.c @@ -4094,8 +4094,7 @@ can_move_insns_across (rtx_insn *from, rtx_insn *to, if (volatile_insn_p (PATTERN (insn))) return false; memrefs_in_across |= find_memory (insn); - note_stores (PATTERN (insn), find_memory_stores, - &mem_sets_in_across); + note_stores (insn, find_memory_stores, &mem_sets_in_across); /* This is used just to find sets of the stack pointer. */ memrefs_in_across |= mem_sets_in_across; trapping_insns_in_across |= may_trap_p (PATTERN (insn)); @@ -4174,7 +4173,7 @@ can_move_insns_across (rtx_insn *from, rtx_insn *to, { int mem_ref_flags = 0; int mem_set_flags = 0; - note_stores (PATTERN (insn), find_memory_stores, &mem_set_flags); + note_stores (insn, find_memory_stores, &mem_set_flags); mem_ref_flags = find_memory (insn); /* Catch sets of the stack pointer. */ mem_ref_flags |= mem_set_flags; diff --git a/gcc/dse.c b/gcc/dse.c index 5e270f9..55b3cf1 100644 --- a/gcc/dse.c +++ b/gcc/dse.c @@ -822,7 +822,7 @@ emit_inc_dec_insn_before (rtx mem ATTRIBUTE_UNUSED, for (cur = new_insn; cur; cur = NEXT_INSN (cur)) { info.current = cur; - note_stores (PATTERN (cur), note_add_store, &info); + note_stores (cur, note_add_store, &info); } /* If a failure was flagged above, return 1 so that for_each_inc_dec will @@ -1979,7 +1979,7 @@ replace_read (store_info *store_info, insn_info_t store_insn, bitmap regs_set = BITMAP_ALLOC (®_obstack); for (this_insn = insns; this_insn != NULL_RTX; this_insn = NEXT_INSN (this_insn)) - note_stores (PATTERN (this_insn), look_for_hardregs, regs_set); + note_stores (this_insn, look_for_hardregs, regs_set); bitmap_and_into (regs_set, regs_live); if (!bitmap_empty_p (regs_set)) diff --git a/gcc/function.c b/gcc/function.c index 5351605..33e3f3e 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -3227,8 +3227,7 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm, for (insn = insns; insn && moved; insn = NEXT_INSN (insn)) { if (INSN_P (insn)) - note_stores (PATTERN (insn), record_hard_reg_sets, - &hardregs); + note_stores (insn, record_hard_reg_sets, &hardregs); if (!hard_reg_set_empty_p (hardregs)) moved = false; } diff --git a/gcc/gcse-common.c b/gcc/gcse-common.c index e6e4b64..5514862 100644 --- a/gcc/gcse-common.c +++ b/gcc/gcse-common.c @@ -89,7 +89,7 @@ record_last_mem_set_info_common (rtx_insn *insn, struct gcse_note_stores_info data; data.insn = insn; data.canon_mem_list = canon_modify_mem_list; - note_stores (PATTERN (insn), canon_list_insert, (void*) &data); + note_stores (insn, canon_list_insert, (void*) &data); } } diff --git a/gcc/gcse.c b/gcc/gcse.c index ff2771b..9bde861 100644 --- a/gcc/gcse.c +++ b/gcc/gcse.c @@ -1049,7 +1049,7 @@ load_killed_in_block_p (const_basic_block bb, int uid_limit, const_rtx x, note_stores to examine each hunk of memory that is modified. */ mci.mem = x; mci.conflict = false; - note_stores (PATTERN (setter), mems_conflict_for_gcse_p, &mci); + note_stores (setter, mems_conflict_for_gcse_p, &mci); if (mci.conflict) return 1; } @@ -1537,7 +1537,7 @@ compute_hash_table_work (struct gcse_hash_table_d *table) record_last_mem_set_info (insn); } - note_stores (PATTERN (insn), record_last_set_info, insn); + note_stores (insn, record_last_set_info, insn); } /* The next pass builds the hash table. */ @@ -2415,7 +2415,7 @@ single_set_gcse (rtx_insn *insn) s.insn = insn; s.nsets = 0; - note_stores (pattern, record_set_data, &s); + note_pattern_stores (pattern, record_set_data, &s); /* Considered invariant insns have exactly one set. */ gcc_assert (s.nsets == 1); diff --git a/gcc/ira.c b/gcc/ira.c index c58daba..66f1fc1 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -3004,7 +3004,7 @@ validate_equiv_mem (rtx_insn *start, rtx reg, rtx memref) return valid_none; } - note_stores (PATTERN (insn), validate_equiv_mem_from_store, &info); + note_stores (insn, validate_equiv_mem_from_store, &info); if (info.equiv_mem_modified) return valid_none; @@ -3447,7 +3447,7 @@ update_equiv_regs (void) if (set == NULL_RTX || side_effects_p (SET_SRC (set))) { - note_stores (PATTERN (insn), no_equiv, NULL); + note_pattern_stores (PATTERN (insn), no_equiv, NULL); continue; } else if (GET_CODE (PATTERN (insn)) == PARALLEL) @@ -3458,7 +3458,7 @@ update_equiv_regs (void) { rtx part = XVECEXP (PATTERN (insn), 0, i); if (part != set) - note_stores (part, no_equiv, NULL); + note_pattern_stores (part, no_equiv, NULL); } } @@ -3516,7 +3516,7 @@ update_equiv_regs (void) { /* This might be setting a SUBREG of a pseudo, a pseudo that is also set somewhere else to a constant. */ - note_stores (set, no_equiv, NULL); + note_pattern_stores (set, no_equiv, NULL); continue; } @@ -3524,7 +3524,7 @@ update_equiv_regs (void) equivalent to a mem. */ if (MEM_P (src) && reg_equiv[regno].pdx_subregs) { - note_stores (set, no_equiv, NULL); + note_pattern_stores (set, no_equiv, NULL); continue; } diff --git a/gcc/loop-doloop.c b/gcc/loop-doloop.c index 0efe7b4..ccd020a 100644 --- a/gcc/loop-doloop.c +++ b/gcc/loop-doloop.c @@ -731,7 +731,7 @@ doloop_optimize (class loop *loop) bitmap modified = BITMAP_ALLOC (NULL); for (rtx_insn *i = doloop_seq; i != NULL; i = NEXT_INSN (i)) - note_stores (PATTERN (i), record_reg_sets, modified); + note_stores (i, record_reg_sets, modified); basic_block loop_end = desc->out_edge->src; bool fail = bitmap_intersect_p (df_get_live_out (loop_end), modified); diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c index 644ecfc..d54cca4 100644 --- a/gcc/loop-invariant.c +++ b/gcc/loop-invariant.c @@ -2171,7 +2171,7 @@ calculate_loop_reg_pressure (void) mark_ref_regs (PATTERN (insn)); n_regs_set = 0; - note_stores (PATTERN (insn), mark_reg_clobber, NULL); + note_stores (insn, mark_reg_clobber, NULL); /* Mark any registers dead after INSN as dead now. */ @@ -2184,7 +2184,7 @@ calculate_loop_reg_pressure (void) Clobbers are processed again, so they conflict with the registers that are set. */ - note_stores (PATTERN (insn), mark_reg_store, NULL); + note_stores (insn, mark_reg_store, NULL); if (AUTO_INC_DEC) for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c index 2274cc3..82b329f 100644 --- a/gcc/loop-iv.c +++ b/gcc/loop-iv.c @@ -1970,7 +1970,7 @@ simplify_using_initial_values (class loop *loop, enum rtx_code op, rtx *expr) continue; CLEAR_REG_SET (this_altered); - note_stores (PATTERN (insn), mark_altered, this_altered); + note_stores (insn, mark_altered, this_altered); if (CALL_P (insn)) { /* Kill all call clobbered registers. */ diff --git a/gcc/mode-switching.c b/gcc/mode-switching.c index 2ff21a4..eba7509 100644 --- a/gcc/mode-switching.c +++ b/gcc/mode-switching.c @@ -637,7 +637,7 @@ optimize_mode_switching (void) if (REG_NOTE_KIND (link) == REG_DEAD) reg_dies (XEXP (link, 0), &live_now); - note_stores (PATTERN (insn), reg_becomes_live, &live_now); + note_stores (insn, reg_becomes_live, &live_now); for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) if (REG_NOTE_KIND (link) == REG_UNUSED) reg_dies (XEXP (link, 0), &live_now); diff --git a/gcc/optabs.c b/gcc/optabs.c index cdd07f3..35921e6 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -3738,7 +3738,7 @@ emit_libcall_block_1 (rtx_insn *insns, rtx target, rtx result, rtx equiv, data.first = insns; data.insn = insn; data.must_stay = 0; - note_stores (PATTERN (insn), no_conflict_move_test, &data); + note_stores (insn, no_conflict_move_test, &data); if (! data.must_stay) { if (PREV_INSN (insn)) @@ -6478,7 +6478,7 @@ expand_atomic_compare_and_swap (rtx *ptarget_bool, rtx *ptarget_oval, /* Otherwise, work out if the compare-and-swap succeeded. */ cc_reg = NULL_RTX; if (have_insn_for (COMPARE, CCmode)) - note_stores (PATTERN (get_last_insn ()), find_cc_set, &cc_reg); + note_stores (get_last_insn (), find_cc_set, &cc_reg); if (cc_reg) { target_bool = emit_store_flag_force (target_bool, EQ, cc_reg, diff --git a/gcc/postreload-gcse.c b/gcc/postreload-gcse.c index c62aee9..a709838 100644 --- a/gcc/postreload-gcse.c +++ b/gcc/postreload-gcse.c @@ -658,7 +658,7 @@ load_killed_in_block_p (int uid_limit, rtx x, bool after_insn) It will set mems_conflict_p to nonzero if there may be a conflict between X and SETTER. */ mems_conflict_p = 0; - note_stores (PATTERN (setter), find_mem_conflicts, x); + note_stores (setter, find_mem_conflicts, x); if (mems_conflict_p) return 1; @@ -760,7 +760,7 @@ record_opr_changes (rtx_insn *insn) rtx note; /* Find all stores and record them. */ - note_stores (PATTERN (insn), record_last_set_info, insn); + note_stores (insn, record_last_set_info, insn); /* Also record autoincremented REGs for this insn as changed. */ for (note = REG_NOTES (insn); note; note = XEXP (note, 1)) @@ -771,25 +771,10 @@ record_opr_changes (rtx_insn *insn) if (CALL_P (insn)) { unsigned int regno; - rtx link, x; hard_reg_set_iterator hrsi; EXECUTE_IF_SET_IN_HARD_REG_SET (regs_invalidated_by_call, 0, regno, hrsi) record_last_reg_set_info_regno (insn, regno); - for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1)) - { - gcc_assert (GET_CODE (XEXP (link, 0)) != CLOBBER_HIGH); - if (GET_CODE (XEXP (link, 0)) == CLOBBER) - { - x = XEXP (XEXP (link, 0), 0); - if (REG_P (x)) - { - gcc_assert (HARD_REGISTER_P (x)); - record_last_reg_set_info (insn, x); - } - } - } - if (! RTL_CONST_OR_PURE_CALL_P (insn)) record_last_mem_set_info (insn); } diff --git a/gcc/postreload.c b/gcc/postreload.c index 728aa9b..497a4b0 100644 --- a/gcc/postreload.c +++ b/gcc/postreload.c @@ -1325,7 +1325,7 @@ reload_combine (void) || reload_combine_recognize_pattern (insn)) continue; - note_stores (PATTERN (insn), reload_combine_note_store, NULL); + note_stores (insn, reload_combine_note_store, NULL); if (CALL_P (insn)) { @@ -1346,22 +1346,12 @@ reload_combine (void) { rtx setuse = XEXP (link, 0); rtx usage_rtx = XEXP (setuse, 0); - /* We could support CLOBBER_HIGH and treat it in the same way as - HARD_REGNO_CALL_PART_CLOBBERED, but no port needs that yet. */ - gcc_assert (GET_CODE (setuse) != CLOBBER_HIGH); - if ((GET_CODE (setuse) == USE || GET_CODE (setuse) == CLOBBER) - && REG_P (usage_rtx)) + if (GET_CODE (setuse) == USE && REG_P (usage_rtx)) { unsigned int end_regno = END_REGNO (usage_rtx); for (unsigned int i = REGNO (usage_rtx); i < end_regno; ++i) - if (GET_CODE (XEXP (link, 0)) == CLOBBER) - { - reg_state[i].use_index = RELOAD_COMBINE_MAX_USES; - reg_state[i].store_ruid = reload_combine_ruid; - } - else - reg_state[i].use_index = -1; + reg_state[i].use_index = -1; } } } @@ -2104,7 +2094,7 @@ reload_cse_move2add (rtx_insn *first) } } } - note_stores (PATTERN (insn), move2add_note_store, insn); + note_stores (insn, move2add_note_store, insn); /* If INSN is a conditional branch, we try to extract an implicit set out of it. */ @@ -2134,32 +2124,12 @@ reload_cse_move2add (rtx_insn *first) unknown values. */ if (CALL_P (insn)) { - rtx link; - for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--) { if (call_used_regs[i]) /* Reset the information about this register. */ reg_mode[i] = VOIDmode; } - - for (link = CALL_INSN_FUNCTION_USAGE (insn); link; - link = XEXP (link, 1)) - { - rtx setuse = XEXP (link, 0); - rtx usage_rtx = XEXP (setuse, 0); - /* CALL_INSN_FUNCTION_USAGEs can only have full clobbers, not - clobber_highs. */ - gcc_assert (GET_CODE (setuse) != CLOBBER_HIGH); - if (GET_CODE (setuse) == CLOBBER - && REG_P (usage_rtx)) - { - unsigned int end_regno = END_REGNO (usage_rtx); - for (unsigned int r = REGNO (usage_rtx); r < end_regno; ++r) - /* Reset the information about this register. */ - reg_mode[r] = VOIDmode; - } - } } } return changed; diff --git a/gcc/regcprop.c b/gcc/regcprop.c index a18c24f..4dc82a7 100644 --- a/gcc/regcprop.c +++ b/gcc/regcprop.c @@ -728,19 +728,7 @@ cprop_find_used_regs (rtx *loc, void *data) static void kill_clobbered_values (rtx_insn *insn, struct value_data *vd) { - note_stores (PATTERN (insn), kill_clobbered_value, vd); - - if (CALL_P (insn)) - { - rtx exp; - - for (exp = CALL_INSN_FUNCTION_USAGE (insn); exp; exp = XEXP (exp, 1)) - { - rtx x = XEXP (exp, 0); - if (GET_CODE (x) == CLOBBER) - kill_value (SET_DEST (x), vd); - } - } + note_stores (insn, kill_clobbered_value, vd); } /* Perform the forward copy propagation on basic block BB. */ @@ -1109,7 +1097,7 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd) if (!noop_p) { /* Notice stores. */ - note_stores (PATTERN (insn), kill_set_value, &ksvd); + note_stores (insn, kill_set_value, &ksvd); /* Notice copies. */ if (copy_p) diff --git a/gcc/regrename.c b/gcc/regrename.c index 73c0ced..580f29d 100644 --- a/gcc/regrename.c +++ b/gcc/regrename.c @@ -1741,7 +1741,7 @@ build_def_use (basic_block bb) outside an operand, as live. */ hide_operands (n_ops, old_operands, old_dups, untracked_operands, false); - note_stores (PATTERN (insn), note_sets_clobbers, &clobber_code); + note_stores (insn, note_sets_clobbers, &clobber_code); restore_operands (insn, n_ops, old_operands, old_dups); /* Step 1b: Begin new chains for earlyclobbered writes inside @@ -1857,7 +1857,7 @@ build_def_use (basic_block bb) outside an operand, as live. */ hide_operands (n_ops, old_operands, old_dups, untracked_operands, false); - note_stores (PATTERN (insn), note_sets_clobbers, &set_code); + note_stores (insn, note_sets_clobbers, &set_code); restore_operands (insn, n_ops, old_operands, old_dups); /* Step 6b: Begin new chains for writes inside operands. */ diff --git a/gcc/reload1.c b/gcc/reload1.c index 70a308e..e606982 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -843,7 +843,7 @@ reload (rtx_insn *first, int global) cannot be done. */ for (insn = first; insn && num_eliminable; insn = NEXT_INSN (insn)) if (INSN_P (insn)) - note_stores (PATTERN (insn), mark_not_eliminable, NULL); + note_pattern_stores (PATTERN (insn), mark_not_eliminable, NULL); maybe_fix_stack_asms (); @@ -4494,7 +4494,7 @@ reload_as_needed (int live_known) { regset_head regs_to_forget; INIT_REG_SET (®s_to_forget); - note_stores (PATTERN (insn), forget_old_reloads_1, ®s_to_forget); + note_stores (insn, forget_old_reloads_1, ®s_to_forget); /* If this is a USE and CLOBBER of a MEM, ensure that any references to eliminable registers have been removed. */ @@ -4621,7 +4621,7 @@ reload_as_needed (int live_known) between INSN and NEXT and use them to forget old reloads. */ for (rtx_insn *x = NEXT_INSN (insn); x != old_next; x = NEXT_INSN (x)) if (NONJUMP_INSN_P (x) && GET_CODE (PATTERN (x)) == CLOBBER) - note_stores (PATTERN (x), forget_old_reloads_1, NULL); + note_stores (x, forget_old_reloads_1, NULL); #if AUTO_INC_DEC /* Likewise for regs altered by auto-increment in this insn. @@ -7702,7 +7702,7 @@ emit_output_reload_insns (class insn_chain *chain, struct reload *rl, clear any memory of reloaded copies of the pseudo reg. If this output reload comes from a spill reg, reg_has_output_reload will make this do nothing. */ - note_stores (pat, forget_old_reloads_1, NULL); + note_stores (p, forget_old_reloads_1, NULL); if (reg_mentioned_p (rl_reg_rtx, pat)) { diff --git a/gcc/resource.c b/gcc/resource.c index c4bcfd7..d4d86ce 100644 --- a/gcc/resource.c +++ b/gcc/resource.c @@ -1078,7 +1078,7 @@ mark_target_live_regs (rtx_insn *insns, rtx target_maybe_return, struct resource GET_MODE (XEXP (link, 0)), REGNO (XEXP (link, 0))); - note_stores (PATTERN (real_insn), update_live_status, NULL); + note_stores (real_insn, update_live_status, NULL); /* If any registers were unused after this insn, kill them. These notes will always be accurate. */ diff --git a/gcc/rtl.h b/gcc/rtl.h index b9e1fe7..911b563 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -1630,11 +1630,17 @@ extern const char * const reg_note_name[]; #define GET_REG_NOTE_NAME(MODE) (reg_note_name[(int) (MODE)]) /* This field is only present on CALL_INSNs. It holds a chain of EXPR_LIST of - USE and CLOBBER expressions. + USE, CLOBBER and SET expressions. USE expressions list the registers filled with arguments that are passed to the function. CLOBBER expressions document the registers explicitly clobbered by this CALL_INSN. + SET expressions say that the return value of the call (the SET_DEST) + is equivalent to a value available before the call (the SET_SRC). + This kind of SET is used when the return value is predictable in + advance. It is purely an optimisation hint; unlike USEs and CLOBBERs, + it does not affect register liveness. + Pseudo registers cannot be mentioned in this list. */ #define CALL_INSN_FUNCTION_USAGE(INSN) XEXP(INSN, 7) @@ -3442,7 +3448,10 @@ extern void record_hard_reg_sets (rtx, const_rtx, void *); extern void record_hard_reg_uses (rtx *, void *); extern void find_all_hard_regs (const_rtx, HARD_REG_SET *); extern void find_all_hard_reg_sets (const rtx_insn *, HARD_REG_SET *, bool); -extern void note_stores (const_rtx, void (*) (rtx, const_rtx, void *), void *); +extern void note_pattern_stores (const_rtx, + void (*) (rtx, const_rtx, void *), void *); +extern void note_stores (const rtx_insn *, + void (*) (rtx, const_rtx, void *), void *); extern void note_uses (rtx *, void (*) (rtx *, void *), void *); extern int dead_or_set_p (const rtx_insn *, const_rtx); extern int dead_or_set_regno_p (const rtx_insn *, unsigned int); diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 3c5a64e..15185b7 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -1440,7 +1440,7 @@ set_of (const_rtx pat, const_rtx insn) struct set_of_data data; data.found = NULL_RTX; data.pat = pat; - note_stores (INSN_P (insn) ? PATTERN (insn) : insn, set_of_1, &data); + note_pattern_stores (INSN_P (insn) ? PATTERN (insn) : insn, set_of_1, &data); return data.found; } @@ -1476,15 +1476,9 @@ find_all_hard_reg_sets (const rtx_insn *insn, HARD_REG_SET *pset, bool implicit) rtx link; CLEAR_HARD_REG_SET (*pset); - note_stores (PATTERN (insn), record_hard_reg_sets, pset); - if (CALL_P (insn)) - { - if (implicit) - IOR_HARD_REG_SET (*pset, call_used_reg_set); - - for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1)) - record_hard_reg_sets (XEXP (link, 0), NULL, pset); - } + note_stores (insn, record_hard_reg_sets, pset); + if (CALL_P (insn) && implicit) + IOR_HARD_REG_SET (*pset, call_used_reg_set); for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) if (REG_NOTE_KIND (link) == REG_INC) record_hard_reg_sets (XEXP (link, 0), NULL, pset); @@ -1899,7 +1893,8 @@ reg_overlap_mentioned_p (const_rtx x, const_rtx in) the SUBREG will be passed. */ void -note_stores (const_rtx x, void (*fun) (rtx, const_rtx, void *), void *data) +note_pattern_stores (const_rtx x, + void (*fun) (rtx, const_rtx, void *), void *data) { int i; @@ -1933,7 +1928,22 @@ note_stores (const_rtx x, void (*fun) (rtx, const_rtx, void *), void *data) else if (GET_CODE (x) == PARALLEL) for (i = XVECLEN (x, 0) - 1; i >= 0; i--) - note_stores (XVECEXP (x, 0, i), fun, data); + note_pattern_stores (XVECEXP (x, 0, i), fun, data); +} + +/* Same, but for an instruction. If the instruction is a call, include + any CLOBBERs in its CALL_INSN_FUNCTION_USAGE. */ + +void +note_stores (const rtx_insn *insn, + void (*fun) (rtx, const_rtx, void *), void *data) +{ + if (CALL_P (insn)) + for (rtx link = CALL_INSN_FUNCTION_USAGE (insn); + link; link = XEXP (link, 1)) + if (GET_CODE (XEXP (link, 0)) == CLOBBER) + note_pattern_stores (XEXP (link, 0), fun, data); + note_pattern_stores (PATTERN (insn), fun, data); } /* Like notes_stores, but call FUN for each expression that is being @@ -4140,7 +4150,7 @@ find_first_parameter_load (rtx_insn *call_insn, rtx_insn *boundary) if (INSN_P (before)) { int nregs_old = parm.nregs; - note_stores (PATTERN (before), parms_set, &parm); + note_stores (before, parms_set, &parm); /* If we found something that did not set a parameter reg, we're done. Do not keep going, as that might result in hoisting an insn before the setting of a pseudo diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c index 5cb4a46..dcc84d7 100644 --- a/gcc/sched-deps.c +++ b/gcc/sched-deps.c @@ -2203,9 +2203,9 @@ init_insn_reg_pressure_info (rtx_insn *insn) reg_pressure_info[cl].change = 0; } - note_stores (PATTERN (insn), mark_insn_reg_clobber, insn); + note_stores (insn, mark_insn_reg_clobber, insn); - note_stores (PATTERN (insn), mark_insn_reg_store, insn); + note_stores (insn, mark_insn_reg_store, insn); if (AUTO_INC_DEC) for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) diff --git a/gcc/sched-rgn.c b/gcc/sched-rgn.c index 59ee6a0..3e08250 100644 --- a/gcc/sched-rgn.c +++ b/gcc/sched-rgn.c @@ -2416,7 +2416,7 @@ static bool sets_likely_spilled (rtx pat) { bool ret = false; - note_stores (pat, sets_likely_spilled_1, &ret); + note_pattern_stores (pat, sets_likely_spilled_1, &ret); return ret; } diff --git a/gcc/shrink-wrap.c b/gcc/shrink-wrap.c index 257422c..9ee712e 100644 --- a/gcc/shrink-wrap.c +++ b/gcc/shrink-wrap.c @@ -689,7 +689,7 @@ try_shrink_wrapping (edge *entry_edge, rtx_insn *prologue_seq) note_uses (&PATTERN (insn), record_hard_reg_uses, &this_used); AND_COMPL_HARD_REG_SET (this_used, prologue_clobbered); IOR_HARD_REG_SET (prologue_used, this_used); - note_stores (PATTERN (insn), record_hard_reg_sets, &prologue_clobbered); + note_stores (insn, record_hard_reg_sets, &prologue_clobbered); } CLEAR_HARD_REG_BIT (prologue_clobbered, STACK_POINTER_REGNUM); if (frame_pointer_needed) diff --git a/gcc/stack-ptr-mod.c b/gcc/stack-ptr-mod.c index a10d59b..5cb95e7 100644 --- a/gcc/stack-ptr-mod.c +++ b/gcc/stack-ptr-mod.c @@ -91,9 +91,7 @@ pass_stack_ptr_mod::execute (function *fun) if (INSN_P (insn)) { /* Check if insn modifies the stack pointer. */ - note_stores (PATTERN (insn), - notice_stack_pointer_modification_1, - NULL); + note_stores (insn, notice_stack_pointer_modification_1, NULL); if (! crtl->sp_is_unchanging) return 0; } diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c index af18528..6c26b61 100644 --- a/gcc/var-tracking.c +++ b/gcc/var-tracking.c @@ -1239,7 +1239,7 @@ adjust_insn (basic_block bb, rtx_insn *insn) amd.stack_adjust = -VTI (bb)->out.stack_adjust; amd.store = true; - note_stores (PATTERN (insn), adjust_mem_stores, &amd); + note_stores (insn, adjust_mem_stores, &amd); amd.store = false; if (GET_CODE (PATTERN (insn)) == PARALLEL @@ -6632,7 +6632,7 @@ add_with_sets (rtx_insn *insn, struct cselib_set *sets, int n_sets) insert notes before it without worrying about any notes that MO_USEs might emit after the insn. */ cui.store_p = true; - note_stores (PATTERN (insn), add_stores, &cui); + note_stores (insn, add_stores, &cui); n2 = VTI (bb)->mos.length () - 1; mos = VTI (bb)->mos.address (); -- cgit v1.1 From 6576d245386e2ce52df274ef8f2ffed81cfaa1c3 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Mon, 9 Sep 2019 17:59:06 +0000 Subject: Remove COPY_HARD_REG_SET This patch replaces "COPY_HARD_REG_SET (x, y)" with "x = y". 2019-09-09 Richard Sandiford gcc/ * hard-reg-set.h (COPY_HARD_REG_SET): Delete. * caller-save.c (save_call_clobbered_regs): Use assignment instead of COPY_HARD_REG_SET. * config/epiphany/epiphany.c (epiphany_compute_frame_size): Likewise. (epiphany_conditional_register_usage): Likewise. * config/frv/frv.c (frv_ifcvt_modify_tests): Likewise. * config/gcn/gcn.c (gcn_md_reorg): Likewise. * config/ia64/ia64.c (ia64_compute_frame_size): Likewise. * config/m32c/m32c.c (m32c_register_move_cost): Likewise. * config/m68k/m68k.c (m68k_conditional_register_usage): Likewise. * config/mips/mips.c (mips_class_max_nregs): Likewise. * config/pdp11/pdp11.c (pdp11_conditional_register_usage): Likewise. * config/rs6000/rs6000.c (rs6000_register_move_cost): Likewise. * config/sh/sh.c (output_stack_adjust): Likewise. * final.c (collect_fn_hard_reg_usage): Likewise. (get_call_reg_set_usage): Likewise. * ira-build.c (ira_create_object, remove_low_level_allocnos) (ira_flattening): Likewise. * ira-color.c (add_allocno_hard_regs, add_allocno_hard_regs_to_forest) (setup_left_conflict_sizes_p, setup_profitable_hard_regs) (get_conflict_and_start_profitable_regs, allocno_reload_assign) (ira_reassign_pseudos): Likewise. * ira-conflicts.c (print_allocno_conflicts): Likewise. (ira_build_conflicts): Likewise. * ira-costs.c (restrict_cost_classes): Likewise. (setup_regno_cost_classes_by_aclass): Likewise. * ira.c (setup_class_hard_regs, setup_alloc_regs): Likewise. (setup_reg_subclasses, setup_class_subset_and_memory_move_costs) (setup_stack_reg_pressure_class, setup_pressure_classes) (setup_allocno_and_important_classes, setup_class_translate_array) (setup_reg_class_relations, setup_prohibited_class_mode_regs) (ira_setup_eliminable_regset): Likewise. * lra-assigns.c (find_hard_regno_for_1): Likewise. (setup_live_pseudos_and_spill_after_risky_transforms): Likewise. * lra-constraints.c (prohibited_class_reg_set_mode_p): Likewise. (process_alt_operands, inherit_in_ebb): Likewise. * lra-lives.c (process_bb_lives): Likewise. * lra-spills.c (assign_spill_hard_regs): Likewise. * lra.c (lra): Likewise. * mode-switching.c (new_seginfo): Likewise. * postreload.c (reload_combine): Likewise. * reg-stack.c (straighten_stack): Likewise. * reginfo.c (save_register_info, restore_register_info): Likewise. (init_reg_sets_1, record_subregs_of_mode): Likewise * regrename.c (create_new_chain, rename_chains): Likewise. * reload1.c (order_regs_for_reload, find_reg): Likewise. (find_reload_regs): Likewise. * resource.c (find_dead_or_set_registers): Likewise. (mark_target_live_regs): Likewise. * sel-sched.c (mark_unavailable_hard_regs): Likewise. From-SVN: r275528 --- gcc/ChangeLog | 53 ++++++++++++++++++++++++++++++++ gcc/caller-save.c | 2 +- gcc/config/epiphany/epiphany.c | 5 ++- gcc/config/frv/frv.c | 2 +- gcc/config/gcn/gcn.c | 10 +++--- gcc/config/ia64/ia64.c | 2 +- gcc/config/m32c/m32c.c | 2 +- gcc/config/m68k/m68k.c | 2 +- gcc/config/mips/mips.c | 2 +- gcc/config/pdp11/pdp11.c | 2 +- gcc/config/rs6000/rs6000.c | 4 +-- gcc/config/sh/sh.c | 4 +-- gcc/final.c | 6 ++-- gcc/hard-reg-set.h | 15 +++------ gcc/ira-build.c | 12 ++++---- gcc/ira-color.c | 33 +++++++++----------- gcc/ira-conflicts.c | 6 ++-- gcc/ira-costs.c | 6 ++-- gcc/ira.c | 70 +++++++++++++++++++----------------------- gcc/lra-assigns.c | 6 ++-- gcc/lra-constraints.c | 11 +++---- gcc/lra-lives.c | 4 +-- gcc/lra-spills.c | 5 ++- gcc/lra.c | 2 +- gcc/mode-switching.c | 2 +- gcc/postreload.c | 2 +- gcc/reg-stack.c | 2 +- gcc/reginfo.c | 19 ++++++------ gcc/regrename.c | 4 +-- gcc/reload1.c | 6 ++-- gcc/resource.c | 16 +++++----- gcc/sel-sched.c | 3 +- 32 files changed, 175 insertions(+), 145 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 338f404..a323888 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,58 @@ 2019-09-09 Richard Sandiford + * hard-reg-set.h (COPY_HARD_REG_SET): Delete. + * caller-save.c (save_call_clobbered_regs): Use assignment instead + of COPY_HARD_REG_SET. + * config/epiphany/epiphany.c (epiphany_compute_frame_size): Likewise. + (epiphany_conditional_register_usage): Likewise. + * config/frv/frv.c (frv_ifcvt_modify_tests): Likewise. + * config/gcn/gcn.c (gcn_md_reorg): Likewise. + * config/ia64/ia64.c (ia64_compute_frame_size): Likewise. + * config/m32c/m32c.c (m32c_register_move_cost): Likewise. + * config/m68k/m68k.c (m68k_conditional_register_usage): Likewise. + * config/mips/mips.c (mips_class_max_nregs): Likewise. + * config/pdp11/pdp11.c (pdp11_conditional_register_usage): Likewise. + * config/rs6000/rs6000.c (rs6000_register_move_cost): Likewise. + * config/sh/sh.c (output_stack_adjust): Likewise. + * final.c (collect_fn_hard_reg_usage): Likewise. + (get_call_reg_set_usage): Likewise. + * ira-build.c (ira_create_object, remove_low_level_allocnos) + (ira_flattening): Likewise. + * ira-color.c (add_allocno_hard_regs, add_allocno_hard_regs_to_forest) + (setup_left_conflict_sizes_p, setup_profitable_hard_regs) + (get_conflict_and_start_profitable_regs, allocno_reload_assign) + (ira_reassign_pseudos): Likewise. + * ira-conflicts.c (print_allocno_conflicts): Likewise. + (ira_build_conflicts): Likewise. + * ira-costs.c (restrict_cost_classes): Likewise. + (setup_regno_cost_classes_by_aclass): Likewise. + * ira.c (setup_class_hard_regs, setup_alloc_regs): Likewise. + (setup_reg_subclasses, setup_class_subset_and_memory_move_costs) + (setup_stack_reg_pressure_class, setup_pressure_classes) + (setup_allocno_and_important_classes, setup_class_translate_array) + (setup_reg_class_relations, setup_prohibited_class_mode_regs) + (ira_setup_eliminable_regset): Likewise. + * lra-assigns.c (find_hard_regno_for_1): Likewise. + (setup_live_pseudos_and_spill_after_risky_transforms): Likewise. + * lra-constraints.c (prohibited_class_reg_set_mode_p): Likewise. + (process_alt_operands, inherit_in_ebb): Likewise. + * lra-lives.c (process_bb_lives): Likewise. + * lra-spills.c (assign_spill_hard_regs): Likewise. + * lra.c (lra): Likewise. + * mode-switching.c (new_seginfo): Likewise. + * postreload.c (reload_combine): Likewise. + * reg-stack.c (straighten_stack): Likewise. + * reginfo.c (save_register_info, restore_register_info): Likewise. + (init_reg_sets_1, record_subregs_of_mode): Likewise + * regrename.c (create_new_chain, rename_chains): Likewise. + * reload1.c (order_regs_for_reload, find_reg): Likewise. + (find_reload_regs): Likewise. + * resource.c (find_dead_or_set_registers): Likewise. + (mark_target_live_regs): Likewise. + * sel-sched.c (mark_unavailable_hard_regs): Likewise. + +2019-09-09 Richard Sandiford + * rtl.h (CALL_INSN_FUNCTION_USAGE): Document what SETs mean. (note_pattern_stores): Declare. (note_stores): Take an rtx_insn *. diff --git a/gcc/caller-save.c b/gcc/caller-save.c index 5edbcc9..03a9b33 100644 --- a/gcc/caller-save.c +++ b/gcc/caller-save.c @@ -775,7 +775,7 @@ save_call_clobbered_regs (void) if (code == JUMP_INSN) /* Restore all registers if this is a JUMP_INSN. */ - COPY_HARD_REG_SET (referenced_regs, hard_regs_saved); + referenced_regs = hard_regs_saved; else { CLEAR_HARD_REG_SET (referenced_regs); diff --git a/gcc/config/epiphany/epiphany.c b/gcc/config/epiphany/epiphany.c index cc51cfa..c2e3215 100644 --- a/gcc/config/epiphany/epiphany.c +++ b/gcc/config/epiphany/epiphany.c @@ -1248,7 +1248,7 @@ epiphany_compute_frame_size (int size /* # of var. bytes allocated. */) current_frame_info.var_size = var_size; current_frame_info.args_size = args_size; current_frame_info.reg_size = reg_size; - COPY_HARD_REG_SET (current_frame_info.gmask, gmask); + current_frame_info.gmask = gmask; current_frame_info.first_slot = first_slot; current_frame_info.last_slot = last_slot; current_frame_info.first_slot_offset = first_slot_offset; @@ -2240,8 +2240,7 @@ epiphany_conditional_register_usage (void) } if (!TARGET_PREFER_SHORT_INSN_REGS) CLEAR_HARD_REG_SET (reg_class_contents[SHORT_INSN_REGS]); - COPY_HARD_REG_SET (reg_class_contents[SIBCALL_REGS], - reg_class_contents[GENERAL_REGS]); + reg_class_contents[SIBCALL_REGS] = reg_class_contents[GENERAL_REGS]; /* It would be simpler and quicker if we could just use AND_COMPL_HARD_REG_SET, alas, call_used_reg_set is yet uninitialized; it is set up later by our caller. */ diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c index 6008e9a..7fc8068 100644 --- a/gcc/config/frv/frv.c +++ b/gcc/config/frv/frv.c @@ -5201,7 +5201,7 @@ frv_ifcvt_modify_tests (ce_if_block *ce_info, rtx *p_true, rtx *p_false) not fixed. However, allow the ICC/ICR temporary registers to be allocated if we did not need to use them in reloading other registers. */ memset (&tmp_reg->regs, 0, sizeof (tmp_reg->regs)); - COPY_HARD_REG_SET (tmp_reg->regs, call_used_reg_set); + tmp_reg->regs = call_used_reg_set; AND_COMPL_HARD_REG_SET (tmp_reg->regs, fixed_reg_set); SET_HARD_REG_BIT (tmp_reg->regs, ICC_TEMP); SET_HARD_REG_BIT (tmp_reg->regs, ICR_TEMP); diff --git a/gcc/config/gcn/gcn.c b/gcc/config/gcn/gcn.c index cdb1c6e..548ab17 100644 --- a/gcc/config/gcn/gcn.c +++ b/gcc/config/gcn/gcn.c @@ -4553,7 +4553,7 @@ gcn_md_reorg (void) && gcn_vmem_insn_p (itype)) { HARD_REG_SET regs; - COPY_HARD_REG_SET (regs, prev_insn->writes); + regs = prev_insn->writes; AND_HARD_REG_SET (regs, ireads); if (hard_reg_set_intersect_p (regs, reg_class_contents[(int) SGPR_REGS])) @@ -4583,7 +4583,7 @@ gcn_md_reorg (void) && get_attr_laneselect (insn) == LANESELECT_YES) { HARD_REG_SET regs; - COPY_HARD_REG_SET (regs, prev_insn->writes); + regs = prev_insn->writes; AND_HARD_REG_SET (regs, ireads); if (hard_reg_set_intersect_p (regs, reg_class_contents[(int) SGPR_REGS]) @@ -4599,7 +4599,7 @@ gcn_md_reorg (void) && itype == TYPE_VOP_DPP) { HARD_REG_SET regs; - COPY_HARD_REG_SET (regs, prev_insn->writes); + regs = prev_insn->writes; AND_HARD_REG_SET (regs, ireads); if (hard_reg_set_intersect_p (regs, reg_class_contents[(int) VGPR_REGS])) @@ -4641,8 +4641,8 @@ gcn_md_reorg (void) back[oldest].insn = insn; back[oldest].unit = iunit; back[oldest].delayeduse = idelayeduse; - COPY_HARD_REG_SET (back[oldest].writes, iwrites); - COPY_HARD_REG_SET (back[oldest].reads, ireads); + back[oldest].writes = iwrites; + back[oldest].reads = ireads; back[oldest].age = 0; oldest = (oldest + 1) % max_waits; diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index 3768c8b..ca69656 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -2965,7 +2965,7 @@ ia64_compute_frame_size (HOST_WIDE_INT size) current_frame_info.spill_cfa_off = pretend_args_size - 16; current_frame_info.spill_size = spill_size; current_frame_info.extra_spill_size = extra_spill_size; - COPY_HARD_REG_SET (current_frame_info.mask, mask); + current_frame_info.mask = mask; current_frame_info.n_spilled = n_spilled; current_frame_info.initialized = reload_completed; } diff --git a/gcc/config/m32c/m32c.c b/gcc/config/m32c/m32c.c index ace00e0..4e18287 100644 --- a/gcc/config/m32c/m32c.c +++ b/gcc/config/m32c/m32c.c @@ -2152,7 +2152,7 @@ m32c_register_move_cost (machine_mode mode, reg_class_t from, HARD_REG_SET cc; /* FIXME: pick real values, but not 2 for now. */ - COPY_HARD_REG_SET (cc, reg_class_contents[(int) from]); + cc = reg_class_contents[from]; IOR_HARD_REG_SET (cc, reg_class_contents[(int) to]); if (mode == QImode diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c index 70f3e5c..fd69511 100644 --- a/gcc/config/m68k/m68k.c +++ b/gcc/config/m68k/m68k.c @@ -6555,7 +6555,7 @@ m68k_conditional_register_usage (void) HARD_REG_SET x; if (!TARGET_HARD_FLOAT) { - COPY_HARD_REG_SET (x, reg_class_contents[(int)FP_REGS]); + x = reg_class_contents[FP_REGS]; for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (TEST_HARD_REG_BIT (x, i)) fixed_regs[i] = call_used_regs[i] = 1; diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index c5389d2..7150a79 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -12975,7 +12975,7 @@ mips_class_max_nregs (enum reg_class rclass, machine_mode mode) HARD_REG_SET left; size = 0x8000; - COPY_HARD_REG_SET (left, reg_class_contents[(int) rclass]); + left = reg_class_contents[rclass]; if (hard_reg_set_intersect_p (left, reg_class_contents[(int) ST_REGS])) { if (mips_hard_regno_mode_ok (ST_REG_FIRST, mode)) diff --git a/gcc/config/pdp11/pdp11.c b/gcc/config/pdp11/pdp11.c index 62a1b27..2d3b94b 100644 --- a/gcc/config/pdp11/pdp11.c +++ b/gcc/config/pdp11/pdp11.c @@ -2213,7 +2213,7 @@ pdp11_conditional_register_usage (void) HARD_REG_SET x; if (!TARGET_FPU) { - COPY_HARD_REG_SET (x, reg_class_contents[(int)FPU_REGS]); + x = reg_class_contents[FPU_REGS]; for (i = 0; i < FIRST_PSEUDO_REGISTER; i++ ) if (TEST_HARD_REG_BIT (x, i)) fixed_regs[i] = call_used_regs[i] = 1; diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index e044c6e..8193c6b 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -21107,9 +21107,9 @@ rs6000_register_move_cost (machine_mode mode, Do this first so we give best-case answers for union classes containing both gprs and vsx regs. */ HARD_REG_SET to_vsx, from_vsx; - COPY_HARD_REG_SET (to_vsx, reg_class_contents[to]); + to_vsx = reg_class_contents[to]; AND_HARD_REG_SET (to_vsx, reg_class_contents[VSX_REGS]); - COPY_HARD_REG_SET (from_vsx, reg_class_contents[from]); + from_vsx = reg_class_contents[from]; AND_HARD_REG_SET (from_vsx, reg_class_contents[VSX_REGS]); if (!hard_reg_set_empty_p (to_vsx) && !hard_reg_set_empty_p (from_vsx) diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 04c56aa..d1af580 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -6708,7 +6708,7 @@ output_stack_adjust (int size, rtx reg, int epilogue_p, if (temp < 0 && ! current_function_interrupt && epilogue_p >= 0) { HARD_REG_SET temps; - COPY_HARD_REG_SET (temps, call_used_reg_set); + temps = call_used_reg_set; AND_COMPL_HARD_REG_SET (temps, call_fixed_reg_set); if (epilogue_p > 0) { @@ -6743,7 +6743,7 @@ output_stack_adjust (int size, rtx reg, int epilogue_p, { HARD_REG_SET temps; - COPY_HARD_REG_SET (temps, *live_regs_mask); + temps = *live_regs_mask; CLEAR_HARD_REG_BIT (temps, REGNO (reg)); temp = scavenge_reg (&temps); } diff --git a/gcc/final.c b/gcc/final.c index fefc487..252b0b6 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -5036,7 +5036,7 @@ collect_fn_hard_reg_usage (void) node = cgraph_node::rtl_info (current_function_decl); gcc_assert (node != NULL); - COPY_HARD_REG_SET (node->function_used_regs, function_used_regs); + node->function_used_regs = function_used_regs; node->function_used_regs_valid = 1; } @@ -5090,12 +5090,12 @@ get_call_reg_set_usage (rtx_insn *insn, HARD_REG_SET *reg_set, if (node != NULL && node->function_used_regs_valid) { - COPY_HARD_REG_SET (*reg_set, node->function_used_regs); + *reg_set = node->function_used_regs; AND_HARD_REG_SET (*reg_set, default_set); return true; } } - COPY_HARD_REG_SET (*reg_set, default_set); + *reg_set = default_set; targetm.remove_extra_call_preserved_regs (insn, reg_set); return false; } diff --git a/gcc/hard-reg-set.h b/gcc/hard-reg-set.h index 32626ba..3d6eef2 100644 --- a/gcc/hard-reg-set.h +++ b/gcc/hard-reg-set.h @@ -83,10 +83,10 @@ struct hard_reg_set_container CLEAR_HARD_REG_SET and SET_HARD_REG_SET. These take just one argument. - Also define macros for copying hard reg sets: - COPY_HARD_REG_SET and COMPL_HARD_REG_SET. - These take two arguments TO and FROM; they read from FROM - and store into TO. COMPL_HARD_REG_SET complements each bit. + Also define macros for copying the complement of a hard reg set: + COMPL_HARD_REG_SET. + This takes two arguments TO and FROM; it reads from FROM + and stores into TO. Also define macros for combining hard reg sets: IOR_HARD_REG_SET and AND_HARD_REG_SET. @@ -116,7 +116,6 @@ struct hard_reg_set_container #define CLEAR_HARD_REG_SET(TO) ((TO) = HARD_CONST (0)) #define SET_HARD_REG_SET(TO) ((TO) = ~ HARD_CONST (0)) -#define COPY_HARD_REG_SET(TO, FROM) ((TO) = (FROM)) #define COMPL_HARD_REG_SET(TO, FROM) ((TO) = ~(FROM)) #define IOR_HARD_REG_SET(TO, FROM) ((TO) |= (FROM)) @@ -186,12 +185,6 @@ SET_HARD_REG_SET (HARD_REG_SET &set) } inline void -COPY_HARD_REG_SET (HARD_REG_SET &to, const_hard_reg_set from) -{ - to = from; -} - -inline void COMPL_HARD_REG_SET (HARD_REG_SET &to, const_hard_reg_set from) { for (unsigned int i = 0; i < ARRAY_SIZE (to.elts); ++i) diff --git a/gcc/ira-build.c b/gcc/ira-build.c index c7457fa4..1fa7a86 100644 --- a/gcc/ira-build.c +++ b/gcc/ira-build.c @@ -456,8 +456,8 @@ ira_create_object (ira_allocno_t a, int subword) OBJECT_CONFLICT_VEC_P (obj) = false; OBJECT_CONFLICT_ARRAY (obj) = NULL; OBJECT_NUM_CONFLICTS (obj) = 0; - COPY_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), ira_no_alloc_regs); - COPY_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), ira_no_alloc_regs); + OBJECT_CONFLICT_HARD_REGS (obj) = ira_no_alloc_regs; + OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) = ira_no_alloc_regs; IOR_COMPL_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), reg_class_contents[aclass]); IOR_COMPL_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), @@ -2569,8 +2569,8 @@ remove_low_level_allocnos (void) ALLOCNO_NEXT_REGNO_ALLOCNO (a) = NULL; ALLOCNO_CAP_MEMBER (a) = NULL; FOR_EACH_ALLOCNO_OBJECT (a, obj, oi) - COPY_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), - OBJECT_TOTAL_CONFLICT_HARD_REGS (obj)); + OBJECT_CONFLICT_HARD_REGS (obj) + = OBJECT_TOTAL_CONFLICT_HARD_REGS (obj); #ifdef STACK_REGS if (ALLOCNO_TOTAL_NO_STACK_REG_P (a)) ALLOCNO_NO_STACK_REG_P (a) = true; @@ -3108,8 +3108,8 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit) flattening. */ continue; FOR_EACH_ALLOCNO_OBJECT (a, obj, oi) - COPY_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), - OBJECT_CONFLICT_HARD_REGS (obj)); + OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) + = OBJECT_CONFLICT_HARD_REGS (obj); #ifdef STACK_REGS ALLOCNO_TOTAL_NO_STACK_REG_P (a) = ALLOCNO_NO_STACK_REG_P (a); #endif diff --git a/gcc/ira-color.c b/gcc/ira-color.c index 9923699..fab3ce7 100644 --- a/gcc/ira-color.c +++ b/gcc/ira-color.c @@ -261,14 +261,14 @@ add_allocno_hard_regs (HARD_REG_SET set, int64_t cost) allocno_hard_regs_t hv; gcc_assert (! hard_reg_set_empty_p (set)); - COPY_HARD_REG_SET (temp.set, set); + temp.set = set; if ((hv = find_hard_regs (&temp)) != NULL) hv->cost += cost; else { hv = ((struct allocno_hard_regs *) ira_allocate (sizeof (struct allocno_hard_regs))); - COPY_HARD_REG_SET (hv->set, set); + hv->set = set; hv->cost = cost; allocno_hard_regs_vec.safe_push (hv); insert_hard_regs (hv); @@ -382,7 +382,7 @@ add_allocno_hard_regs_to_forest (allocno_hard_regs_node_t *roots, hard_regs_node_vec.safe_push (node); else if (hard_reg_set_intersect_p (hv->set, node->hard_regs->set)) { - COPY_HARD_REG_SET (temp_set, hv->set); + temp_set = hv->set; AND_HARD_REG_SET (temp_set, node->hard_regs->set); hv2 = add_allocno_hard_regs (temp_set, hv->cost); add_allocno_hard_regs_to_forest (&node->first, hv2); @@ -833,10 +833,10 @@ setup_left_conflict_sizes_p (ira_allocno_t a) nobj = ALLOCNO_NUM_OBJECTS (a); data = ALLOCNO_COLOR_DATA (a); subnodes = allocno_hard_regs_subnodes + data->hard_regs_subnodes_start; - COPY_HARD_REG_SET (profitable_hard_regs, data->profitable_hard_regs); + profitable_hard_regs = data->profitable_hard_regs; node = data->hard_regs_node; node_preorder_num = node->preorder_num; - COPY_HARD_REG_SET (node_set, node->hard_regs->set); + node_set = node->hard_regs->set; node_check_tick++; for (k = 0; k < nobj; k++) { @@ -859,7 +859,7 @@ setup_left_conflict_sizes_p (ira_allocno_t a) ->profitable_hard_regs)) continue; conflict_node = conflict_data->hard_regs_node; - COPY_HARD_REG_SET (conflict_node_set, conflict_node->hard_regs->set); + conflict_node_set = conflict_node->hard_regs->set; if (hard_reg_set_subset_p (node_set, conflict_node_set)) temp_node = node; else @@ -897,7 +897,7 @@ setup_left_conflict_sizes_p (ira_allocno_t a) int j, n, hard_regno; enum reg_class aclass; - COPY_HARD_REG_SET (temp_set, temp_node->hard_regs->set); + temp_set = temp_node->hard_regs->set; AND_HARD_REG_SET (temp_set, profitable_hard_regs); aclass = ALLOCNO_CLASS (a); for (n = 0, j = ira_class_hard_regs_num[aclass] - 1; j >= 0; j--) @@ -1042,8 +1042,8 @@ setup_profitable_hard_regs (void) else { mode = ALLOCNO_MODE (a); - COPY_HARD_REG_SET (data->profitable_hard_regs, - ira_useful_class_mode_regs[aclass][mode]); + data->profitable_hard_regs + = ira_useful_class_mode_regs[aclass][mode]; nobj = ALLOCNO_NUM_OBJECTS (a); for (k = 0; k < nobj; k++) { @@ -1589,20 +1589,17 @@ get_conflict_and_start_profitable_regs (ira_allocno_t a, bool retry_p, for (i = 0; i < nwords; i++) { obj = ALLOCNO_OBJECT (a, i); - COPY_HARD_REG_SET (conflict_regs[i], - OBJECT_TOTAL_CONFLICT_HARD_REGS (obj)); + conflict_regs[i] = OBJECT_TOTAL_CONFLICT_HARD_REGS (obj); } if (retry_p) { - COPY_HARD_REG_SET (*start_profitable_regs, - reg_class_contents[ALLOCNO_CLASS (a)]); + *start_profitable_regs = reg_class_contents[ALLOCNO_CLASS (a)]; AND_COMPL_HARD_REG_SET (*start_profitable_regs, ira_prohibited_class_mode_regs [ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]); } else - COPY_HARD_REG_SET (*start_profitable_regs, - ALLOCNO_COLOR_DATA (a)->profitable_hard_regs); + *start_profitable_regs = ALLOCNO_COLOR_DATA (a)->profitable_hard_regs; } /* Return true if HARD_REGNO is ok for assigning to allocno A with @@ -4387,7 +4384,7 @@ allocno_reload_assign (ira_allocno_t a, HARD_REG_SET forbidden_regs) for (i = 0; i < n; i++) { ira_object_t obj = ALLOCNO_OBJECT (a, i); - COPY_HARD_REG_SET (saved[i], OBJECT_TOTAL_CONFLICT_HARD_REGS (obj)); + saved[i] = OBJECT_TOTAL_CONFLICT_HARD_REGS (obj); IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), forbidden_regs); if (! flag_caller_saves && ALLOCNO_CALLS_CROSSED_NUM (a) != 0) IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), @@ -4434,7 +4431,7 @@ allocno_reload_assign (ira_allocno_t a, HARD_REG_SET forbidden_regs) for (i = 0; i < n; i++) { ira_object_t obj = ALLOCNO_OBJECT (a, i); - COPY_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), saved[i]); + OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) = saved[i]; } return reg_renumber[regno] >= 0; } @@ -4519,7 +4516,7 @@ ira_reassign_pseudos (int *spilled_pseudo_regs, int num, for (i = 0; i < num; i++) { regno = spilled_pseudo_regs[i]; - COPY_HARD_REG_SET (forbidden_regs, bad_spill_regs); + forbidden_regs = bad_spill_regs; IOR_HARD_REG_SET (forbidden_regs, pseudo_forbidden_regs[regno]); IOR_HARD_REG_SET (forbidden_regs, pseudo_previous_regs[regno]); gcc_assert (reg_renumber[regno] < 0); diff --git a/gcc/ira-conflicts.c b/gcc/ira-conflicts.c index 813a6d4..670e526 100644 --- a/gcc/ira-conflicts.c +++ b/gcc/ira-conflicts.c @@ -660,14 +660,14 @@ print_allocno_conflicts (FILE * file, bool reg_p, ira_allocno_t a) putc (')', file); } } - COPY_HARD_REG_SET (conflicting_hard_regs, OBJECT_TOTAL_CONFLICT_HARD_REGS (obj)); + conflicting_hard_regs = OBJECT_TOTAL_CONFLICT_HARD_REGS (obj); AND_COMPL_HARD_REG_SET (conflicting_hard_regs, ira_no_alloc_regs); AND_HARD_REG_SET (conflicting_hard_regs, reg_class_contents[ALLOCNO_CLASS (a)]); print_hard_reg_set (file, "\n;; total conflict hard regs:", conflicting_hard_regs); - COPY_HARD_REG_SET (conflicting_hard_regs, OBJECT_CONFLICT_HARD_REGS (obj)); + conflicting_hard_regs = OBJECT_CONFLICT_HARD_REGS (obj); AND_COMPL_HARD_REG_SET (conflicting_hard_regs, ira_no_alloc_regs); AND_HARD_REG_SET (conflicting_hard_regs, reg_class_contents[ALLOCNO_CLASS (a)]); @@ -741,7 +741,7 @@ ira_build_conflicts (void) CLEAR_HARD_REG_SET (temp_hard_reg_set); else { - COPY_HARD_REG_SET (temp_hard_reg_set, reg_class_contents[base]); + temp_hard_reg_set = reg_class_contents[base]; AND_COMPL_HARD_REG_SET (temp_hard_reg_set, ira_no_alloc_regs); AND_HARD_REG_SET (temp_hard_reg_set, call_used_reg_set); } diff --git a/gcc/ira-costs.c b/gcc/ira-costs.c index 3d81c90..f721c64 100644 --- a/gcc/ira-costs.c +++ b/gcc/ira-costs.c @@ -255,7 +255,7 @@ restrict_cost_classes (cost_classes_t full, machine_mode mode, /* Calculate the set of registers in CL that belong to REGS and are valid for MODE. */ HARD_REG_SET valid_for_cl; - COPY_HARD_REG_SET (valid_for_cl, reg_class_contents[cl]); + valid_for_cl = reg_class_contents[cl]; AND_HARD_REG_SET (valid_for_cl, regs); AND_COMPL_HARD_REG_SET (valid_for_cl, ira_prohibited_class_mode_regs[cl][mode]); @@ -343,7 +343,7 @@ setup_regno_cost_classes_by_aclass (int regno, enum reg_class aclass) if ((classes_ptr = cost_classes_aclass_cache[aclass]) == NULL) { - COPY_HARD_REG_SET (temp, reg_class_contents[aclass]); + temp = reg_class_contents[aclass]; AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs); /* We exclude classes from consideration which are subsets of ACLASS only if ACLASS is an uniform class. */ @@ -356,7 +356,7 @@ setup_regno_cost_classes_by_aclass (int regno, enum reg_class aclass) { /* Exclude non-uniform classes which are subsets of ACLASS. */ - COPY_HARD_REG_SET (temp2, reg_class_contents[cl]); + temp2 = reg_class_contents[cl]; AND_COMPL_HARD_REG_SET (temp2, ira_no_alloc_regs); if (hard_reg_set_subset_p (temp2, temp) && cl != aclass) continue; diff --git a/gcc/ira.c b/gcc/ira.c index 66f1fc1..a2ebbab 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -471,7 +471,7 @@ setup_class_hard_regs (void) ira_assert (SHRT_MAX >= FIRST_PSEUDO_REGISTER); for (cl = (int) N_REG_CLASSES - 1; cl >= 0; cl--) { - COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]); + temp_hard_regset = reg_class_contents[cl]; AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); CLEAR_HARD_REG_SET (processed_hard_reg_set); for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) @@ -514,7 +514,7 @@ setup_alloc_regs (bool use_hard_frame_p) #ifdef ADJUST_REG_ALLOC_ORDER ADJUST_REG_ALLOC_ORDER; #endif - COPY_HARD_REG_SET (no_unit_alloc_regs, fixed_nonglobal_reg_set); + no_unit_alloc_regs = fixed_nonglobal_reg_set; if (! use_hard_frame_p) SET_HARD_REG_BIT (no_unit_alloc_regs, HARD_FRAME_POINTER_REGNUM); setup_class_hard_regs (); @@ -541,7 +541,7 @@ setup_reg_subclasses (void) if (i == (int) NO_REGS) continue; - COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[i]); + temp_hard_regset = reg_class_contents[i]; AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); if (hard_reg_set_empty_p (temp_hard_regset)) continue; @@ -550,7 +550,7 @@ setup_reg_subclasses (void) { enum reg_class *p; - COPY_HARD_REG_SET (temp_hard_regset2, reg_class_contents[j]); + temp_hard_regset2 = reg_class_contents[j]; AND_COMPL_HARD_REG_SET (temp_hard_regset2, no_unit_alloc_regs); if (! hard_reg_set_subset_p (temp_hard_regset, temp_hard_regset2)) @@ -605,9 +605,9 @@ setup_class_subset_and_memory_move_costs (void) for (cl = (int) N_REG_CLASSES - 1; cl >= 0; cl--) for (cl2 = (int) N_REG_CLASSES - 1; cl2 >= 0; cl2--) { - COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]); + temp_hard_regset = reg_class_contents[cl]; AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); - COPY_HARD_REG_SET (temp_hard_regset2, reg_class_contents[cl2]); + temp_hard_regset2 = reg_class_contents[cl2]; AND_COMPL_HARD_REG_SET (temp_hard_regset2, no_unit_alloc_regs); ira_class_subset_p[cl][cl2] = hard_reg_set_subset_p (temp_hard_regset, temp_hard_regset2); @@ -757,7 +757,7 @@ setup_stack_reg_pressure_class (void) for (i = 0; i < ira_pressure_classes_num; i++) { cl = ira_pressure_classes[i]; - COPY_HARD_REG_SET (temp_hard_regset2, temp_hard_regset); + temp_hard_regset2 = temp_hard_regset; AND_HARD_REG_SET (temp_hard_regset2, reg_class_contents[cl]); size = hard_reg_set_size (temp_hard_regset2); if (best < size) @@ -816,7 +816,7 @@ setup_pressure_classes (void) register pressure class. */ for (m = 0; m < NUM_MACHINE_MODES; m++) { - COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]); + temp_hard_regset = reg_class_contents[cl]; AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); AND_COMPL_HARD_REG_SET (temp_hard_regset, ira_prohibited_class_mode_regs[cl][m]); @@ -833,7 +833,7 @@ setup_pressure_classes (void) } curr = 0; insert_p = true; - COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]); + temp_hard_regset = reg_class_contents[cl]; AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); /* Remove so far added pressure classes which are subset of the current candidate class. Prefer GENERAL_REGS as a pressure @@ -845,7 +845,7 @@ setup_pressure_classes (void) for (i = 0; i < n; i++) { cl2 = pressure_classes[i]; - COPY_HARD_REG_SET (temp_hard_regset2, reg_class_contents[cl2]); + temp_hard_regset2 = reg_class_contents[cl2]; AND_COMPL_HARD_REG_SET (temp_hard_regset2, no_unit_alloc_regs); if (hard_reg_set_subset_p (temp_hard_regset, temp_hard_regset2) && (! hard_reg_set_equal_p (temp_hard_regset, @@ -882,7 +882,7 @@ setup_pressure_classes (void) registers available for the allocation. */ CLEAR_HARD_REG_SET (temp_hard_regset); CLEAR_HARD_REG_SET (temp_hard_regset2); - COPY_HARD_REG_SET (ignore_hard_regs, no_unit_alloc_regs); + ignore_hard_regs = no_unit_alloc_regs; for (cl = 0; cl < LIM_REG_CLASSES; cl++) { /* For some targets (like MIPS with MD_REGS), there are some @@ -1001,12 +1001,12 @@ setup_allocno_and_important_classes (void) same set of hard registers. */ for (i = 0; i < LIM_REG_CLASSES; i++) { - COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[i]); + temp_hard_regset = reg_class_contents[i]; AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); for (j = 0; j < n; j++) { cl = classes[j]; - COPY_HARD_REG_SET (temp_hard_regset2, reg_class_contents[cl]); + temp_hard_regset2 = reg_class_contents[cl]; AND_COMPL_HARD_REG_SET (temp_hard_regset2, no_unit_alloc_regs); if (hard_reg_set_equal_p (temp_hard_regset, @@ -1037,13 +1037,12 @@ setup_allocno_and_important_classes (void) for (cl = 0; cl < N_REG_CLASSES; cl++) if (ira_class_hard_regs_num[cl] > 0) { - COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]); + temp_hard_regset = reg_class_contents[cl]; AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); set_p = false; for (j = 0; j < ira_allocno_classes_num; j++) { - COPY_HARD_REG_SET (temp_hard_regset2, - reg_class_contents[ira_allocno_classes[j]]); + temp_hard_regset2 = reg_class_contents[ira_allocno_classes[j]]; AND_COMPL_HARD_REG_SET (temp_hard_regset2, no_unit_alloc_regs); if ((enum reg_class) cl == ira_allocno_classes[j]) break; @@ -1118,8 +1117,7 @@ setup_class_translate_array (enum reg_class *class_translate, for (i = 0; i < classes_num; i++) { aclass = classes[i]; - COPY_HARD_REG_SET (temp_hard_regset, - reg_class_contents[aclass]); + temp_hard_regset = reg_class_contents[aclass]; AND_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]); AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); if (! hard_reg_set_empty_p (temp_hard_regset)) @@ -1223,9 +1221,9 @@ setup_reg_class_relations (void) ira_reg_classes_intersect_p[cl1][cl2] = false; ira_reg_class_intersect[cl1][cl2] = NO_REGS; ira_reg_class_subset[cl1][cl2] = NO_REGS; - COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl1]); + temp_hard_regset = reg_class_contents[cl1]; AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); - COPY_HARD_REG_SET (temp_set2, reg_class_contents[cl2]); + temp_set2 = reg_class_contents[cl2]; AND_COMPL_HARD_REG_SET (temp_set2, no_unit_alloc_regs); if (hard_reg_set_empty_p (temp_hard_regset) && hard_reg_set_empty_p (temp_set2)) @@ -1264,15 +1262,15 @@ setup_reg_class_relations (void) } ira_reg_class_subunion[cl1][cl2] = NO_REGS; ira_reg_class_superunion[cl1][cl2] = NO_REGS; - COPY_HARD_REG_SET (intersection_set, reg_class_contents[cl1]); + intersection_set = reg_class_contents[cl1]; AND_HARD_REG_SET (intersection_set, reg_class_contents[cl2]); AND_COMPL_HARD_REG_SET (intersection_set, no_unit_alloc_regs); - COPY_HARD_REG_SET (union_set, reg_class_contents[cl1]); + union_set = reg_class_contents[cl1]; IOR_HARD_REG_SET (union_set, reg_class_contents[cl2]); AND_COMPL_HARD_REG_SET (union_set, no_unit_alloc_regs); for (cl3 = 0; cl3 < N_REG_CLASSES; cl3++) { - COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl3]); + temp_hard_regset = reg_class_contents[cl3]; AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); if (hard_reg_set_subset_p (temp_hard_regset, intersection_set)) { @@ -1281,10 +1279,9 @@ setup_reg_class_relations (void) of CL1 and CL2. */ if (important_class_p[cl3]) { - COPY_HARD_REG_SET - (temp_set2, - reg_class_contents - [(int) ira_reg_class_intersect[cl1][cl2]]); + temp_set2 + = (reg_class_contents + [ira_reg_class_intersect[cl1][cl2]]); AND_COMPL_HARD_REG_SET (temp_set2, no_unit_alloc_regs); if (! hard_reg_set_subset_p (temp_hard_regset, temp_set2) /* If the allocatable hard register sets are @@ -1302,9 +1299,8 @@ setup_reg_class_relations (void) ira_reg_class_intersect[cl1][cl2]]))))) ira_reg_class_intersect[cl1][cl2] = (enum reg_class) cl3; } - COPY_HARD_REG_SET - (temp_set2, - reg_class_contents[(int) ira_reg_class_subset[cl1][cl2]]); + temp_set2 + = reg_class_contents[ira_reg_class_subset[cl1][cl2]]; AND_COMPL_HARD_REG_SET (temp_set2, no_unit_alloc_regs); if (! hard_reg_set_subset_p (temp_hard_regset, temp_set2) /* Ignore unavailable hard registers and prefer @@ -1322,9 +1318,8 @@ setup_reg_class_relations (void) /* CL3 allocatable hard register set is inside of union of allocatable hard register sets of CL1 and CL2. */ - COPY_HARD_REG_SET - (temp_set2, - reg_class_contents[(int) ira_reg_class_subunion[cl1][cl2]]); + temp_set2 + = reg_class_contents[ira_reg_class_subunion[cl1][cl2]]; AND_COMPL_HARD_REG_SET (temp_set2, no_unit_alloc_regs); if (ira_reg_class_subunion[cl1][cl2] == NO_REGS || (hard_reg_set_subset_p (temp_set2, temp_hard_regset) @@ -1347,9 +1342,8 @@ setup_reg_class_relations (void) /* CL3 allocatable hard register set contains union of allocatable hard register sets of CL1 and CL2. */ - COPY_HARD_REG_SET - (temp_set2, - reg_class_contents[(int) ira_reg_class_superunion[cl1][cl2]]); + temp_set2 + = reg_class_contents[ira_reg_class_superunion[cl1][cl2]]; AND_COMPL_HARD_REG_SET (temp_set2, no_unit_alloc_regs); if (ira_reg_class_superunion[cl1][cl2] == NO_REGS || (hard_reg_set_subset_p (temp_hard_regset, temp_set2) @@ -1499,7 +1493,7 @@ setup_prohibited_class_mode_regs (void) for (cl = (int) N_REG_CLASSES - 1; cl >= 0; cl--) { - COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]); + temp_hard_regset = reg_class_contents[cl]; AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); for (j = 0; j < NUM_MACHINE_MODES; j++) { @@ -2305,7 +2299,7 @@ ira_setup_eliminable_regset (void) if (frame_pointer_needed) df_set_regs_ever_live (HARD_FRAME_POINTER_REGNUM, true); - COPY_HARD_REG_SET (ira_no_alloc_regs, no_unit_alloc_regs); + ira_no_alloc_regs = no_unit_alloc_regs; CLEAR_HARD_REG_SET (eliminable_regset); compute_regs_asm_clobbered (); diff --git a/gcc/lra-assigns.c b/gcc/lra-assigns.c index 609feec..d5268c3 100644 --- a/gcc/lra-assigns.c +++ b/gcc/lra-assigns.c @@ -493,7 +493,7 @@ find_hard_regno_for_1 (int regno, int *cost, int try_only_hard_regno, HARD_REG_SET impossible_start_hard_regs, available_regs; if (hard_reg_set_empty_p (regno_set)) - COPY_HARD_REG_SET (conflict_set, lra_no_alloc_regs); + conflict_set = lra_no_alloc_regs; else { COMPL_HARD_REG_SET (conflict_set, regno_set); @@ -622,7 +622,7 @@ find_hard_regno_for_1 (int regno, int *cost, int try_only_hard_regno, biggest_nregs = hard_regno_nregs (hard_regno, biggest_mode); nregs_diff = (biggest_nregs - hard_regno_nregs (hard_regno, PSEUDO_REGNO_MODE (regno))); - COPY_HARD_REG_SET (available_regs, reg_class_contents[rclass]); + available_regs = reg_class_contents[rclass]; AND_COMPL_HARD_REG_SET (available_regs, lra_no_alloc_regs); for (i = 0; i < rclass_size; i++) { @@ -1217,7 +1217,7 @@ setup_live_pseudos_and_spill_after_risky_transforms (bitmap sparseset_set_bit (live_range_hard_reg_pseudos, r2->regno); } } - COPY_HARD_REG_SET (conflict_set, lra_no_alloc_regs); + conflict_set = lra_no_alloc_regs; IOR_HARD_REG_SET (conflict_set, lra_reg_info[regno].conflict_hard_regs); val = lra_reg_info[regno].val; offset = lra_reg_info[regno].offset; diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index f258407..9354612 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -1854,7 +1854,7 @@ prohibited_class_reg_set_mode_p (enum reg_class rclass, HARD_REG_SET temp; lra_assert (hard_reg_set_subset_p (reg_class_contents[rclass], set)); - COPY_HARD_REG_SET (temp, set); + temp = set; AND_COMPL_HARD_REG_SET (temp, lra_no_alloc_regs); return (hard_reg_set_subset_p (temp, ira_prohibited_class_mode_regs[rclass][mode])); @@ -2288,7 +2288,7 @@ process_alt_operands (int only_alternative) reloads. */ badop = false; this_alternative = curr_alt[m]; - COPY_HARD_REG_SET (this_alternative_set, curr_alt_set[m]); + this_alternative_set = curr_alt_set[m]; winreg = this_alternative != NO_REGS; break; } @@ -2517,8 +2517,7 @@ process_alt_operands (int only_alternative) { HARD_REG_SET available_regs; - COPY_HARD_REG_SET (available_regs, - reg_class_contents[this_alternative]); + available_regs = reg_class_contents[this_alternative]; AND_COMPL_HARD_REG_SET (available_regs, ira_prohibited_class_mode_regs[this_alternative][mode]); @@ -2888,7 +2887,7 @@ process_alt_operands (int only_alternative) goto fail; } curr_alt[nop] = this_alternative; - COPY_HARD_REG_SET (curr_alt_set[nop], this_alternative_set); + curr_alt_set[nop] = this_alternative_set; curr_alt_win[nop] = this_alternative_win; curr_alt_match_win[nop] = this_alternative_match_win; curr_alt_offmemok[nop] = this_alternative_offmemok; @@ -6246,7 +6245,7 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail) bitmap_clear (&invalid_invariant_regs); last_processed_bb = NULL; CLEAR_HARD_REG_SET (potential_reload_hard_regs); - COPY_HARD_REG_SET (live_hard_regs, eliminable_regset); + live_hard_regs = eliminable_regset; IOR_HARD_REG_SET (live_hard_regs, lra_no_alloc_regs); /* We don't process new insns generated in the loop. */ for (curr_insn = tail; curr_insn != PREV_INSN (head); curr_insn = prev_insn) diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c index 057ef8c..4403816 100644 --- a/gcc/lra-lives.c +++ b/gcc/lra-lives.c @@ -929,7 +929,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) { call_insn = curr_insn; if (! flag_ipa_ra && ! targetm.return_call_with_max_clobbers) - COPY_HARD_REG_SET(last_call_used_reg_set, call_used_reg_set); + last_call_used_reg_set = call_used_reg_set; else { HARD_REG_SET this_call_used_reg_set; @@ -953,7 +953,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) last_call_used_reg_set, last_call_insn); } - COPY_HARD_REG_SET(last_call_used_reg_set, this_call_used_reg_set); + last_call_used_reg_set = this_call_used_reg_set; last_call_insn = call_insn; } diff --git a/gcc/lra-spills.c b/gcc/lra-spills.c index a322da8..26cb421 100644 --- a/gcc/lra-spills.c +++ b/gcc/lra-spills.c @@ -243,7 +243,7 @@ assign_spill_hard_regs (int *pseudo_regnos, int n) /* Set up reserved hard regs for every program point. */ reserved_hard_regs = XNEWVEC (HARD_REG_SET, lra_live_max_point); for (p = 0; p < lra_live_max_point; p++) - COPY_HARD_REG_SET (reserved_hard_regs[p], lra_no_alloc_regs); + reserved_hard_regs[p] = lra_no_alloc_regs; for (i = FIRST_PSEUDO_REGISTER; i < regs_num; i++) if (lra_reg_info[i].nrefs != 0 && (hard_regno = lra_get_regno_hard_regno (i)) >= 0) @@ -274,8 +274,7 @@ assign_spill_hard_regs (int *pseudo_regnos, int n) continue; } lra_assert (spill_class != NO_REGS); - COPY_HARD_REG_SET (conflict_hard_regs, - lra_reg_info[regno].conflict_hard_regs); + conflict_hard_regs = lra_reg_info[regno].conflict_hard_regs; for (r = lra_reg_info[regno].live_ranges; r != NULL; r = r->next) for (p = r->start; p <= r->finish; p++) IOR_HARD_REG_SET (conflict_hard_regs, reserved_hard_regs[p]); diff --git a/gcc/lra.c b/gcc/lra.c index 1f97744..886fb10 100644 --- a/gcc/lra.c +++ b/gcc/lra.c @@ -2384,7 +2384,7 @@ lra (FILE *f) need it. */ emit_note (NOTE_INSN_DELETED); - COPY_HARD_REG_SET (lra_no_alloc_regs, ira_no_alloc_regs); + lra_no_alloc_regs = ira_no_alloc_regs; init_reg_info (); expand_reg_info (); diff --git a/gcc/mode-switching.c b/gcc/mode-switching.c index eba7509..4a34d4a 100644 --- a/gcc/mode-switching.c +++ b/gcc/mode-switching.c @@ -165,7 +165,7 @@ new_seginfo (int mode, rtx_insn *insn, int bb, HARD_REG_SET regs_live) ptr->insn_ptr = insn; ptr->bbnum = bb; ptr->next = NULL; - COPY_HARD_REG_SET (ptr->regs_live, regs_live); + ptr->regs_live = regs_live; return ptr; } diff --git a/gcc/postreload.c b/gcc/postreload.c index 497a4b0..268b75b 100644 --- a/gcc/postreload.c +++ b/gcc/postreload.c @@ -1267,7 +1267,7 @@ reload_combine (void) REG_SET_TO_HARD_REG_SET (live, live_in); compute_use_by_pseudos (&live, live_in); - COPY_HARD_REG_SET (LABEL_LIVE (insn), live); + LABEL_LIVE (insn) = live; IOR_HARD_REG_SET (ever_live_at_start, live); } } diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c index 0f0089a..19f020a 100644 --- a/gcc/reg-stack.c +++ b/gcc/reg-stack.c @@ -368,7 +368,7 @@ straighten_stack (rtx_insn *insn, stack_ptr regstack) if (regstack->top <= 0) return; - COPY_HARD_REG_SET (temp_stack.reg_set, regstack->reg_set); + temp_stack.reg_set = regstack->reg_set; for (top = temp_stack.top = regstack->top; top >= 0; top--) temp_stack.reg[top] = FIRST_STACK_REG + temp_stack.top - top; diff --git a/gcc/reginfo.c b/gcc/reginfo.c index 4832aff..8268d0d 100644 --- a/gcc/reginfo.c +++ b/gcc/reginfo.c @@ -230,8 +230,8 @@ save_register_info (void) /* And similarly for reg_names. */ gcc_assert (sizeof reg_names == sizeof saved_reg_names); memcpy (saved_reg_names, reg_names, sizeof reg_names); - COPY_HARD_REG_SET (saved_accessible_reg_set, accessible_reg_set); - COPY_HARD_REG_SET (saved_operand_reg_set, operand_reg_set); + saved_accessible_reg_set = accessible_reg_set; + saved_operand_reg_set = operand_reg_set; } /* Restore the register information. */ @@ -247,8 +247,8 @@ restore_register_info (void) #endif memcpy (reg_names, saved_reg_names, sizeof reg_names); - COPY_HARD_REG_SET (accessible_reg_set, saved_accessible_reg_set); - COPY_HARD_REG_SET (operand_reg_set, saved_operand_reg_set); + accessible_reg_set = saved_accessible_reg_set; + operand_reg_set = saved_operand_reg_set; } /* After switches have been processed, which perhaps alter @@ -298,7 +298,7 @@ init_reg_sets_1 (void) HARD_REG_SET c; int k; - COPY_HARD_REG_SET (c, reg_class_contents[i]); + c = reg_class_contents[i]; IOR_HARD_REG_SET (c, reg_class_contents[j]); for (k = 0; k < N_REG_CLASSES; k++) if (hard_reg_set_subset_p (reg_class_contents[k], c) @@ -321,7 +321,7 @@ init_reg_sets_1 (void) HARD_REG_SET c; int k; - COPY_HARD_REG_SET (c, reg_class_contents[i]); + c = reg_class_contents[i]; IOR_HARD_REG_SET (c, reg_class_contents[j]); for (k = 0; k < N_REG_CLASSES; k++) if (hard_reg_set_subset_p (c, reg_class_contents[k])) @@ -450,8 +450,8 @@ init_reg_sets_1 (void) } } - COPY_HARD_REG_SET (call_fixed_reg_set, fixed_reg_set); - COPY_HARD_REG_SET (fixed_nonglobal_reg_set, fixed_reg_set); + call_fixed_reg_set = fixed_reg_set; + fixed_nonglobal_reg_set = fixed_reg_set; /* Preserve global registers if called more than once. */ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) @@ -1323,8 +1323,7 @@ record_subregs_of_mode (rtx subreg, bool partial_def) { valid_mode_changes[regno] = XOBNEW (&valid_mode_changes_obstack, HARD_REG_SET); - COPY_HARD_REG_SET (*valid_mode_changes[regno], - simplifiable_subregs (shape)); + *valid_mode_changes[regno] = simplifiable_subregs (shape); } } diff --git a/gcc/regrename.c b/gcc/regrename.c index 580f29d..997e884 100644 --- a/gcc/regrename.c +++ b/gcc/regrename.c @@ -253,7 +253,7 @@ create_new_chain (unsigned this_regno, unsigned this_nregs, rtx *loc, CLEAR_HARD_REG_BIT (live_hard_regs, head->regno + nregs); } - COPY_HARD_REG_SET (head->hard_conflicts, live_hard_regs); + head->hard_conflicts = live_hard_regs; bitmap_set_bit (&open_chains_set, head->id); open_chains = head; @@ -486,7 +486,7 @@ rename_chains (void) && reg == FRAME_POINTER_REGNUM)) continue; - COPY_HARD_REG_SET (this_unavailable, unavailable); + this_unavailable = unavailable; reg_class super_class = regrename_find_superclass (this_head, &n_uses, &this_unavailable); diff --git a/gcc/reload1.c b/gcc/reload1.c index e606982..cadad5e 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -1732,7 +1732,7 @@ order_regs_for_reload (class insn_chain *chain) HARD_REG_SET used_by_pseudos2; reg_set_iterator rsi; - COPY_HARD_REG_SET (bad_spill_regs, fixed_reg_set); + bad_spill_regs = fixed_reg_set; memset (spill_cost, 0, sizeof spill_cost); memset (spill_add_cost, 0, sizeof spill_add_cost); @@ -1823,7 +1823,7 @@ find_reg (class insn_chain *chain, int order) static int regno_pseudo_regs[FIRST_PSEUDO_REGISTER]; static int best_regno_pseudo_regs[FIRST_PSEUDO_REGISTER]; - COPY_HARD_REG_SET (not_usable, bad_spill_regs); + not_usable = bad_spill_regs; IOR_HARD_REG_SET (not_usable, bad_spill_regs_global); IOR_COMPL_HARD_REG_SET (not_usable, reg_class_contents[rl->rclass]); @@ -2007,7 +2007,7 @@ find_reload_regs (class insn_chain *chain) } } - COPY_HARD_REG_SET (chain->used_spill_regs, used_spill_regs_local); + chain->used_spill_regs = used_spill_regs_local; IOR_HARD_REG_SET (used_spill_regs, used_spill_regs_local); memcpy (chain->rld, rld, n_reloads * sizeof (struct reload)); diff --git a/gcc/resource.c b/gcc/resource.c index d4d86ce..5b738e0 100644 --- a/gcc/resource.c +++ b/gcc/resource.c @@ -565,12 +565,12 @@ find_dead_or_set_registers (rtx_insn *target, struct resources *res, } target_res = *res; - COPY_HARD_REG_SET (scratch, target_set.regs); + scratch = target_set.regs; AND_COMPL_HARD_REG_SET (scratch, needed.regs); AND_COMPL_HARD_REG_SET (target_res.regs, scratch); fallthrough_res = *res; - COPY_HARD_REG_SET (scratch, set.regs); + scratch = set.regs; AND_COMPL_HARD_REG_SET (scratch, needed.regs); AND_COMPL_HARD_REG_SET (fallthrough_res.regs, scratch); @@ -601,7 +601,7 @@ find_dead_or_set_registers (rtx_insn *target, struct resources *res, mark_referenced_resources (insn, &needed, true); mark_set_resources (insn, &set, 0, MARK_SRC_DEST_CALL); - COPY_HARD_REG_SET (scratch, set.regs); + scratch = set.regs; AND_COMPL_HARD_REG_SET (scratch, needed.regs); AND_COMPL_HARD_REG_SET (res->regs, scratch); } @@ -960,7 +960,7 @@ mark_target_live_regs (rtx_insn *insns, rtx target_maybe_return, struct resource update it below. */ if (b == tinfo->block && b != -1 && tinfo->bb_tick == bb_ticks[b]) { - COPY_HARD_REG_SET (res->regs, tinfo->live_regs); + res->regs = tinfo->live_regs; return; } } @@ -1121,7 +1121,7 @@ mark_target_live_regs (rtx_insn *insns, rtx target_maybe_return, struct resource IOR_HARD_REG_SET (current_live_regs, start_of_epilogue_needs.regs); } - COPY_HARD_REG_SET (res->regs, current_live_regs); + res->regs = current_live_regs; if (tinfo != NULL) { tinfo->block = b; @@ -1160,7 +1160,7 @@ mark_target_live_regs (rtx_insn *insns, rtx target_maybe_return, struct resource { mark_referenced_resources (insn, &needed, true); - COPY_HARD_REG_SET (scratch, needed.regs); + scratch = needed.regs; AND_COMPL_HARD_REG_SET (scratch, set.regs); IOR_HARD_REG_SET (new_resources.regs, scratch); @@ -1171,9 +1171,7 @@ mark_target_live_regs (rtx_insn *insns, rtx target_maybe_return, struct resource } if (tinfo != NULL) - { - COPY_HARD_REG_SET (tinfo->live_regs, res->regs); - } + tinfo->live_regs = res->regs; } /* Initialize the resources required by mark_target_live_regs (). diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c index f127ff7..ce2db81 100644 --- a/gcc/sel-sched.c +++ b/gcc/sel-sched.c @@ -1238,8 +1238,7 @@ mark_unavailable_hard_regs (def_t def, struct reg_rename *reg_rename_p, /* Leave regs as 'available' only from the current register class. */ - COPY_HARD_REG_SET (reg_rename_p->available_for_renaming, - reg_class_contents[cl]); + reg_rename_p->available_for_renaming = reg_class_contents[cl]; mode = GET_MODE (orig_dest); -- cgit v1.1 From 50b3f54d551787e0a066451ef60ef3b055a893e6 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Mon, 9 Sep 2019 17:59:10 +0000 Subject: Remove COMPL_HARD_REG_SET "COMPL_HARD_REG_SET (x, y)" becomes "x = ~y". 2019-09-09 Richard Sandiford gcc/ * hard-reg-set.h (HARD_REG_SET::operator~): New function. (COMPL_HARD_REG_SET): Delete. * config/c6x/c6x.c (c6x_call_saved_register_used): Use ~ instead of COMPL_HARD_REG_SET. (try_rename_operands): Likewise. * config/sh/sh.c (push_regs): Likewise. * lra-assigns.c (find_hard_regno_for_1): Likewise. * lra-constraints.c (contains_reg_p): Likewise. * reload1.c (finish_spills, choose_reload_regs_init): Likewise. From-SVN: r275529 --- gcc/ChangeLog | 12 ++++++++++++ gcc/config/c6x/c6x.c | 4 ++-- gcc/config/sh/sh.c | 5 +---- gcc/hard-reg-set.h | 23 +++++++++-------------- gcc/lra-assigns.c | 2 +- gcc/lra-constraints.c | 2 +- gcc/reload1.c | 4 ++-- 7 files changed, 28 insertions(+), 24 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a323888..69b742a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,17 @@ 2019-09-09 Richard Sandiford + * hard-reg-set.h (HARD_REG_SET::operator~): New function. + (COMPL_HARD_REG_SET): Delete. + * config/c6x/c6x.c (c6x_call_saved_register_used): Use ~ instead + of COMPL_HARD_REG_SET. + (try_rename_operands): Likewise. + * config/sh/sh.c (push_regs): Likewise. + * lra-assigns.c (find_hard_regno_for_1): Likewise. + * lra-constraints.c (contains_reg_p): Likewise. + * reload1.c (finish_spills, choose_reload_regs_init): Likewise. + +2019-09-09 Richard Sandiford + * hard-reg-set.h (COPY_HARD_REG_SET): Delete. * caller-save.c (save_call_clobbered_regs): Use assignment instead of COPY_HARD_REG_SET. diff --git a/gcc/config/c6x/c6x.c b/gcc/config/c6x/c6x.c index 05b111e..f6a4518 100644 --- a/gcc/config/c6x/c6x.c +++ b/gcc/config/c6x/c6x.c @@ -1094,7 +1094,7 @@ c6x_call_saved_register_used (tree call_expr) INIT_CUMULATIVE_ARGS (cum_v, NULL, NULL, 0, 0); cum = pack_cumulative_args (&cum_v); - COMPL_HARD_REG_SET (call_saved_regset, call_used_reg_set); + call_saved_regset = ~call_used_reg_set; for (i = 0; i < call_expr_nargs (call_expr); i++) { parameter = CALL_EXPR_ARG (call_expr, i); @@ -3472,7 +3472,7 @@ try_rename_operands (rtx_insn *head, rtx_insn *tail, unit_req_table reqs, } /* If we get here, we can do the renaming. */ - COMPL_HARD_REG_SET (unavailable, reg_class_contents[(int) super_class]); + unavailable = ~reg_class_contents[super_class]; old_reg = this_head->regno; best_reg = diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index d1af580..4b70ac9 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -6908,11 +6908,8 @@ push_regs (HARD_REG_SET *mask, bool interrupt_handler) if (i == FIRST_FP_REG && interrupt_handler && TARGET_FMOVD && hard_reg_set_intersect_p (*mask, reg_class_contents[DF_REGS])) { - HARD_REG_SET unsaved; - push (FPSCR_REG); - COMPL_HARD_REG_SET (unsaved, *mask); - fpscr_set_from_mem (NORMAL_MODE (FP_MODE), unsaved); + fpscr_set_from_mem (NORMAL_MODE (FP_MODE), ~*mask); skip_fpscr = true; } if (i != PR_REG diff --git a/gcc/hard-reg-set.h b/gcc/hard-reg-set.h index 3d6eef2..ca663e8 100644 --- a/gcc/hard-reg-set.h +++ b/gcc/hard-reg-set.h @@ -53,6 +53,15 @@ typedef const HARD_REG_SET const_hard_reg_set; struct HARD_REG_SET { + HARD_REG_SET + operator~ () const + { + HARD_REG_SET res; + for (unsigned int i = 0; i < ARRAY_SIZE (elts); ++i) + res.elts[i] = ~elts[i]; + return res; + } + HARD_REG_ELT_TYPE elts[HARD_REG_SET_LONGS]; }; typedef const HARD_REG_SET &const_hard_reg_set; @@ -83,11 +92,6 @@ struct hard_reg_set_container CLEAR_HARD_REG_SET and SET_HARD_REG_SET. These take just one argument. - Also define macros for copying the complement of a hard reg set: - COMPL_HARD_REG_SET. - This takes two arguments TO and FROM; it reads from FROM - and stores into TO. - Also define macros for combining hard reg sets: IOR_HARD_REG_SET and AND_HARD_REG_SET. These take two arguments TO and FROM; they read from FROM @@ -116,8 +120,6 @@ struct hard_reg_set_container #define CLEAR_HARD_REG_SET(TO) ((TO) = HARD_CONST (0)) #define SET_HARD_REG_SET(TO) ((TO) = ~ HARD_CONST (0)) -#define COMPL_HARD_REG_SET(TO, FROM) ((TO) = ~(FROM)) - #define IOR_HARD_REG_SET(TO, FROM) ((TO) |= (FROM)) #define IOR_COMPL_HARD_REG_SET(TO, FROM) ((TO) |= ~ (FROM)) #define AND_HARD_REG_SET(TO, FROM) ((TO) &= (FROM)) @@ -185,13 +187,6 @@ SET_HARD_REG_SET (HARD_REG_SET &set) } inline void -COMPL_HARD_REG_SET (HARD_REG_SET &to, const_hard_reg_set from) -{ - for (unsigned int i = 0; i < ARRAY_SIZE (to.elts); ++i) - to.elts[i] = ~from.elts[i]; -} - -inline void AND_HARD_REG_SET (HARD_REG_SET &to, const_hard_reg_set from) { for (unsigned int i = 0; i < ARRAY_SIZE (to.elts); ++i) diff --git a/gcc/lra-assigns.c b/gcc/lra-assigns.c index d5268c3..8c07e90 100644 --- a/gcc/lra-assigns.c +++ b/gcc/lra-assigns.c @@ -496,7 +496,7 @@ find_hard_regno_for_1 (int regno, int *cost, int try_only_hard_regno, conflict_set = lra_no_alloc_regs; else { - COMPL_HARD_REG_SET (conflict_set, regno_set); + conflict_set = ~regno_set; IOR_HARD_REG_SET (conflict_set, lra_no_alloc_regs); } rclass = regno_allocno_class_array[regno]; diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index 9354612..c3f0c6e 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -4559,7 +4559,7 @@ contains_reg_p (rtx x, bool hard_reg_p, bool spilled_p) regno = lra_get_regno_hard_regno (regno); if (regno < 0) return false; - COMPL_HARD_REG_SET (alloc_regs, lra_no_alloc_regs); + alloc_regs = ~lra_no_alloc_regs; return overlaps_hard_reg_set_p (alloc_regs, GET_MODE (x), regno); } else diff --git a/gcc/reload1.c b/gcc/reload1.c index cadad5e..b2c8304 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -4310,7 +4310,7 @@ finish_spills (int global) may be not included in the value calculated here because of possible removing caller-saves insns (see function delete_caller_save_insns. */ - COMPL_HARD_REG_SET (chain->used_spill_regs, used_by_pseudos); + chain->used_spill_regs = ~used_by_pseudos; AND_HARD_REG_SET (chain->used_spill_regs, used_spill_regs); } } @@ -6257,7 +6257,7 @@ choose_reload_regs_init (class insn_chain *chain, rtx *save_reload_reg_rtx) CLEAR_HARD_REG_SET (reload_reg_used_in_outaddr_addr[i]); } - COMPL_HARD_REG_SET (reload_reg_unavailable, chain->used_spill_regs); + reload_reg_unavailable = ~chain->used_spill_regs; CLEAR_HARD_REG_SET (reload_reg_used_for_inherit); -- cgit v1.1 From dc333d8ff60909dbed89126443e3024f1592f8a4 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Mon, 9 Sep 2019 17:59:14 +0000 Subject: Remove AND_HARD_REG_SET Use "x &= y" instead of "AND_HARD_REG_SET (x, y)" (or just "x & y" if the result is a temporary). 2019-09-09 Richard Sandiford gcc/ * hard-reg-set.h (HARD_REG_SET::operator&): New function. (HARD_REG_SET::operator&): Likewise. (AND_HARD_REG_SET): Delete. * caller-save.c (setup_save_areas): Use "&" instead of AND_HARD_REG_SET. (save_call_clobbered_regs): Likewise. * config/gcn/gcn.c (gcn_md_reorg): Likewise. * config/m32c/m32c.c (reduce_class): Likewise. * config/rs6000/rs6000.c (rs6000_register_move_cost): Likewise. * final.c (get_call_reg_set_usage): Likewise. * ira-color.c (add_allocno_hard_regs_to_forest): Likewise. (setup_left_conflict_sizes_p): Likewise. * ira-conflicts.c (print_allocno_conflicts): Likewise. (ira_build_conflicts): Likewise. * ira-costs.c (restrict_cost_classes): Likewise. * ira.c (setup_stack_reg_pressure_class, setup_class_translate_array) (setup_reg_class_relations): Likewise. * reginfo.c (init_reg_sets_1, record_subregs_of_mode): Likewise. * reload1.c (maybe_fix_stack_asms, finish_spills): Likewise. * resource.c (find_dead_or_set_registers): Likewise. * sel-sched.c (mark_unavailable_hard_regs): Likewise. From-SVN: r275530 --- gcc/ChangeLog | 24 ++++++++++++++++++++++++ gcc/caller-save.c | 8 ++++---- gcc/config/gcn/gcn.c | 12 +++--------- gcc/config/m32c/m32c.c | 3 +-- gcc/config/rs6000/rs6000.c | 6 ++---- gcc/final.c | 3 +-- gcc/hard-reg-set.h | 33 +++++++++++++++++++++------------ gcc/ira-color.c | 6 ++---- gcc/ira-conflicts.c | 8 +++----- gcc/ira-costs.c | 4 +--- gcc/ira.c | 11 +++++------ gcc/reginfo.c | 5 ++--- gcc/reload1.c | 5 ++--- gcc/resource.c | 2 +- gcc/sel-sched.c | 3 +-- 15 files changed, 73 insertions(+), 60 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 69b742a..dcc87c9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,29 @@ 2019-09-09 Richard Sandiford + * hard-reg-set.h (HARD_REG_SET::operator&): New function. + (HARD_REG_SET::operator&): Likewise. + (AND_HARD_REG_SET): Delete. + * caller-save.c (setup_save_areas): Use "&" instead of + AND_HARD_REG_SET. + (save_call_clobbered_regs): Likewise. + * config/gcn/gcn.c (gcn_md_reorg): Likewise. + * config/m32c/m32c.c (reduce_class): Likewise. + * config/rs6000/rs6000.c (rs6000_register_move_cost): Likewise. + * final.c (get_call_reg_set_usage): Likewise. + * ira-color.c (add_allocno_hard_regs_to_forest): Likewise. + (setup_left_conflict_sizes_p): Likewise. + * ira-conflicts.c (print_allocno_conflicts): Likewise. + (ira_build_conflicts): Likewise. + * ira-costs.c (restrict_cost_classes): Likewise. + * ira.c (setup_stack_reg_pressure_class, setup_class_translate_array) + (setup_reg_class_relations): Likewise. + * reginfo.c (init_reg_sets_1, record_subregs_of_mode): Likewise. + * reload1.c (maybe_fix_stack_asms, finish_spills): Likewise. + * resource.c (find_dead_or_set_registers): Likewise. + * sel-sched.c (mark_unavailable_hard_regs): Likewise. + +2019-09-09 Richard Sandiford + * hard-reg-set.h (HARD_REG_SET::operator~): New function. (COMPL_HARD_REG_SET): Delete. * config/c6x/c6x.c (c6x_call_saved_register_used): Use ~ instead diff --git a/gcc/caller-save.c b/gcc/caller-save.c index 03a9b33..b6bcb7b 100644 --- a/gcc/caller-save.c +++ b/gcc/caller-save.c @@ -457,7 +457,7 @@ setup_save_areas (void) AND_COMPL_HARD_REG_SET (used_regs, call_fixed_reg_set); AND_COMPL_HARD_REG_SET (used_regs, this_insn_sets); - AND_HARD_REG_SET (hard_regs_to_save, used_regs); + hard_regs_to_save &= used_regs; for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) if (TEST_HARD_REG_BIT (hard_regs_to_save, regno)) { @@ -542,7 +542,7 @@ setup_save_areas (void) AND_COMPL_HARD_REG_SET (used_regs, call_fixed_reg_set); AND_COMPL_HARD_REG_SET (used_regs, this_insn_sets); - AND_HARD_REG_SET (hard_regs_to_save, used_regs); + hard_regs_to_save &= used_regs; for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) if (TEST_HARD_REG_BIT (hard_regs_to_save, regno)) { @@ -781,7 +781,7 @@ save_call_clobbered_regs (void) CLEAR_HARD_REG_SET (referenced_regs); mark_referenced_regs (&PATTERN (insn), mark_reg_as_referenced, NULL); - AND_HARD_REG_SET (referenced_regs, hard_regs_saved); + referenced_regs &= hard_regs_saved; } for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) @@ -857,7 +857,7 @@ save_call_clobbered_regs (void) AND_COMPL_HARD_REG_SET (hard_regs_to_save, hard_regs_saved); get_call_reg_set_usage (insn, &call_def_reg_set, call_used_reg_set); - AND_HARD_REG_SET (hard_regs_to_save, call_def_reg_set); + hard_regs_to_save &= call_def_reg_set; for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) if (TEST_HARD_REG_BIT (hard_regs_to_save, regno)) diff --git a/gcc/config/gcn/gcn.c b/gcc/config/gcn/gcn.c index 548ab17..2c6c872 100644 --- a/gcc/config/gcn/gcn.c +++ b/gcc/config/gcn/gcn.c @@ -4552,9 +4552,7 @@ gcn_md_reorg (void) && prev_insn->unit == UNIT_VECTOR && gcn_vmem_insn_p (itype)) { - HARD_REG_SET regs; - regs = prev_insn->writes; - AND_HARD_REG_SET (regs, ireads); + HARD_REG_SET regs = prev_insn->writes & ireads; if (hard_reg_set_intersect_p (regs, reg_class_contents[(int) SGPR_REGS])) nops_rqd = 5 - prev_insn->age; @@ -4582,9 +4580,7 @@ gcn_md_reorg (void) && prev_insn->unit == UNIT_VECTOR && get_attr_laneselect (insn) == LANESELECT_YES) { - HARD_REG_SET regs; - regs = prev_insn->writes; - AND_HARD_REG_SET (regs, ireads); + HARD_REG_SET regs = prev_insn->writes & ireads; if (hard_reg_set_intersect_p (regs, reg_class_contents[(int) SGPR_REGS]) || hard_reg_set_intersect_p @@ -4598,9 +4594,7 @@ gcn_md_reorg (void) && prev_insn->unit == UNIT_VECTOR && itype == TYPE_VOP_DPP) { - HARD_REG_SET regs; - regs = prev_insn->writes; - AND_HARD_REG_SET (regs, ireads); + HARD_REG_SET regs = prev_insn->writes & ireads; if (hard_reg_set_intersect_p (regs, reg_class_contents[(int) VGPR_REGS])) nops_rqd = 2 - prev_insn->age; diff --git a/gcc/config/m32c/m32c.c b/gcc/config/m32c/m32c.c index 4e18287..d89064a 100644 --- a/gcc/config/m32c/m32c.c +++ b/gcc/config/m32c/m32c.c @@ -341,8 +341,7 @@ reduce_class (reg_class_t original_class, reg_class_t limiting_class, if (original_class == limiting_class) return original_class; - cc = reg_class_contents[original_class]; - AND_HARD_REG_SET (cc, reg_class_contents[limiting_class]); + cc = reg_class_contents[original_class] & reg_class_contents[limiting_class]; for (i = 0; i < LIM_REG_CLASSES; i++) { diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 8193c6b..03349e8 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -21107,10 +21107,8 @@ rs6000_register_move_cost (machine_mode mode, Do this first so we give best-case answers for union classes containing both gprs and vsx regs. */ HARD_REG_SET to_vsx, from_vsx; - to_vsx = reg_class_contents[to]; - AND_HARD_REG_SET (to_vsx, reg_class_contents[VSX_REGS]); - from_vsx = reg_class_contents[from]; - AND_HARD_REG_SET (from_vsx, reg_class_contents[VSX_REGS]); + to_vsx = reg_class_contents[to] & reg_class_contents[VSX_REGS]; + from_vsx = reg_class_contents[from] & reg_class_contents[VSX_REGS]; if (!hard_reg_set_empty_p (to_vsx) && !hard_reg_set_empty_p (from_vsx) && (TARGET_VSX diff --git a/gcc/final.c b/gcc/final.c index 252b0b6..5347fac 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -5090,8 +5090,7 @@ get_call_reg_set_usage (rtx_insn *insn, HARD_REG_SET *reg_set, if (node != NULL && node->function_used_regs_valid) { - *reg_set = node->function_used_regs; - AND_HARD_REG_SET (*reg_set, default_set); + *reg_set = node->function_used_regs & default_set; return true; } } diff --git a/gcc/hard-reg-set.h b/gcc/hard-reg-set.h index ca663e8..5733782 100644 --- a/gcc/hard-reg-set.h +++ b/gcc/hard-reg-set.h @@ -62,6 +62,23 @@ struct HARD_REG_SET return res; } + HARD_REG_SET + operator& (const HARD_REG_SET &other) const + { + HARD_REG_SET res; + for (unsigned int i = 0; i < ARRAY_SIZE (elts); ++i) + res.elts[i] = elts[i] & other.elts[i]; + return res; + } + + HARD_REG_SET & + operator&= (const HARD_REG_SET &other) + { + for (unsigned int i = 0; i < ARRAY_SIZE (elts); ++i) + elts[i] &= other.elts[i]; + return *this; + } + HARD_REG_ELT_TYPE elts[HARD_REG_SET_LONGS]; }; typedef const HARD_REG_SET &const_hard_reg_set; @@ -92,10 +109,10 @@ struct hard_reg_set_container CLEAR_HARD_REG_SET and SET_HARD_REG_SET. These take just one argument. - Also define macros for combining hard reg sets: - IOR_HARD_REG_SET and AND_HARD_REG_SET. - These take two arguments TO and FROM; they read from FROM - and combine bitwise into TO. Define also two variants + Also define a macro for combining hard reg sets: + IOR_HARD_REG_SET + This takes two arguments TO and FROM; it reads from FROM + and combines bitwise into TO. Define also IOR_COMPL_HARD_REG_SET and AND_COMPL_HARD_REG_SET which use the complement of the set FROM. @@ -122,7 +139,6 @@ struct hard_reg_set_container #define IOR_HARD_REG_SET(TO, FROM) ((TO) |= (FROM)) #define IOR_COMPL_HARD_REG_SET(TO, FROM) ((TO) |= ~ (FROM)) -#define AND_HARD_REG_SET(TO, FROM) ((TO) &= (FROM)) #define AND_COMPL_HARD_REG_SET(TO, FROM) ((TO) &= ~ (FROM)) static inline bool @@ -187,13 +203,6 @@ SET_HARD_REG_SET (HARD_REG_SET &set) } inline void -AND_HARD_REG_SET (HARD_REG_SET &to, const_hard_reg_set from) -{ - for (unsigned int i = 0; i < ARRAY_SIZE (to.elts); ++i) - to.elts[i] &= from.elts[i]; -} - -inline void AND_COMPL_HARD_REG_SET (HARD_REG_SET &to, const_hard_reg_set from) { for (unsigned int i = 0; i < ARRAY_SIZE (to.elts); ++i) diff --git a/gcc/ira-color.c b/gcc/ira-color.c index fab3ce7..0611891 100644 --- a/gcc/ira-color.c +++ b/gcc/ira-color.c @@ -382,8 +382,7 @@ add_allocno_hard_regs_to_forest (allocno_hard_regs_node_t *roots, hard_regs_node_vec.safe_push (node); else if (hard_reg_set_intersect_p (hv->set, node->hard_regs->set)) { - temp_set = hv->set; - AND_HARD_REG_SET (temp_set, node->hard_regs->set); + temp_set = hv->set & node->hard_regs->set; hv2 = add_allocno_hard_regs (temp_set, hv->cost); add_allocno_hard_regs_to_forest (&node->first, hv2); } @@ -897,8 +896,7 @@ setup_left_conflict_sizes_p (ira_allocno_t a) int j, n, hard_regno; enum reg_class aclass; - temp_set = temp_node->hard_regs->set; - AND_HARD_REG_SET (temp_set, profitable_hard_regs); + temp_set = temp_node->hard_regs->set & profitable_hard_regs; aclass = ALLOCNO_CLASS (a); for (n = 0, j = ira_class_hard_regs_num[aclass] - 1; j >= 0; j--) { diff --git a/gcc/ira-conflicts.c b/gcc/ira-conflicts.c index 670e526..f8804b7 100644 --- a/gcc/ira-conflicts.c +++ b/gcc/ira-conflicts.c @@ -662,15 +662,13 @@ print_allocno_conflicts (FILE * file, bool reg_p, ira_allocno_t a) } conflicting_hard_regs = OBJECT_TOTAL_CONFLICT_HARD_REGS (obj); AND_COMPL_HARD_REG_SET (conflicting_hard_regs, ira_no_alloc_regs); - AND_HARD_REG_SET (conflicting_hard_regs, - reg_class_contents[ALLOCNO_CLASS (a)]); + conflicting_hard_regs &= reg_class_contents[ALLOCNO_CLASS (a)]; print_hard_reg_set (file, "\n;; total conflict hard regs:", conflicting_hard_regs); conflicting_hard_regs = OBJECT_CONFLICT_HARD_REGS (obj); AND_COMPL_HARD_REG_SET (conflicting_hard_regs, ira_no_alloc_regs); - AND_HARD_REG_SET (conflicting_hard_regs, - reg_class_contents[ALLOCNO_CLASS (a)]); + conflicting_hard_regs &= reg_class_contents[ALLOCNO_CLASS (a)]; print_hard_reg_set (file, ";; conflict hard regs:", conflicting_hard_regs); putc ('\n', file); @@ -743,7 +741,7 @@ ira_build_conflicts (void) { temp_hard_reg_set = reg_class_contents[base]; AND_COMPL_HARD_REG_SET (temp_hard_reg_set, ira_no_alloc_regs); - AND_HARD_REG_SET (temp_hard_reg_set, call_used_reg_set); + temp_hard_reg_set &= call_used_reg_set; } FOR_EACH_ALLOCNO (a, ai) { diff --git a/gcc/ira-costs.c b/gcc/ira-costs.c index f721c64..ae94365 100644 --- a/gcc/ira-costs.c +++ b/gcc/ira-costs.c @@ -254,9 +254,7 @@ restrict_cost_classes (cost_classes_t full, machine_mode mode, /* Calculate the set of registers in CL that belong to REGS and are valid for MODE. */ - HARD_REG_SET valid_for_cl; - valid_for_cl = reg_class_contents[cl]; - AND_HARD_REG_SET (valid_for_cl, regs); + HARD_REG_SET valid_for_cl = reg_class_contents[cl] & regs; AND_COMPL_HARD_REG_SET (valid_for_cl, ira_prohibited_class_mode_regs[cl][mode]); AND_COMPL_HARD_REG_SET (valid_for_cl, ira_no_alloc_regs); diff --git a/gcc/ira.c b/gcc/ira.c index a2ebbab..6856d37 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -757,8 +757,7 @@ setup_stack_reg_pressure_class (void) for (i = 0; i < ira_pressure_classes_num; i++) { cl = ira_pressure_classes[i]; - temp_hard_regset2 = temp_hard_regset; - AND_HARD_REG_SET (temp_hard_regset2, reg_class_contents[cl]); + temp_hard_regset2 = temp_hard_regset & reg_class_contents[cl]; size = hard_reg_set_size (temp_hard_regset2); if (best < size) { @@ -1117,8 +1116,8 @@ setup_class_translate_array (enum reg_class *class_translate, for (i = 0; i < classes_num; i++) { aclass = classes[i]; - temp_hard_regset = reg_class_contents[aclass]; - AND_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]); + temp_hard_regset = (reg_class_contents[aclass] + & reg_class_contents[cl]); AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); if (! hard_reg_set_empty_p (temp_hard_regset)) { @@ -1262,8 +1261,8 @@ setup_reg_class_relations (void) } ira_reg_class_subunion[cl1][cl2] = NO_REGS; ira_reg_class_superunion[cl1][cl2] = NO_REGS; - intersection_set = reg_class_contents[cl1]; - AND_HARD_REG_SET (intersection_set, reg_class_contents[cl2]); + intersection_set = (reg_class_contents[cl1] + & reg_class_contents[cl2]); AND_COMPL_HARD_REG_SET (intersection_set, no_unit_alloc_regs); union_set = reg_class_contents[cl1]; IOR_HARD_REG_SET (union_set, reg_class_contents[cl2]); diff --git a/gcc/reginfo.c b/gcc/reginfo.c index 8268d0d..86f8b68 100644 --- a/gcc/reginfo.c +++ b/gcc/reginfo.c @@ -378,7 +378,7 @@ init_reg_sets_1 (void) else CLEAR_REG_SET (fixed_reg_set_regset); - AND_HARD_REG_SET (operand_reg_set, accessible_reg_set); + operand_reg_set &= accessible_reg_set; for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) { /* As a special exception, registers whose class is NO_REGS are @@ -1317,8 +1317,7 @@ record_subregs_of_mode (rtx subreg, bool partial_def) } if (valid_mode_changes[regno]) - AND_HARD_REG_SET (*valid_mode_changes[regno], - simplifiable_subregs (shape)); + *valid_mode_changes[regno] &= simplifiable_subregs (shape); else { valid_mode_changes[regno] diff --git a/gcc/reload1.c b/gcc/reload1.c index b2c8304..7aa3f85 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -1399,7 +1399,7 @@ maybe_fix_stack_asms (void) /* Those of the registers which are clobbered, but allowed by the constraints, must be usable as reload registers. So clear them out of the life information. */ - AND_HARD_REG_SET (allowed, clobbered); + allowed &= clobbered; for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (TEST_HARD_REG_BIT (allowed, i)) { @@ -4310,8 +4310,7 @@ finish_spills (int global) may be not included in the value calculated here because of possible removing caller-saves insns (see function delete_caller_save_insns. */ - chain->used_spill_regs = ~used_by_pseudos; - AND_HARD_REG_SET (chain->used_spill_regs, used_spill_regs); + chain->used_spill_regs = ~used_by_pseudos & used_spill_regs; } } diff --git a/gcc/resource.c b/gcc/resource.c index 5b738e0..b24679f 100644 --- a/gcc/resource.c +++ b/gcc/resource.c @@ -582,7 +582,7 @@ find_dead_or_set_registers (rtx_insn *target, struct resources *res, &fallthrough_res, 0, jump_count, set, needed); IOR_HARD_REG_SET (fallthrough_res.regs, target_res.regs); - AND_HARD_REG_SET (res->regs, fallthrough_res.regs); + res->regs &= fallthrough_res.regs; break; } else diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c index ce2db81..ccca43d 100644 --- a/gcc/sel-sched.c +++ b/gcc/sel-sched.c @@ -1245,8 +1245,7 @@ mark_unavailable_hard_regs (def_t def, struct reg_rename *reg_rename_p, /* Leave only registers available for this mode. */ if (!sel_hrd.regs_for_mode_ok[mode]) init_regs_for_mode (mode); - AND_HARD_REG_SET (reg_rename_p->available_for_renaming, - sel_hrd.regs_for_mode[mode]); + reg_rename_p->available_for_renaming &= sel_hrd.regs_for_mode[mode]; /* Exclude registers that are partially call clobbered. */ if (def->crosses_call -- cgit v1.1 From 44942965f4eae141bd1f8300e7f77d0c9a3936e4 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Mon, 9 Sep 2019 17:59:19 +0000 Subject: Remove IOR_HARD_REG_SET Use "x |= y" instead of "IOR_HARD_REG_SET (x, y)" (or just "x | y" if the result is a temporary). 2019-09-09 Richard Sandiford gcc/ * hard-reg-set.h (HARD_REG_SET::operator|): New function. (HARD_REG_SET::operator|=): Likewise. (IOR_HARD_REG_SET): Delete. * config/gcn/gcn.c (gcn_md_reorg): Use "|" instead of IOR_HARD_REG_SET. * config/m32c/m32c.c (m32c_register_move_cost): Likewise. * config/s390/s390.c (s390_adjust_loop_scan_osc): Likewise. * final.c (collect_fn_hard_reg_usage): Likewise. * hw-doloop.c (scan_loop, optimize_loop): Likewise. * ira-build.c (merge_hard_reg_conflicts): Likewise. (ior_hard_reg_conflicts, create_cap_allocno, propagate_allocno_info) (propagate_some_info_from_allocno): Likewise. (copy_info_to_removed_store_destinations): Likewise. * ira-color.c (add_allocno_hard_regs_to_forest, assign_hard_reg) (allocno_reload_assign, ira_reassign_pseudos): Likewise. (fast_allocation): Likewise. * ira-conflicts.c (ira_build_conflicts): Likewise. * ira-lives.c (make_object_dead, process_single_reg_class_operands) (process_bb_node_lives): Likewise. * ira.c (setup_pressure_classes, setup_reg_class_relations): Likewise. * lra-assigns.c (find_hard_regno_for_1): Likewise. (setup_live_pseudos_and_spill_after_risky_transforms): Likewise. * lra-constraints.c (process_alt_operands, inherit_in_ebb): Likewise. * lra-eliminations.c (spill_pseudos, update_reg_eliminate): Likewise. * lra-lives.c (mark_pseudo_dead, check_pseudos_live_through_calls) (process_bb_lives): Likewise. * lra-spills.c (assign_spill_hard_regs): Likewise. * postreload.c (reload_combine): Likewise. * reginfo.c (init_reg_sets_1): Likewise. * regrename.c (merge_overlapping_regs, find_rename_reg) (merge_chains): Likewise. * reload1.c (maybe_fix_stack_asms, order_regs_for_reload, find_reg) (find_reload_regs, finish_spills, choose_reload_regs_init) (emit_reload_insns): Likewise. * reorg.c (redundant_insn): Likewise. * resource.c (find_dead_or_set_registers, mark_set_resources) (mark_target_live_regs): Likewise. * rtlanal.c (find_all_hard_reg_sets): Likewise. * sched-deps.c (sched_analyze_insn): Likewise. * sel-sched.c (mark_unavailable_hard_regs): Likewise. (find_best_reg_for_expr): Likewise. * shrink-wrap.c (try_shrink_wrapping): Likewise. From-SVN: r275531 --- gcc/ChangeLog | 45 +++++++++++++++++++++++++++++++++++++++++++++ gcc/config/gcn/gcn.c | 2 +- gcc/config/m32c/m32c.c | 3 +-- gcc/config/s390/s390.c | 4 ++-- gcc/final.c | 6 +++--- gcc/hard-reg-set.h | 33 ++++++++++++++++++++------------- gcc/hw-doloop.c | 4 ++-- gcc/ira-build.c | 28 ++++++++++++++-------------- gcc/ira-color.c | 26 +++++++++++--------------- gcc/ira-conflicts.c | 18 ++++++------------ gcc/ira-lives.c | 22 ++++++++++------------ gcc/ira.c | 9 ++++----- gcc/lra-assigns.c | 9 +++------ gcc/lra-constraints.c | 21 +++++++-------------- gcc/lra-eliminations.c | 4 ++-- gcc/lra-lives.c | 9 ++++----- gcc/lra-spills.c | 2 +- gcc/postreload.c | 2 +- gcc/reginfo.c | 6 ++---- gcc/regrename.c | 6 +++--- gcc/reload1.c | 25 +++++++++++-------------- gcc/reorg.c | 2 +- gcc/resource.c | 12 ++++++------ gcc/rtlanal.c | 2 +- gcc/sched-deps.c | 2 +- gcc/sel-sched.c | 9 +++------ gcc/shrink-wrap.c | 2 +- 27 files changed, 166 insertions(+), 147 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dcc87c9..c7a6716 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,50 @@ 2019-09-09 Richard Sandiford + * hard-reg-set.h (HARD_REG_SET::operator|): New function. + (HARD_REG_SET::operator|=): Likewise. + (IOR_HARD_REG_SET): Delete. + * config/gcn/gcn.c (gcn_md_reorg): Use "|" instead of + IOR_HARD_REG_SET. + * config/m32c/m32c.c (m32c_register_move_cost): Likewise. + * config/s390/s390.c (s390_adjust_loop_scan_osc): Likewise. + * final.c (collect_fn_hard_reg_usage): Likewise. + * hw-doloop.c (scan_loop, optimize_loop): Likewise. + * ira-build.c (merge_hard_reg_conflicts): Likewise. + (ior_hard_reg_conflicts, create_cap_allocno, propagate_allocno_info) + (propagate_some_info_from_allocno): Likewise. + (copy_info_to_removed_store_destinations): Likewise. + * ira-color.c (add_allocno_hard_regs_to_forest, assign_hard_reg) + (allocno_reload_assign, ira_reassign_pseudos): Likewise. + (fast_allocation): Likewise. + * ira-conflicts.c (ira_build_conflicts): Likewise. + * ira-lives.c (make_object_dead, process_single_reg_class_operands) + (process_bb_node_lives): Likewise. + * ira.c (setup_pressure_classes, setup_reg_class_relations): Likewise. + * lra-assigns.c (find_hard_regno_for_1): Likewise. + (setup_live_pseudos_and_spill_after_risky_transforms): Likewise. + * lra-constraints.c (process_alt_operands, inherit_in_ebb): Likewise. + * lra-eliminations.c (spill_pseudos, update_reg_eliminate): Likewise. + * lra-lives.c (mark_pseudo_dead, check_pseudos_live_through_calls) + (process_bb_lives): Likewise. + * lra-spills.c (assign_spill_hard_regs): Likewise. + * postreload.c (reload_combine): Likewise. + * reginfo.c (init_reg_sets_1): Likewise. + * regrename.c (merge_overlapping_regs, find_rename_reg) + (merge_chains): Likewise. + * reload1.c (maybe_fix_stack_asms, order_regs_for_reload, find_reg) + (find_reload_regs, finish_spills, choose_reload_regs_init) + (emit_reload_insns): Likewise. + * reorg.c (redundant_insn): Likewise. + * resource.c (find_dead_or_set_registers, mark_set_resources) + (mark_target_live_regs): Likewise. + * rtlanal.c (find_all_hard_reg_sets): Likewise. + * sched-deps.c (sched_analyze_insn): Likewise. + * sel-sched.c (mark_unavailable_hard_regs): Likewise. + (find_best_reg_for_expr): Likewise. + * shrink-wrap.c (try_shrink_wrapping): Likewise. + +2019-09-09 Richard Sandiford + * hard-reg-set.h (HARD_REG_SET::operator&): New function. (HARD_REG_SET::operator&): Likewise. (AND_HARD_REG_SET): Delete. diff --git a/gcc/config/gcn/gcn.c b/gcc/config/gcn/gcn.c index 2c6c872..8d99eb2 100644 --- a/gcc/config/gcn/gcn.c +++ b/gcc/config/gcn/gcn.c @@ -4627,7 +4627,7 @@ gcn_md_reorg (void) not publish the cycle times for instructions. */ prev_insn->age += 1 + nops_rqd; - IOR_HARD_REG_SET (written, iwrites); + written |= iwrites; AND_COMPL_HARD_REG_SET (prev_insn->writes, written); } diff --git a/gcc/config/m32c/m32c.c b/gcc/config/m32c/m32c.c index d89064a..b60044f 100644 --- a/gcc/config/m32c/m32c.c +++ b/gcc/config/m32c/m32c.c @@ -2151,8 +2151,7 @@ m32c_register_move_cost (machine_mode mode, reg_class_t from, HARD_REG_SET cc; /* FIXME: pick real values, but not 2 for now. */ - cc = reg_class_contents[from]; - IOR_HARD_REG_SET (cc, reg_class_contents[(int) to]); + cc = reg_class_contents[from] | reg_class_contents[(int) to]; if (mode == QImode && hard_reg_set_intersect_p (cc, reg_class_contents[R23_REGS])) diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 389fca8..2c6b598 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -14073,7 +14073,7 @@ s390_adjust_loop_scan_osc (struct loop* loop) return false; find_all_hard_reg_sets (insn, &newregs, true); - IOR_HARD_REG_SET (modregs, newregs); + modregs |= newregs; set = single_set (insn); if (!set) @@ -14104,7 +14104,7 @@ s390_adjust_loop_scan_osc (struct loop* loop) return false; find_all_hard_reg_sets (insn, &newregs, true); - IOR_HARD_REG_SET (modregs, newregs); + modregs |= newregs; set = single_set (insn); if (!set) diff --git a/gcc/final.c b/gcc/final.c index 5347fac..6d91aa0 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -5010,15 +5010,15 @@ collect_fn_hard_reg_usage (void) call_used_reg_set)) return; - IOR_HARD_REG_SET (function_used_regs, insn_used_regs); + function_used_regs |= insn_used_regs; } find_all_hard_reg_sets (insn, &insn_used_regs, false); - IOR_HARD_REG_SET (function_used_regs, insn_used_regs); + function_used_regs |= insn_used_regs; } /* Be conservative - mark fixed and global registers as used. */ - IOR_HARD_REG_SET (function_used_regs, fixed_reg_set); + function_used_regs |= fixed_reg_set; #ifdef STACK_REGS /* Handle STACK_REGS conservatively, since the df-framework does not diff --git a/gcc/hard-reg-set.h b/gcc/hard-reg-set.h index 5733782..3f98e77 100644 --- a/gcc/hard-reg-set.h +++ b/gcc/hard-reg-set.h @@ -79,6 +79,23 @@ struct HARD_REG_SET return *this; } + HARD_REG_SET + operator| (const HARD_REG_SET &other) const + { + HARD_REG_SET res; + for (unsigned int i = 0; i < ARRAY_SIZE (elts); ++i) + res.elts[i] = elts[i] | other.elts[i]; + return res; + } + + HARD_REG_SET & + operator|= (const HARD_REG_SET &other) + { + for (unsigned int i = 0; i < ARRAY_SIZE (elts); ++i) + elts[i] |= other.elts[i]; + return *this; + } + HARD_REG_ELT_TYPE elts[HARD_REG_SET_LONGS]; }; typedef const HARD_REG_SET &const_hard_reg_set; @@ -109,12 +126,10 @@ struct hard_reg_set_container CLEAR_HARD_REG_SET and SET_HARD_REG_SET. These take just one argument. - Also define a macro for combining hard reg sets: - IOR_HARD_REG_SET - This takes two arguments TO and FROM; it reads from FROM - and combines bitwise into TO. Define also + Also define: IOR_COMPL_HARD_REG_SET and AND_COMPL_HARD_REG_SET - which use the complement of the set FROM. + These take two arguments TO and FROM; they read from FROM + and combines its complement bitwise into TO. Also define: @@ -137,7 +152,6 @@ struct hard_reg_set_container #define CLEAR_HARD_REG_SET(TO) ((TO) = HARD_CONST (0)) #define SET_HARD_REG_SET(TO) ((TO) = ~ HARD_CONST (0)) -#define IOR_HARD_REG_SET(TO, FROM) ((TO) |= (FROM)) #define IOR_COMPL_HARD_REG_SET(TO, FROM) ((TO) |= ~ (FROM)) #define AND_COMPL_HARD_REG_SET(TO, FROM) ((TO) &= ~ (FROM)) @@ -210,13 +224,6 @@ AND_COMPL_HARD_REG_SET (HARD_REG_SET &to, const_hard_reg_set from) } inline void -IOR_HARD_REG_SET (HARD_REG_SET &to, const_hard_reg_set from) -{ - for (unsigned int i = 0; i < ARRAY_SIZE (to.elts); ++i) - to.elts[i] |= from.elts[i]; -} - -inline void IOR_COMPL_HARD_REG_SET (HARD_REG_SET &to, const_hard_reg_set from) { for (unsigned int i = 0; i < ARRAY_SIZE (to.elts); ++i) diff --git a/gcc/hw-doloop.c b/gcc/hw-doloop.c index 2decece..3ee0b40 100644 --- a/gcc/hw-doloop.c +++ b/gcc/hw-doloop.c @@ -141,7 +141,7 @@ scan_loop (hwloop_info loop) CLEAR_HARD_REG_BIT (set_this_insn, REGNO (loop->iter_reg)); else if (reg_mentioned_p (loop->iter_reg, PATTERN (insn))) loop->iter_reg_used = true; - IOR_HARD_REG_SET (loop->regs_set_in_loop, set_this_insn); + loop->regs_set_in_loop |= set_this_insn; } } } @@ -581,7 +581,7 @@ optimize_loop (hwloop_info loop, struct hw_doloop_hooks *hooks) inner_depth = inner->depth; /* The set of registers may be changed while optimizing the inner loop. */ - IOR_HARD_REG_SET (loop->regs_set_in_loop, inner->regs_set_in_loop); + loop->regs_set_in_loop |= inner->regs_set_in_loop; } loop->depth = inner_depth + 1; diff --git a/gcc/ira-build.c b/gcc/ira-build.c index 1fa7a86..354f989 100644 --- a/gcc/ira-build.c +++ b/gcc/ira-build.c @@ -602,10 +602,10 @@ merge_hard_reg_conflicts (ira_allocno_t from, ira_allocno_t to, ira_object_t to_obj = ALLOCNO_OBJECT (to, i); if (!total_only) - IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (to_obj), - OBJECT_CONFLICT_HARD_REGS (from_obj)); - IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (to_obj), - OBJECT_TOTAL_CONFLICT_HARD_REGS (from_obj)); + OBJECT_CONFLICT_HARD_REGS (to_obj) + |= OBJECT_CONFLICT_HARD_REGS (from_obj); + OBJECT_TOTAL_CONFLICT_HARD_REGS (to_obj) + |= OBJECT_TOTAL_CONFLICT_HARD_REGS (from_obj); } #ifdef STACK_REGS if (!total_only && ALLOCNO_NO_STACK_REG_P (from)) @@ -625,8 +625,8 @@ ior_hard_reg_conflicts (ira_allocno_t a, HARD_REG_SET *set) FOR_EACH_ALLOCNO_OBJECT (a, obj, i) { - IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), *set); - IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), *set); + OBJECT_CONFLICT_HARD_REGS (obj) |= *set; + OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= *set; } } @@ -907,8 +907,8 @@ create_cap_allocno (ira_allocno_t a) ALLOCNO_CALLS_CROSSED_NUM (cap) = ALLOCNO_CALLS_CROSSED_NUM (a); ALLOCNO_CHEAP_CALLS_CROSSED_NUM (cap) = ALLOCNO_CHEAP_CALLS_CROSSED_NUM (a); - IOR_HARD_REG_SET (ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (cap), - ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a)); + ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (cap) + |= ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a); if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL) { fprintf (ira_dump_file, " Creating cap "); @@ -2036,8 +2036,8 @@ propagate_allocno_info (void) += ALLOCNO_CALLS_CROSSED_NUM (a); ALLOCNO_CHEAP_CALLS_CROSSED_NUM (parent_a) += ALLOCNO_CHEAP_CALLS_CROSSED_NUM (a); - IOR_HARD_REG_SET (ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (parent_a), - ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a)); + ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (parent_a) + |= ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a); ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (parent_a) += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a); aclass = ALLOCNO_CLASS (a); @@ -2419,8 +2419,8 @@ propagate_some_info_from_allocno (ira_allocno_t a, ira_allocno_t from_a) ALLOCNO_CALLS_CROSSED_NUM (a) += ALLOCNO_CALLS_CROSSED_NUM (from_a); ALLOCNO_CHEAP_CALLS_CROSSED_NUM (a) += ALLOCNO_CHEAP_CALLS_CROSSED_NUM (from_a); - IOR_HARD_REG_SET (ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a), - ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (from_a)); + ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a) + |= ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (from_a); ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a) += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (from_a); @@ -3060,8 +3060,8 @@ copy_info_to_removed_store_destinations (int regno) += ALLOCNO_CALLS_CROSSED_NUM (a); ALLOCNO_CHEAP_CALLS_CROSSED_NUM (parent_a) += ALLOCNO_CHEAP_CALLS_CROSSED_NUM (a); - IOR_HARD_REG_SET (ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (parent_a), - ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a)); + ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (parent_a) + |= ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a); ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (parent_a) += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a); merged_p = true; diff --git a/gcc/ira-color.c b/gcc/ira-color.c index 0611891..1078ef7 100644 --- a/gcc/ira-color.c +++ b/gcc/ira-color.c @@ -397,7 +397,7 @@ add_allocno_hard_regs_to_forest (allocno_hard_regs_node_t *roots, i++) { node = hard_regs_node_vec[i]; - IOR_HARD_REG_SET (temp_set, node->hard_regs->set); + temp_set |= node->hard_regs->set; } hv = add_allocno_hard_regs (temp_set, hv->cost); new_node = create_new_allocno_hard_regs_node (hv); @@ -1798,9 +1798,8 @@ assign_hard_reg (ira_allocno_t a, bool retry_p) hard_regno + num); } else - IOR_HARD_REG_SET - (conflicting_regs[word], - ira_reg_mode_hard_regset[hard_regno][mode]); + conflicting_regs[word] + |= ira_reg_mode_hard_regset[hard_regno][mode]; if (hard_reg_set_subset_p (profitable_hard_regs, conflicting_regs[word])) goto fail; @@ -4383,10 +4382,9 @@ allocno_reload_assign (ira_allocno_t a, HARD_REG_SET forbidden_regs) { ira_object_t obj = ALLOCNO_OBJECT (a, i); saved[i] = OBJECT_TOTAL_CONFLICT_HARD_REGS (obj); - IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), forbidden_regs); + OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= forbidden_regs; if (! flag_caller_saves && ALLOCNO_CALLS_CROSSED_NUM (a) != 0) - IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), - call_used_reg_set); + OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= call_used_reg_set; } ALLOCNO_ASSIGNED_P (a) = false; aclass = ALLOCNO_CLASS (a); @@ -4514,9 +4512,9 @@ ira_reassign_pseudos (int *spilled_pseudo_regs, int num, for (i = 0; i < num; i++) { regno = spilled_pseudo_regs[i]; - forbidden_regs = bad_spill_regs; - IOR_HARD_REG_SET (forbidden_regs, pseudo_forbidden_regs[regno]); - IOR_HARD_REG_SET (forbidden_regs, pseudo_previous_regs[regno]); + forbidden_regs = (bad_spill_regs + | pseudo_forbidden_regs[regno] + | pseudo_previous_regs[regno]); gcc_assert (reg_renumber[regno] < 0); a = ira_regno_allocno_map[regno]; ira_mark_allocation_change (regno); @@ -4881,11 +4879,10 @@ fast_allocation (void) for (l = 0; l < nr; l++) { ira_object_t obj = ALLOCNO_OBJECT (a, l); - IOR_HARD_REG_SET (conflict_hard_regs, - OBJECT_CONFLICT_HARD_REGS (obj)); + conflict_hard_regs |= OBJECT_CONFLICT_HARD_REGS (obj); for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next) for (j = r->start; j <= r->finish; j++) - IOR_HARD_REG_SET (conflict_hard_regs, used_hard_regs[j]); + conflict_hard_regs |= used_hard_regs[j]; } aclass = ALLOCNO_CLASS (a); ALLOCNO_ASSIGNED_P (a) = true; @@ -4933,8 +4930,7 @@ fast_allocation (void) ira_object_t obj = ALLOCNO_OBJECT (a, l); for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next) for (k = r->start; k <= r->finish; k++) - IOR_HARD_REG_SET (used_hard_regs[k], - ira_reg_mode_hard_regset[hard_regno][mode]); + used_hard_regs[k] |= ira_reg_mode_hard_regset[hard_regno][mode]; } } ira_free (sorted_allocnos); diff --git a/gcc/ira-conflicts.c b/gcc/ira-conflicts.c index f8804b7..46ff590 100644 --- a/gcc/ira-conflicts.c +++ b/gcc/ira-conflicts.c @@ -762,21 +762,15 @@ ira_build_conflicts (void) && REG_USERVAR_P (allocno_reg) && ! reg_is_parm_p (allocno_reg))) { - IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), - call_used_reg_set); - IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), - call_used_reg_set); + OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= call_used_reg_set; + OBJECT_CONFLICT_HARD_REGS (obj) |= call_used_reg_set; } else if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0) { - IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), - no_caller_save_reg_set); - IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), - temp_hard_reg_set); - IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), - no_caller_save_reg_set); - IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), - temp_hard_reg_set); + OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= no_caller_save_reg_set; + OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= temp_hard_reg_set; + OBJECT_CONFLICT_HARD_REGS (obj) |= no_caller_save_reg_set; + OBJECT_CONFLICT_HARD_REGS (obj) |= temp_hard_reg_set; } /* Now we deal with paradoxical subreg cases where certain registers diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c index 2029027..e1d502f 100644 --- a/gcc/ira-lives.c +++ b/gcc/ira-lives.c @@ -188,8 +188,8 @@ make_object_dead (ira_object_t obj) } } - IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), hard_regs_live); - IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), hard_regs_live); + OBJECT_CONFLICT_HARD_REGS (obj) |= hard_regs_live; + OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= hard_regs_live; /* If IGNORE_REG_FOR_CONFLICTS did not already conflict with OBJ, make sure it still doesn't. */ @@ -990,10 +990,8 @@ process_single_reg_class_operands (bool in_p, int freq) /* We could increase costs of A instead of making it conflicting with the hard register. But it works worse because it will be spilled in reload in anyway. */ - IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), - reg_class_contents[cl]); - IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), - reg_class_contents[cl]); + OBJECT_CONFLICT_HARD_REGS (obj) |= reg_class_contents[cl]; + OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= reg_class_contents[cl]; } } } @@ -1275,10 +1273,10 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) } if (can_throw_internal (insn)) { - IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), - this_call_used_reg_set); - IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), - this_call_used_reg_set); + OBJECT_CONFLICT_HARD_REGS (obj) + |= this_call_used_reg_set; + OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) + |= this_call_used_reg_set; } if (sparseset_bit_p (allocnos_processed, num)) @@ -1295,8 +1293,8 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) /* Mark it as saved at the next call. */ allocno_saved_at_call[num] = last_call_num + 1; ALLOCNO_CALLS_CROSSED_NUM (a)++; - IOR_HARD_REG_SET (ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a), - this_call_used_reg_set); + ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a) + |= this_call_used_reg_set; if (cheap_reg != NULL_RTX && ALLOCNO_REGNO (a) == (int) REGNO (cheap_reg)) ALLOCNO_CHEAP_CALLS_CROSSED_NUM (a)++; diff --git a/gcc/ira.c b/gcc/ira.c index 6856d37..970cf1d 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -892,15 +892,15 @@ setup_pressure_classes (void) break; if (m >= NUM_MACHINE_MODES) { - IOR_HARD_REG_SET (ignore_hard_regs, reg_class_contents[cl]); + ignore_hard_regs |= reg_class_contents[cl]; continue; } for (i = 0; i < n; i++) if ((int) pressure_classes[i] == cl) break; - IOR_HARD_REG_SET (temp_hard_regset2, reg_class_contents[cl]); + temp_hard_regset2 |= reg_class_contents[cl]; if (i < n) - IOR_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]); + temp_hard_regset |= reg_class_contents[cl]; } for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) /* Some targets (like SPARC with ICC reg) have allocatable regs @@ -1264,8 +1264,7 @@ setup_reg_class_relations (void) intersection_set = (reg_class_contents[cl1] & reg_class_contents[cl2]); AND_COMPL_HARD_REG_SET (intersection_set, no_unit_alloc_regs); - union_set = reg_class_contents[cl1]; - IOR_HARD_REG_SET (union_set, reg_class_contents[cl2]); + union_set = reg_class_contents[cl1] | reg_class_contents[cl2]; AND_COMPL_HARD_REG_SET (union_set, no_unit_alloc_regs); for (cl3 = 0; cl3 < N_REG_CLASSES; cl3++) { diff --git a/gcc/lra-assigns.c b/gcc/lra-assigns.c index 8c07e90..ce6b07b 100644 --- a/gcc/lra-assigns.c +++ b/gcc/lra-assigns.c @@ -495,16 +495,13 @@ find_hard_regno_for_1 (int regno, int *cost, int try_only_hard_regno, if (hard_reg_set_empty_p (regno_set)) conflict_set = lra_no_alloc_regs; else - { - conflict_set = ~regno_set; - IOR_HARD_REG_SET (conflict_set, lra_no_alloc_regs); - } + conflict_set = ~regno_set | lra_no_alloc_regs; rclass = regno_allocno_class_array[regno]; rclass_intersect_p = ira_reg_classes_intersect_p[rclass]; curr_hard_regno_costs_check++; sparseset_clear (conflict_reload_and_inheritance_pseudos); sparseset_clear (live_range_hard_reg_pseudos); - IOR_HARD_REG_SET (conflict_set, lra_reg_info[regno].conflict_hard_regs); + conflict_set |= lra_reg_info[regno].conflict_hard_regs; biggest_mode = lra_reg_info[regno].biggest_mode; for (r = lra_reg_info[regno].live_ranges; r != NULL; r = r->next) { @@ -1218,7 +1215,7 @@ setup_live_pseudos_and_spill_after_risky_transforms (bitmap } } conflict_set = lra_no_alloc_regs; - IOR_HARD_REG_SET (conflict_set, lra_reg_info[regno].conflict_hard_regs); + conflict_set |= lra_reg_info[regno].conflict_hard_regs; val = lra_reg_info[regno].val; offset = lra_reg_info[regno].offset; EXECUTE_IF_SET_IN_SPARSESET (live_range_hard_reg_pseudos, conflict_regno) diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index c3f0c6e..d4eea85 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -2373,14 +2373,12 @@ process_alt_operands (int only_alternative) if (mode == BLKmode) break; this_alternative = reg_class_subunion[this_alternative][cl]; - IOR_HARD_REG_SET (this_alternative_set, - reg_class_contents[cl]); + this_alternative_set |= reg_class_contents[cl]; if (costly_p) { this_costly_alternative = reg_class_subunion[this_costly_alternative][cl]; - IOR_HARD_REG_SET (this_costly_alternative_set, - reg_class_contents[cl]); + this_costly_alternative_set |= reg_class_contents[cl]; } winreg = true; if (REG_P (op)) @@ -6245,8 +6243,7 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail) bitmap_clear (&invalid_invariant_regs); last_processed_bb = NULL; CLEAR_HARD_REG_SET (potential_reload_hard_regs); - live_hard_regs = eliminable_regset; - IOR_HARD_REG_SET (live_hard_regs, lra_no_alloc_regs); + live_hard_regs = eliminable_regset | lra_no_alloc_regs; /* We don't process new insns generated in the loop. */ for (curr_insn = tail; curr_insn != PREV_INSN (head); curr_insn = prev_insn) { @@ -6316,8 +6313,7 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail) else setup_next_usage_insn (src_regno, curr_insn, reloads_num, false); if (hard_reg_set_subset_p (reg_class_contents[cl], live_hard_regs)) - IOR_HARD_REG_SET (potential_reload_hard_regs, - reg_class_contents[cl]); + potential_reload_hard_regs |= reg_class_contents[cl]; } else if (src_regno < 0 && dst_regno >= lra_constraint_new_regno_start @@ -6334,8 +6330,7 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail) if (process_invariant_for_inheritance (SET_DEST (curr_set), SET_SRC (curr_set))) change_p = true; if (hard_reg_set_subset_p (reg_class_contents[cl], live_hard_regs)) - IOR_HARD_REG_SET (potential_reload_hard_regs, - reg_class_contents[cl]); + potential_reload_hard_regs |= reg_class_contents[cl]; } else if (src_regno >= lra_constraint_new_regno_start && dst_regno < lra_constraint_new_regno_start @@ -6357,8 +6352,7 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail) /* Invalidate. */ usage_insns[dst_regno].check = 0; if (hard_reg_set_subset_p (reg_class_contents[cl], live_hard_regs)) - IOR_HARD_REG_SET (potential_reload_hard_regs, - reg_class_contents[cl]); + potential_reload_hard_regs |= reg_class_contents[cl]; } else if (INSN_P (curr_insn)) { @@ -6593,8 +6587,7 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail) if (ira_class_hard_regs_num[cl] <= max_small_class_regs_num) reloads_num++; if (hard_reg_set_subset_p (reg_class_contents[cl], live_hard_regs)) - IOR_HARD_REG_SET (potential_reload_hard_regs, - reg_class_contents[cl]); + potential_reload_hard_regs |= reg_class_contents[cl]; } } if (NONDEBUG_INSN_P (curr_insn)) diff --git a/gcc/lra-eliminations.c b/gcc/lra-eliminations.c index 943da88..7e5fbe3 100644 --- a/gcc/lra-eliminations.c +++ b/gcc/lra-eliminations.c @@ -1089,7 +1089,7 @@ spill_pseudos (HARD_REG_SET set) reg_renumber[i] = -1; bitmap_ior_into (&to_process, &lra_reg_info[i].insn_bitmap); } - IOR_HARD_REG_SET (lra_no_alloc_regs, set); + lra_no_alloc_regs |= set; for (insn = get_insns (); insn != NULL_RTX; insn = NEXT_INSN (insn)) if (bitmap_bit_p (&to_process, INSN_UID (insn))) { @@ -1202,7 +1202,7 @@ update_reg_eliminate (bitmap insns_with_changed_offsets) result = true; } } - IOR_HARD_REG_SET (lra_no_alloc_regs, temp_hard_reg_set); + lra_no_alloc_regs |= temp_hard_reg_set; AND_COMPL_HARD_REG_SET (eliminable_regset, temp_hard_reg_set); spill_pseudos (temp_hard_reg_set); return result; diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c index 4403816..e046817 100644 --- a/gcc/lra-lives.c +++ b/gcc/lra-lives.c @@ -327,7 +327,7 @@ static void mark_pseudo_dead (int regno) { lra_assert (!HARD_REGISTER_NUM_P (regno)); - IOR_HARD_REG_SET (lra_reg_info[regno].conflict_hard_regs, hard_regs_live); + lra_reg_info[regno].conflict_hard_regs |= hard_regs_live; if (!sparseset_bit_p (pseudos_live, regno)) return; @@ -602,8 +602,7 @@ check_pseudos_live_through_calls (int regno, lra_reg_info[regno].call_insn = call_insn; sparseset_clear_bit (pseudos_live_through_calls, regno); - IOR_HARD_REG_SET (lra_reg_info[regno].conflict_hard_regs, - last_call_used_reg_set); + lra_reg_info[regno].conflict_hard_regs |= last_call_used_reg_set; for (hr = 0; HARD_REGISTER_NUM_P (hr); hr++) if (targetm.hard_regno_call_part_clobbered (call_insn, hr, @@ -945,8 +944,8 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, j) { - IOR_HARD_REG_SET (lra_reg_info[j].actual_call_used_reg_set, - this_call_used_reg_set); + lra_reg_info[j].actual_call_used_reg_set + |= this_call_used_reg_set; if (flush) check_pseudos_live_through_calls (j, diff --git a/gcc/lra-spills.c b/gcc/lra-spills.c index 26cb421..0068e52 100644 --- a/gcc/lra-spills.c +++ b/gcc/lra-spills.c @@ -277,7 +277,7 @@ assign_spill_hard_regs (int *pseudo_regnos, int n) conflict_hard_regs = lra_reg_info[regno].conflict_hard_regs; for (r = lra_reg_info[regno].live_ranges; r != NULL; r = r->next) for (p = r->start; p <= r->finish; p++) - IOR_HARD_REG_SET (conflict_hard_regs, reserved_hard_regs[p]); + conflict_hard_regs |= reserved_hard_regs[p]; spill_class_size = ira_class_hard_regs_num[spill_class]; mode = lra_reg_info[regno].biggest_mode; for (k = 0; k < spill_class_size; k++) diff --git a/gcc/postreload.c b/gcc/postreload.c index 268b75b..3f2dac3 100644 --- a/gcc/postreload.c +++ b/gcc/postreload.c @@ -1268,7 +1268,7 @@ reload_combine (void) REG_SET_TO_HARD_REG_SET (live, live_in); compute_use_by_pseudos (&live, live_in); LABEL_LIVE (insn) = live; - IOR_HARD_REG_SET (ever_live_at_start, live); + ever_live_at_start |= live; } } diff --git a/gcc/reginfo.c b/gcc/reginfo.c index 86f8b68..9b77261 100644 --- a/gcc/reginfo.c +++ b/gcc/reginfo.c @@ -298,8 +298,7 @@ init_reg_sets_1 (void) HARD_REG_SET c; int k; - c = reg_class_contents[i]; - IOR_HARD_REG_SET (c, reg_class_contents[j]); + c = reg_class_contents[i] | reg_class_contents[j]; for (k = 0; k < N_REG_CLASSES; k++) if (hard_reg_set_subset_p (reg_class_contents[k], c) && !hard_reg_set_subset_p (reg_class_contents[k], @@ -321,8 +320,7 @@ init_reg_sets_1 (void) HARD_REG_SET c; int k; - c = reg_class_contents[i]; - IOR_HARD_REG_SET (c, reg_class_contents[j]); + c = reg_class_contents[i] | reg_class_contents[j]; for (k = 0; k < N_REG_CLASSES; k++) if (hard_reg_set_subset_p (c, reg_class_contents[k])) break; diff --git a/gcc/regrename.c b/gcc/regrename.c index 997e884..c28023e 100644 --- a/gcc/regrename.c +++ b/gcc/regrename.c @@ -292,7 +292,7 @@ merge_overlapping_regs (HARD_REG_SET *pset, class du_head *head) { bitmap_iterator bi; unsigned i; - IOR_HARD_REG_SET (*pset, head->hard_conflicts); + *pset |= head->hard_conflicts; EXECUTE_IF_SET_IN_BITMAP (&head->conflicts, 0, i, bi) { du_head_p other = regrename_chain_from_id (i); @@ -367,7 +367,7 @@ find_rename_reg (du_head_p this_head, enum reg_class super_class, If the chain needs a call-saved register, mark the call-used registers as unavailable. */ if (this_head->need_caller_save_reg) - IOR_HARD_REG_SET (*unavailable, call_used_reg_set); + *unavailable |= call_used_reg_set; /* Mark registers that overlap this chain's lifetime as unavailable. */ merge_overlapping_regs (unavailable, this_head); @@ -678,7 +678,7 @@ merge_chains (du_head_p c1, du_head_p c2) c2->first = c2->last = NULL; c2->id = c1->id; - IOR_HARD_REG_SET (c1->hard_conflicts, c2->hard_conflicts); + c1->hard_conflicts |= c2->hard_conflicts; bitmap_ior_into (&c1->conflicts, &c2->conflicts); c1->need_caller_save_reg |= c2->need_caller_save_reg; diff --git a/gcc/reload1.c b/gcc/reload1.c index 7aa3f85..6c95c9c 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -1364,7 +1364,7 @@ maybe_fix_stack_asms (void) { /* End of one alternative - mark the regs in the current class, and reset the class. */ - IOR_HARD_REG_SET (allowed, reg_class_contents[cls]); + allowed |= reg_class_contents[cls]; cls = NO_REGS; p++; if (c == '#') @@ -1745,8 +1745,8 @@ order_regs_for_reload (class insn_chain *chain) REG_SET_TO_HARD_REG_SET (used_by_pseudos, &chain->live_throughout); REG_SET_TO_HARD_REG_SET (used_by_pseudos2, &chain->dead_or_set); - IOR_HARD_REG_SET (bad_spill_regs, used_by_pseudos); - IOR_HARD_REG_SET (bad_spill_regs, used_by_pseudos2); + bad_spill_regs |= used_by_pseudos; + bad_spill_regs |= used_by_pseudos2; /* Now find out which pseudos are allocated to it, and update hard_reg_n_uses. */ @@ -1823,8 +1823,7 @@ find_reg (class insn_chain *chain, int order) static int regno_pseudo_regs[FIRST_PSEUDO_REGISTER]; static int best_regno_pseudo_regs[FIRST_PSEUDO_REGISTER]; - not_usable = bad_spill_regs; - IOR_HARD_REG_SET (not_usable, bad_spill_regs_global); + not_usable = bad_spill_regs | bad_spill_regs_global; IOR_COMPL_HARD_REG_SET (not_usable, reg_class_contents[rl->rclass]); CLEAR_HARD_REG_SET (used_by_other_reload); @@ -2008,7 +2007,7 @@ find_reload_regs (class insn_chain *chain) } chain->used_spill_regs = used_spill_regs_local; - IOR_HARD_REG_SET (used_spill_regs, used_spill_regs_local); + used_spill_regs |= used_spill_regs_local; memcpy (chain->rld, rld, n_reloads * sizeof (struct reload)); } @@ -4251,14 +4250,12 @@ finish_spills (int global) EXECUTE_IF_SET_IN_REG_SET (&chain->live_throughout, FIRST_PSEUDO_REGISTER, i, rsi) { - IOR_HARD_REG_SET (pseudo_forbidden_regs[i], - chain->used_spill_regs); + pseudo_forbidden_regs[i] |= chain->used_spill_regs; } EXECUTE_IF_SET_IN_REG_SET (&chain->dead_or_set, FIRST_PSEUDO_REGISTER, i, rsi) { - IOR_HARD_REG_SET (pseudo_forbidden_regs[i], - chain->used_spill_regs); + pseudo_forbidden_regs[i] |= chain->used_spill_regs; } } @@ -4302,7 +4299,7 @@ finish_spills (int global) { REG_SET_TO_HARD_REG_SET (used_by_pseudos, &chain->live_throughout); REG_SET_TO_HARD_REG_SET (used_by_pseudos2, &chain->dead_or_set); - IOR_HARD_REG_SET (used_by_pseudos, used_by_pseudos2); + used_by_pseudos |= used_by_pseudos2; compute_use_by_pseudos (&used_by_pseudos, &chain->live_throughout); compute_use_by_pseudos (&used_by_pseudos, &chain->dead_or_set); @@ -6239,9 +6236,9 @@ choose_reload_regs_init (class insn_chain *chain, rtx *save_reload_reg_rtx) { HARD_REG_SET tmp; REG_SET_TO_HARD_REG_SET (tmp, &chain->live_throughout); - IOR_HARD_REG_SET (reg_used_in_insn, tmp); + reg_used_in_insn |= tmp; REG_SET_TO_HARD_REG_SET (tmp, &chain->dead_or_set); - IOR_HARD_REG_SET (reg_used_in_insn, tmp); + reg_used_in_insn |= tmp; compute_use_by_pseudos (®_used_in_insn, &chain->live_throughout); compute_use_by_pseudos (®_used_in_insn, &chain->dead_or_set); } @@ -8420,7 +8417,7 @@ emit_reload_insns (class insn_chain *chain) } } } - IOR_HARD_REG_SET (reg_reloaded_dead, reg_reloaded_died); + reg_reloaded_dead |= reg_reloaded_died; } /* Go through the motions to emit INSN and test if it is strictly valid. diff --git a/gcc/reorg.c b/gcc/reorg.c index bdfcf88..f542a10 100644 --- a/gcc/reorg.c +++ b/gcc/reorg.c @@ -1575,7 +1575,7 @@ redundant_insn (rtx insn, rtx_insn *target, const vec &delay_list) /* Insns we pass may not set either NEEDED or SET, so merge them for simpler tests. */ needed.memory |= set.memory; - IOR_HARD_REG_SET (needed.regs, set.regs); + needed.regs |= set.regs; /* This insn isn't redundant if it conflicts with an insn that either is or will be in a delay slot of TARGET. */ diff --git a/gcc/resource.c b/gcc/resource.c index b24679f..f13956b 100644 --- a/gcc/resource.c +++ b/gcc/resource.c @@ -581,7 +581,7 @@ find_dead_or_set_registers (rtx_insn *target, struct resources *res, find_dead_or_set_registers (next_insn, &fallthrough_res, 0, jump_count, set, needed); - IOR_HARD_REG_SET (fallthrough_res.regs, target_res.regs); + fallthrough_res.regs |= target_res.regs; res->regs &= fallthrough_res.regs; break; } @@ -670,7 +670,7 @@ mark_set_resources (rtx x, struct resources *res, int in_dest, res->cc = res->memory = 1; get_call_reg_set_usage (call_insn, ®s, regs_invalidated_by_call); - IOR_HARD_REG_SET (res->regs, regs); + res->regs |= regs; for (link = CALL_INSN_FUNCTION_USAGE (call_insn); link; link = XEXP (link, 1)) @@ -1109,7 +1109,7 @@ mark_target_live_regs (rtx_insn *insns, rtx target_maybe_return, struct resource HARD_REG_SET extra_live; REG_SET_TO_HARD_REG_SET (extra_live, DF_LR_IN (bb)); - IOR_HARD_REG_SET (current_live_regs, extra_live); + current_live_regs |= extra_live; } } @@ -1118,7 +1118,7 @@ mark_target_live_regs (rtx_insn *insns, rtx target_maybe_return, struct resource are implicitly required at that point. */ else if (NOTE_P (real_insn) && NOTE_KIND (real_insn) == NOTE_INSN_EPILOGUE_BEG) - IOR_HARD_REG_SET (current_live_regs, start_of_epilogue_needs.regs); + current_live_regs |= start_of_epilogue_needs.regs; } res->regs = current_live_regs; @@ -1162,12 +1162,12 @@ mark_target_live_regs (rtx_insn *insns, rtx target_maybe_return, struct resource scratch = needed.regs; AND_COMPL_HARD_REG_SET (scratch, set.regs); - IOR_HARD_REG_SET (new_resources.regs, scratch); + new_resources.regs |= scratch; mark_set_resources (insn, &set, 0, MARK_SRC_DEST_CALL); } - IOR_HARD_REG_SET (res->regs, new_resources.regs); + res->regs |= new_resources.regs; } if (tinfo != NULL) diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 15185b7..3dcdc84 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -1478,7 +1478,7 @@ find_all_hard_reg_sets (const rtx_insn *insn, HARD_REG_SET *pset, bool implicit) CLEAR_HARD_REG_SET (*pset); note_stores (insn, record_hard_reg_sets, pset); if (CALL_P (insn) && implicit) - IOR_HARD_REG_SET (*pset, call_used_reg_set); + *pset |= call_used_reg_set; for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) if (REG_NOTE_KIND (link) == REG_INC) record_hard_reg_sets (XEXP (link, 0), NULL, pset); diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c index dcc84d7..8031d72 100644 --- a/gcc/sched-deps.c +++ b/gcc/sched-deps.c @@ -2901,7 +2901,7 @@ sched_analyze_insn (class deps_desc *deps, rtx x, rtx_insn *insn) { HARD_REG_SET temp; get_implicit_reg_pending_clobbers (&temp, insn); - IOR_HARD_REG_SET (implicit_reg_pending_clobbers, temp); + implicit_reg_pending_clobbers |= temp; } can_start_lhs_rhs_p = (NONJUMP_INSN_P (insn) diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c index ccca43d..e5b825a 100644 --- a/gcc/sel-sched.c +++ b/gcc/sel-sched.c @@ -1221,15 +1221,13 @@ mark_unavailable_hard_regs (def_t def, struct reg_rename *reg_rename_p, The HARD_REGNO_RENAME_OK covers other cases in condition below. */ if (IN_RANGE (REGNO (orig_dest), FIRST_STACK_REG, LAST_STACK_REG) && REGNO_REG_SET_P (used_regs, FIRST_STACK_REG)) - IOR_HARD_REG_SET (reg_rename_p->unavailable_hard_regs, - sel_hrd.stack_regs); + reg_rename_p->unavailable_hard_regs |= sel_hrd.stack_regs; #endif /* If there's a call on this path, make regs from call_used_reg_set unavailable. */ if (def->crosses_call) - IOR_HARD_REG_SET (reg_rename_p->unavailable_hard_regs, - call_used_reg_set); + reg_rename_p->unavailable_hard_regs |= call_used_reg_set; /* Stop here before reload: we need FRAME_REGS, STACK_REGS, and crosses_call, but not register classes. */ @@ -1684,8 +1682,7 @@ find_best_reg_for_expr (expr_t expr, blist_t bnds, bool *is_orig_reg_p) /* Join hard registers unavailable due to register class restrictions and live range intersection. */ - IOR_HARD_REG_SET (hard_regs_used, - reg_rename_data.unavailable_hard_regs); + hard_regs_used |= reg_rename_data.unavailable_hard_regs; best_reg = choose_best_reg (hard_regs_used, ®_rename_data, original_insns, is_orig_reg_p); diff --git a/gcc/shrink-wrap.c b/gcc/shrink-wrap.c index 9ee712e..bf6d045 100644 --- a/gcc/shrink-wrap.c +++ b/gcc/shrink-wrap.c @@ -688,7 +688,7 @@ try_shrink_wrapping (edge *entry_edge, rtx_insn *prologue_seq) CLEAR_HARD_REG_SET (this_used); note_uses (&PATTERN (insn), record_hard_reg_uses, &this_used); AND_COMPL_HARD_REG_SET (this_used, prologue_clobbered); - IOR_HARD_REG_SET (prologue_used, this_used); + prologue_used |= this_used; note_stores (insn, record_hard_reg_sets, &prologue_clobbered); } CLEAR_HARD_REG_BIT (prologue_clobbered, STACK_POINTER_REGNUM); -- cgit v1.1 From d15e5131845e2a68513230a624839ef5abcda690 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Mon, 9 Sep 2019 17:59:25 +0000 Subject: Remove AND_COMPL_HARD_REG_SET Use "x &= ~y" instead of "AND_COMPL_HARD_REG_SET (x, y)", or just "x & ~y" if the result is a temporary. This means that we're splitting it into two operations, but the compiler should be able to combine them for reasonable values of FIRST_PSEUDO_REGISTER. 2019-09-09 Richard Sandiford gcc/ * hard-reg-set.h (AND_COMPL_HARD_REG_SET): Delete. * caller-save.c (setup_save_areas): Use "&~" instead of AND_COMPL_HARD_REG_SET. (save_call_clobbered_regs): Likewise. * config/epiphany/epiphany.c (epiphany_conditional_register_usage): Likewise. * config/frv/frv.c (frv_ifcvt_modify_tests): Likewise. * config/gcn/gcn.c (gcn_md_reorg): Likewise. * config/i386/i386.c (ix86_conditional_register_usage): Likewise. * config/mips/mips.c (mips_class_max_nregs): Likewise. (mips_conditional_register_usage): Likewise. * config/sh/sh.c (output_stack_adjust): Likewise. * ira-color.c (form_allocno_hard_regs_nodes_forest): Likewise. (setup_profitable_hard_regs): Likewise. (get_conflict_and_start_profitable_regs): Likewise. * ira-conflicts.c (print_allocno_conflicts): Likewise. (ira_build_conflicts): Likewise. * ira-costs.c (restrict_cost_classes): Likewise. (setup_regno_cost_classes_by_aclass): Likewise. * ira-lives.c (process_bb_node_lives): Likewise. * ira.c (setup_class_hard_regs, setup_reg_subclasses): Likewise. (setup_class_subset_and_memory_move_costs, setup_pressure_classes) (setup_allocno_and_important_classes, setup_class_translate_array) (setup_reg_class_relations, setup_prohibited_class_mode_regs): Likewise. * lra-assigns.c (find_hard_regno_for_1): Likewise. * lra-constraints.c (prohibited_class_reg_set_mode_p): Likewise. (process_alt_operands, inherit_in_ebb): Likewise. * lra-eliminations.c (update_reg_eliminate): Likewise. * lra-lives.c (process_bb_lives): Likewise. * reload1.c (update_eliminables_and_spill, reload_as_needed): Likewise. * resource.c (find_dead_or_set_registers): Likewise. (mark_target_live_regs): Likewise. * sched-deps.c (get_implicit_reg_pending_clobbers): Likewise. * sel-sched.c (mark_unavailable_hard_regs): Likewise. (implicit_clobber_conflict_p): Likewise. * shrink-wrap.c (requires_stack_frame_p): Likewise. (try_shrink_wrapping): Likewise. From-SVN: r275532 --- gcc/ChangeLog | 41 ++++++++++++++++++++ gcc/caller-save.c | 14 +++---- gcc/config/epiphany/epiphany.c | 2 +- gcc/config/frv/frv.c | 8 ++-- gcc/config/gcn/gcn.c | 2 +- gcc/config/i386/i386.c | 12 ++---- gcc/config/mips/mips.c | 24 ++++-------- gcc/config/sh/sh.c | 4 +- gcc/hard-reg-set.h | 12 +----- gcc/ira-color.c | 22 +++++------ gcc/ira-conflicts.c | 20 +++++----- gcc/ira-costs.c | 11 ++---- gcc/ira-lives.c | 3 +- gcc/ira.c | 86 ++++++++++++++++++------------------------ gcc/lra-assigns.c | 3 +- gcc/lra-constraints.c | 19 ++++------ gcc/lra-eliminations.c | 2 +- gcc/lra-lives.c | 2 +- gcc/reload1.c | 6 +-- gcc/resource.c | 27 ++++++------- gcc/sched-deps.c | 2 +- gcc/sel-sched.c | 9 ++--- gcc/shrink-wrap.c | 4 +- 23 files changed, 158 insertions(+), 177 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c7a6716..1fc84ae 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,46 @@ 2019-09-09 Richard Sandiford + * hard-reg-set.h (AND_COMPL_HARD_REG_SET): Delete. + * caller-save.c (setup_save_areas): Use "&~" instead of + AND_COMPL_HARD_REG_SET. + (save_call_clobbered_regs): Likewise. + * config/epiphany/epiphany.c (epiphany_conditional_register_usage): + Likewise. + * config/frv/frv.c (frv_ifcvt_modify_tests): Likewise. + * config/gcn/gcn.c (gcn_md_reorg): Likewise. + * config/i386/i386.c (ix86_conditional_register_usage): Likewise. + * config/mips/mips.c (mips_class_max_nregs): Likewise. + (mips_conditional_register_usage): Likewise. + * config/sh/sh.c (output_stack_adjust): Likewise. + * ira-color.c (form_allocno_hard_regs_nodes_forest): Likewise. + (setup_profitable_hard_regs): Likewise. + (get_conflict_and_start_profitable_regs): Likewise. + * ira-conflicts.c (print_allocno_conflicts): Likewise. + (ira_build_conflicts): Likewise. + * ira-costs.c (restrict_cost_classes): Likewise. + (setup_regno_cost_classes_by_aclass): Likewise. + * ira-lives.c (process_bb_node_lives): Likewise. + * ira.c (setup_class_hard_regs, setup_reg_subclasses): Likewise. + (setup_class_subset_and_memory_move_costs, setup_pressure_classes) + (setup_allocno_and_important_classes, setup_class_translate_array) + (setup_reg_class_relations, setup_prohibited_class_mode_regs): + Likewise. + * lra-assigns.c (find_hard_regno_for_1): Likewise. + * lra-constraints.c (prohibited_class_reg_set_mode_p): Likewise. + (process_alt_operands, inherit_in_ebb): Likewise. + * lra-eliminations.c (update_reg_eliminate): Likewise. + * lra-lives.c (process_bb_lives): Likewise. + * reload1.c (update_eliminables_and_spill, reload_as_needed): Likewise. + * resource.c (find_dead_or_set_registers): Likewise. + (mark_target_live_regs): Likewise. + * sched-deps.c (get_implicit_reg_pending_clobbers): Likewise. + * sel-sched.c (mark_unavailable_hard_regs): Likewise. + (implicit_clobber_conflict_p): Likewise. + * shrink-wrap.c (requires_stack_frame_p): Likewise. + (try_shrink_wrapping): Likewise. + +2019-09-09 Richard Sandiford + * hard-reg-set.h (HARD_REG_SET::operator|): New function. (HARD_REG_SET::operator|=): Likewise. (IOR_HARD_REG_SET): Delete. diff --git a/gcc/caller-save.c b/gcc/caller-save.c index b6bcb7b..8c88af9 100644 --- a/gcc/caller-save.c +++ b/gcc/caller-save.c @@ -455,8 +455,7 @@ setup_save_areas (void) if (SIBLING_CALL_P (insn) && crtl->return_rtx) mark_set_regs (crtl->return_rtx, NULL_RTX, &this_insn_sets); - AND_COMPL_HARD_REG_SET (used_regs, call_fixed_reg_set); - AND_COMPL_HARD_REG_SET (used_regs, this_insn_sets); + used_regs &= ~(call_fixed_reg_set | this_insn_sets); hard_regs_to_save &= used_regs; for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) if (TEST_HARD_REG_BIT (hard_regs_to_save, regno)) @@ -540,8 +539,7 @@ setup_save_areas (void) if (SIBLING_CALL_P (insn) && crtl->return_rtx) mark_set_regs (crtl->return_rtx, NULL_RTX, &this_insn_sets); - AND_COMPL_HARD_REG_SET (used_regs, call_fixed_reg_set); - AND_COMPL_HARD_REG_SET (used_regs, this_insn_sets); + used_regs &= ~(call_fixed_reg_set | this_insn_sets); hard_regs_to_save &= used_regs; for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) if (TEST_HARD_REG_BIT (hard_regs_to_save, regno)) @@ -796,7 +794,7 @@ save_call_clobbered_regs (void) afterwards. */ CLEAR_HARD_REG_SET (this_insn_sets); note_stores (insn, mark_set_regs, &this_insn_sets); - AND_COMPL_HARD_REG_SET (hard_regs_saved, this_insn_sets); + hard_regs_saved &= ~this_insn_sets; } if (code == CALL_INSN @@ -852,9 +850,9 @@ save_call_clobbered_regs (void) note_stores (insn, mark_set_regs, &this_insn_sets); /* Compute which hard regs must be saved before this call. */ - AND_COMPL_HARD_REG_SET (hard_regs_to_save, call_fixed_reg_set); - AND_COMPL_HARD_REG_SET (hard_regs_to_save, this_insn_sets); - AND_COMPL_HARD_REG_SET (hard_regs_to_save, hard_regs_saved); + hard_regs_to_save &= ~(call_fixed_reg_set + | this_insn_sets + | hard_regs_saved); get_call_reg_set_usage (insn, &call_def_reg_set, call_used_reg_set); hard_regs_to_save &= call_def_reg_set; diff --git a/gcc/config/epiphany/epiphany.c b/gcc/config/epiphany/epiphany.c index c2e3215..41cd89e 100644 --- a/gcc/config/epiphany/epiphany.c +++ b/gcc/config/epiphany/epiphany.c @@ -2242,7 +2242,7 @@ epiphany_conditional_register_usage (void) CLEAR_HARD_REG_SET (reg_class_contents[SHORT_INSN_REGS]); reg_class_contents[SIBCALL_REGS] = reg_class_contents[GENERAL_REGS]; /* It would be simpler and quicker if we could just use - AND_COMPL_HARD_REG_SET, alas, call_used_reg_set is yet uninitialized; + &~, alas, call_used_reg_set is yet uninitialized; it is set up later by our caller. */ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (!call_used_regs[i]) diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c index 7fc8068..8a1f399 100644 --- a/gcc/config/frv/frv.c +++ b/gcc/config/frv/frv.c @@ -5201,8 +5201,7 @@ frv_ifcvt_modify_tests (ce_if_block *ce_info, rtx *p_true, rtx *p_false) not fixed. However, allow the ICC/ICR temporary registers to be allocated if we did not need to use them in reloading other registers. */ memset (&tmp_reg->regs, 0, sizeof (tmp_reg->regs)); - tmp_reg->regs = call_used_reg_set; - AND_COMPL_HARD_REG_SET (tmp_reg->regs, fixed_reg_set); + tmp_reg->regs = call_used_reg_set &~ fixed_reg_set; SET_HARD_REG_BIT (tmp_reg->regs, ICC_TEMP); SET_HARD_REG_BIT (tmp_reg->regs, ICR_TEMP); @@ -5311,7 +5310,7 @@ frv_ifcvt_modify_tests (ce_if_block *ce_info, rtx *p_true, rtx *p_false) CLEAR_HARD_REG_SET (mentioned_regs); find_all_hard_regs (PATTERN (insn), &mentioned_regs); - AND_COMPL_HARD_REG_SET (tmp_reg->regs, mentioned_regs); + tmp_reg->regs &= ~mentioned_regs; pattern = PATTERN (insn); if (GET_CODE (pattern) == COND_EXEC) @@ -5347,8 +5346,7 @@ frv_ifcvt_modify_tests (ce_if_block *ce_info, rtx *p_true, rtx *p_false) } if (! skip_nested_if) - AND_COMPL_HARD_REG_SET (frv_ifcvt.nested_cc_ok_rewrite, - mentioned_regs); + frv_ifcvt.nested_cc_ok_rewrite &= ~mentioned_regs; } if (insn == last_insn) diff --git a/gcc/config/gcn/gcn.c b/gcc/config/gcn/gcn.c index 8d99eb2..473f6ed 100644 --- a/gcc/config/gcn/gcn.c +++ b/gcc/config/gcn/gcn.c @@ -4628,7 +4628,7 @@ gcn_md_reorg (void) prev_insn->age += 1 + nops_rqd; written |= iwrites; - AND_COMPL_HARD_REG_SET (prev_insn->writes, written); + prev_insn->writes &= ~written; } /* Track the current instruction as a previous instruction. */ diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index f6de6e9..5e68a87 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -497,18 +497,15 @@ ix86_conditional_register_usage (void) /* If MMX is disabled, disable the registers. */ if (! TARGET_MMX) - AND_COMPL_HARD_REG_SET (accessible_reg_set, - reg_class_contents[(int) MMX_REGS]); + accessible_reg_set &= ~reg_class_contents[MMX_REGS]; /* If SSE is disabled, disable the registers. */ if (! TARGET_SSE) - AND_COMPL_HARD_REG_SET (accessible_reg_set, - reg_class_contents[(int) ALL_SSE_REGS]); + accessible_reg_set &= ~reg_class_contents[ALL_SSE_REGS]; /* If the FPU is disabled, disable the registers. */ if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387)) - AND_COMPL_HARD_REG_SET (accessible_reg_set, - reg_class_contents[(int) FLOAT_REGS]); + accessible_reg_set &= ~reg_class_contents[FLOAT_REGS]; /* If AVX512F is disabled, disable the registers. */ if (! TARGET_AVX512F) @@ -516,8 +513,7 @@ ix86_conditional_register_usage (void) for (i = FIRST_EXT_REX_SSE_REG; i <= LAST_EXT_REX_SSE_REG; i++) CLEAR_HARD_REG_BIT (accessible_reg_set, i); - AND_COMPL_HARD_REG_SET (accessible_reg_set, - reg_class_contents[(int) ALL_MASK_REGS]); + accessible_reg_set &= ~reg_class_contents[ALL_MASK_REGS]; } } diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 7150a79..4c61154 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -12981,7 +12981,7 @@ mips_class_max_nregs (enum reg_class rclass, machine_mode mode) if (mips_hard_regno_mode_ok (ST_REG_FIRST, mode)) size = MIN (size, 4); - AND_COMPL_HARD_REG_SET (left, reg_class_contents[(int) ST_REGS]); + left &= ~reg_class_contents[ST_REGS]; } if (hard_reg_set_intersect_p (left, reg_class_contents[(int) FP_REGS])) { @@ -12993,7 +12993,7 @@ mips_class_max_nregs (enum reg_class rclass, machine_mode mode) size = MIN (size, UNITS_PER_FPREG); } - AND_COMPL_HARD_REG_SET (left, reg_class_contents[(int) FP_REGS]); + left &= ~reg_class_contents[FP_REGS]; } if (!hard_reg_set_empty_p (left)) size = MIN (size, UNITS_PER_WORD); @@ -20431,27 +20431,20 @@ mips_conditional_register_usage (void) global_regs[CCDSP_SC_REGNUM] = 1; } else - AND_COMPL_HARD_REG_SET (accessible_reg_set, - reg_class_contents[(int) DSP_ACC_REGS]); + accessible_reg_set &= ~reg_class_contents[DSP_ACC_REGS]; if (!ISA_HAS_HILO) - AND_COMPL_HARD_REG_SET (accessible_reg_set, - reg_class_contents[(int) MD_REGS]); + accessible_reg_set &= ~reg_class_contents[MD_REGS]; if (!TARGET_HARD_FLOAT) - { - AND_COMPL_HARD_REG_SET (accessible_reg_set, - reg_class_contents[(int) FP_REGS]); - AND_COMPL_HARD_REG_SET (accessible_reg_set, - reg_class_contents[(int) ST_REGS]); - } + accessible_reg_set &= ~(reg_class_contents[FP_REGS] + | reg_class_contents[ST_REGS]); else if (!ISA_HAS_8CC) { /* We only have a single condition-code register. We implement this by fixing all the condition-code registers and generating RTL that refers directly to ST_REG_FIRST. */ - AND_COMPL_HARD_REG_SET (accessible_reg_set, - reg_class_contents[(int) ST_REGS]); + accessible_reg_set &= ~reg_class_contents[ST_REGS]; if (!ISA_HAS_CCF) SET_HARD_REG_BIT (accessible_reg_set, FPSW_REGNUM); fixed_regs[FPSW_REGNUM] = call_used_regs[FPSW_REGNUM] = 1; @@ -20493,8 +20486,7 @@ mips_conditional_register_usage (void) /* Do not allow HI and LO to be treated as register operands. There are no MTHI or MTLO instructions (or any real need for them) and one-way registers cannot easily be reloaded. */ - AND_COMPL_HARD_REG_SET (operand_reg_set, - reg_class_contents[(int) MD_REGS]); + operand_reg_set &= ~reg_class_contents[MD_REGS]; } /* $f20-$f23 are call-clobbered for n64. */ if (mips_abi == ABI_64) diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 4b70ac9..7cc8857 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -6707,9 +6707,7 @@ output_stack_adjust (int size, rtx reg, int epilogue_p, temp = -1; if (temp < 0 && ! current_function_interrupt && epilogue_p >= 0) { - HARD_REG_SET temps; - temps = call_used_reg_set; - AND_COMPL_HARD_REG_SET (temps, call_fixed_reg_set); + HARD_REG_SET temps = call_used_reg_set & ~call_fixed_reg_set; if (epilogue_p > 0) { int nreg = 0; diff --git a/gcc/hard-reg-set.h b/gcc/hard-reg-set.h index 3f98e77..7d41162 100644 --- a/gcc/hard-reg-set.h +++ b/gcc/hard-reg-set.h @@ -127,8 +127,8 @@ struct hard_reg_set_container These take just one argument. Also define: - IOR_COMPL_HARD_REG_SET and AND_COMPL_HARD_REG_SET - These take two arguments TO and FROM; they read from FROM + IOR_COMPL_HARD_REG_SET + This takes two arguments TO and FROM; it reads from FROM and combines its complement bitwise into TO. Also define: @@ -153,7 +153,6 @@ struct hard_reg_set_container #define SET_HARD_REG_SET(TO) ((TO) = ~ HARD_CONST (0)) #define IOR_COMPL_HARD_REG_SET(TO, FROM) ((TO) |= ~ (FROM)) -#define AND_COMPL_HARD_REG_SET(TO, FROM) ((TO) &= ~ (FROM)) static inline bool hard_reg_set_subset_p (const_hard_reg_set x, const_hard_reg_set y) @@ -217,13 +216,6 @@ SET_HARD_REG_SET (HARD_REG_SET &set) } inline void -AND_COMPL_HARD_REG_SET (HARD_REG_SET &to, const_hard_reg_set from) -{ - for (unsigned int i = 0; i < ARRAY_SIZE (to.elts); ++i) - to.elts[i] &= ~from.elts[i]; -} - -inline void IOR_COMPL_HARD_REG_SET (HARD_REG_SET &to, const_hard_reg_set from) { for (unsigned int i = 0; i < ARRAY_SIZE (to.elts); ++i) diff --git a/gcc/ira-color.c b/gcc/ira-color.c index 1078ef7..8d68c87 100644 --- a/gcc/ira-color.c +++ b/gcc/ira-color.c @@ -716,8 +716,7 @@ form_allocno_hard_regs_nodes_forest (void) (allocno_data->profitable_hard_regs, ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a))); } - SET_HARD_REG_SET (temp); - AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs); + temp = ~ira_no_alloc_regs; add_allocno_hard_regs (temp, 0); qsort (allocno_hard_regs_vec.address () + start, allocno_hard_regs_vec.length () - start, @@ -1047,8 +1046,8 @@ setup_profitable_hard_regs (void) { ira_object_t obj = ALLOCNO_OBJECT (a, k); - AND_COMPL_HARD_REG_SET (data->profitable_hard_regs, - OBJECT_TOTAL_CONFLICT_HARD_REGS (obj)); + data->profitable_hard_regs + &= ~OBJECT_TOTAL_CONFLICT_HARD_REGS (obj); } } } @@ -1089,9 +1088,8 @@ setup_profitable_hard_regs (void) hard_regno + num); } else - AND_COMPL_HARD_REG_SET - (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs, - ira_reg_mode_hard_regset[hard_regno][mode]); + ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs + &= ~ira_reg_mode_hard_regset[hard_regno][mode]; } } } @@ -1590,12 +1588,10 @@ get_conflict_and_start_profitable_regs (ira_allocno_t a, bool retry_p, conflict_regs[i] = OBJECT_TOTAL_CONFLICT_HARD_REGS (obj); } if (retry_p) - { - *start_profitable_regs = reg_class_contents[ALLOCNO_CLASS (a)]; - AND_COMPL_HARD_REG_SET (*start_profitable_regs, - ira_prohibited_class_mode_regs - [ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]); - } + *start_profitable_regs + = (reg_class_contents[ALLOCNO_CLASS (a)] + &~ (ira_prohibited_class_mode_regs + [ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)])); else *start_profitable_regs = ALLOCNO_COLOR_DATA (a)->profitable_hard_regs; } diff --git a/gcc/ira-conflicts.c b/gcc/ira-conflicts.c index 46ff590..ac8014a 100644 --- a/gcc/ira-conflicts.c +++ b/gcc/ira-conflicts.c @@ -660,15 +660,15 @@ print_allocno_conflicts (FILE * file, bool reg_p, ira_allocno_t a) putc (')', file); } } - conflicting_hard_regs = OBJECT_TOTAL_CONFLICT_HARD_REGS (obj); - AND_COMPL_HARD_REG_SET (conflicting_hard_regs, ira_no_alloc_regs); - conflicting_hard_regs &= reg_class_contents[ALLOCNO_CLASS (a)]; + conflicting_hard_regs = (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) + & ~ira_no_alloc_regs + & reg_class_contents[ALLOCNO_CLASS (a)]); print_hard_reg_set (file, "\n;; total conflict hard regs:", conflicting_hard_regs); - conflicting_hard_regs = OBJECT_CONFLICT_HARD_REGS (obj); - AND_COMPL_HARD_REG_SET (conflicting_hard_regs, ira_no_alloc_regs); - conflicting_hard_regs &= reg_class_contents[ALLOCNO_CLASS (a)]; + conflicting_hard_regs = (OBJECT_CONFLICT_HARD_REGS (obj) + & ~ira_no_alloc_regs + & reg_class_contents[ALLOCNO_CLASS (a)]); print_hard_reg_set (file, ";; conflict hard regs:", conflicting_hard_regs); putc ('\n', file); @@ -738,11 +738,9 @@ ira_build_conflicts (void) if (! targetm.class_likely_spilled_p (base)) CLEAR_HARD_REG_SET (temp_hard_reg_set); else - { - temp_hard_reg_set = reg_class_contents[base]; - AND_COMPL_HARD_REG_SET (temp_hard_reg_set, ira_no_alloc_regs); - temp_hard_reg_set &= call_used_reg_set; - } + temp_hard_reg_set = (reg_class_contents[base] + & ~ira_no_alloc_regs + & call_used_reg_set); FOR_EACH_ALLOCNO (a, ai) { int i, n = ALLOCNO_NUM_OBJECTS (a); diff --git a/gcc/ira-costs.c b/gcc/ira-costs.c index ae94365..5d672ac 100644 --- a/gcc/ira-costs.c +++ b/gcc/ira-costs.c @@ -255,9 +255,8 @@ restrict_cost_classes (cost_classes_t full, machine_mode mode, /* Calculate the set of registers in CL that belong to REGS and are valid for MODE. */ HARD_REG_SET valid_for_cl = reg_class_contents[cl] & regs; - AND_COMPL_HARD_REG_SET (valid_for_cl, - ira_prohibited_class_mode_regs[cl][mode]); - AND_COMPL_HARD_REG_SET (valid_for_cl, ira_no_alloc_regs); + valid_for_cl &= ~(ira_prohibited_class_mode_regs[cl][mode] + | ira_no_alloc_regs); if (hard_reg_set_empty_p (valid_for_cl)) continue; @@ -341,8 +340,7 @@ setup_regno_cost_classes_by_aclass (int regno, enum reg_class aclass) if ((classes_ptr = cost_classes_aclass_cache[aclass]) == NULL) { - temp = reg_class_contents[aclass]; - AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs); + temp = reg_class_contents[aclass] & ~ira_no_alloc_regs; /* We exclude classes from consideration which are subsets of ACLASS only if ACLASS is an uniform class. */ exclude_p = ira_uniform_class_p[aclass]; @@ -354,8 +352,7 @@ setup_regno_cost_classes_by_aclass (int regno, enum reg_class aclass) { /* Exclude non-uniform classes which are subsets of ACLASS. */ - temp2 = reg_class_contents[cl]; - AND_COMPL_HARD_REG_SET (temp2, ira_no_alloc_regs); + temp2 = reg_class_contents[cl] & ~ira_no_alloc_regs; if (hard_reg_set_subset_p (temp2, temp) && cl != aclass) continue; } diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c index e1d502f..6f4012f 100644 --- a/gcc/ira-lives.c +++ b/gcc/ira-lives.c @@ -1129,8 +1129,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) reg_live_out = df_get_live_out (bb); sparseset_clear (objects_live); REG_SET_TO_HARD_REG_SET (hard_regs_live, reg_live_out); - AND_COMPL_HARD_REG_SET (hard_regs_live, eliminable_regset); - AND_COMPL_HARD_REG_SET (hard_regs_live, ira_no_alloc_regs); + hard_regs_live &= ~(eliminable_regset | ira_no_alloc_regs); for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (TEST_HARD_REG_BIT (hard_regs_live, i)) { diff --git a/gcc/ira.c b/gcc/ira.c index 970cf1d..7926ae0 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -471,8 +471,7 @@ setup_class_hard_regs (void) ira_assert (SHRT_MAX >= FIRST_PSEUDO_REGISTER); for (cl = (int) N_REG_CLASSES - 1; cl >= 0; cl--) { - temp_hard_regset = reg_class_contents[cl]; - AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); + temp_hard_regset = reg_class_contents[cl] & ~no_unit_alloc_regs; CLEAR_HARD_REG_SET (processed_hard_reg_set); for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) { @@ -541,8 +540,7 @@ setup_reg_subclasses (void) if (i == (int) NO_REGS) continue; - temp_hard_regset = reg_class_contents[i]; - AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); + temp_hard_regset = reg_class_contents[i] & ~no_unit_alloc_regs; if (hard_reg_set_empty_p (temp_hard_regset)) continue; for (j = 0; j < N_REG_CLASSES; j++) @@ -550,8 +548,7 @@ setup_reg_subclasses (void) { enum reg_class *p; - temp_hard_regset2 = reg_class_contents[j]; - AND_COMPL_HARD_REG_SET (temp_hard_regset2, no_unit_alloc_regs); + temp_hard_regset2 = reg_class_contents[j] & ~no_unit_alloc_regs; if (! hard_reg_set_subset_p (temp_hard_regset, temp_hard_regset2)) continue; @@ -605,10 +602,8 @@ setup_class_subset_and_memory_move_costs (void) for (cl = (int) N_REG_CLASSES - 1; cl >= 0; cl--) for (cl2 = (int) N_REG_CLASSES - 1; cl2 >= 0; cl2--) { - temp_hard_regset = reg_class_contents[cl]; - AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); - temp_hard_regset2 = reg_class_contents[cl2]; - AND_COMPL_HARD_REG_SET (temp_hard_regset2, no_unit_alloc_regs); + temp_hard_regset = reg_class_contents[cl] & ~no_unit_alloc_regs; + temp_hard_regset2 = reg_class_contents[cl2] & ~no_unit_alloc_regs; ira_class_subset_p[cl][cl2] = hard_reg_set_subset_p (temp_hard_regset, temp_hard_regset2); if (! hard_reg_set_empty_p (temp_hard_regset2) @@ -815,10 +810,10 @@ setup_pressure_classes (void) register pressure class. */ for (m = 0; m < NUM_MACHINE_MODES; m++) { - temp_hard_regset = reg_class_contents[cl]; - AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); - AND_COMPL_HARD_REG_SET (temp_hard_regset, - ira_prohibited_class_mode_regs[cl][m]); + temp_hard_regset + = (reg_class_contents[cl] + & ~(no_unit_alloc_regs + | ira_prohibited_class_mode_regs[cl][m])); if (hard_reg_set_empty_p (temp_hard_regset)) continue; ira_init_register_move_cost_if_necessary ((machine_mode) m); @@ -832,8 +827,7 @@ setup_pressure_classes (void) } curr = 0; insert_p = true; - temp_hard_regset = reg_class_contents[cl]; - AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); + temp_hard_regset = reg_class_contents[cl] & ~no_unit_alloc_regs; /* Remove so far added pressure classes which are subset of the current candidate class. Prefer GENERAL_REGS as a pressure register class to another class containing the same @@ -844,8 +838,8 @@ setup_pressure_classes (void) for (i = 0; i < n; i++) { cl2 = pressure_classes[i]; - temp_hard_regset2 = reg_class_contents[cl2]; - AND_COMPL_HARD_REG_SET (temp_hard_regset2, no_unit_alloc_regs); + temp_hard_regset2 = (reg_class_contents[cl2] + & ~no_unit_alloc_regs); if (hard_reg_set_subset_p (temp_hard_regset, temp_hard_regset2) && (! hard_reg_set_equal_p (temp_hard_regset, temp_hard_regset2) @@ -907,8 +901,8 @@ setup_pressure_classes (void) for which no reg class is defined. */ if (REGNO_REG_CLASS (i) == NO_REGS) SET_HARD_REG_BIT (ignore_hard_regs, i); - AND_COMPL_HARD_REG_SET (temp_hard_regset, ignore_hard_regs); - AND_COMPL_HARD_REG_SET (temp_hard_regset2, ignore_hard_regs); + temp_hard_regset &= ~ignore_hard_regs; + temp_hard_regset2 &= ~ignore_hard_regs; ira_assert (hard_reg_set_subset_p (temp_hard_regset2, temp_hard_regset)); } #endif @@ -1000,14 +994,11 @@ setup_allocno_and_important_classes (void) same set of hard registers. */ for (i = 0; i < LIM_REG_CLASSES; i++) { - temp_hard_regset = reg_class_contents[i]; - AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); + temp_hard_regset = reg_class_contents[i] & ~no_unit_alloc_regs; for (j = 0; j < n; j++) { cl = classes[j]; - temp_hard_regset2 = reg_class_contents[cl]; - AND_COMPL_HARD_REG_SET (temp_hard_regset2, - no_unit_alloc_regs); + temp_hard_regset2 = reg_class_contents[cl] & ~no_unit_alloc_regs; if (hard_reg_set_equal_p (temp_hard_regset, temp_hard_regset2)) break; @@ -1036,13 +1027,12 @@ setup_allocno_and_important_classes (void) for (cl = 0; cl < N_REG_CLASSES; cl++) if (ira_class_hard_regs_num[cl] > 0) { - temp_hard_regset = reg_class_contents[cl]; - AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); + temp_hard_regset = reg_class_contents[cl] & ~no_unit_alloc_regs; set_p = false; for (j = 0; j < ira_allocno_classes_num; j++) { - temp_hard_regset2 = reg_class_contents[ira_allocno_classes[j]]; - AND_COMPL_HARD_REG_SET (temp_hard_regset2, no_unit_alloc_regs); + temp_hard_regset2 = (reg_class_contents[ira_allocno_classes[j]] + & ~no_unit_alloc_regs); if ((enum reg_class) cl == ira_allocno_classes[j]) break; else if (hard_reg_set_subset_p (temp_hard_regset, @@ -1117,8 +1107,8 @@ setup_class_translate_array (enum reg_class *class_translate, { aclass = classes[i]; temp_hard_regset = (reg_class_contents[aclass] - & reg_class_contents[cl]); - AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); + & reg_class_contents[cl] + & ~no_unit_alloc_regs); if (! hard_reg_set_empty_p (temp_hard_regset)) { min_cost = INT_MAX; @@ -1220,10 +1210,8 @@ setup_reg_class_relations (void) ira_reg_classes_intersect_p[cl1][cl2] = false; ira_reg_class_intersect[cl1][cl2] = NO_REGS; ira_reg_class_subset[cl1][cl2] = NO_REGS; - temp_hard_regset = reg_class_contents[cl1]; - AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); - temp_set2 = reg_class_contents[cl2]; - AND_COMPL_HARD_REG_SET (temp_set2, no_unit_alloc_regs); + temp_hard_regset = reg_class_contents[cl1] & ~no_unit_alloc_regs; + temp_set2 = reg_class_contents[cl2] & ~no_unit_alloc_regs; if (hard_reg_set_empty_p (temp_hard_regset) && hard_reg_set_empty_p (temp_set2)) { @@ -1262,14 +1250,13 @@ setup_reg_class_relations (void) ira_reg_class_subunion[cl1][cl2] = NO_REGS; ira_reg_class_superunion[cl1][cl2] = NO_REGS; intersection_set = (reg_class_contents[cl1] - & reg_class_contents[cl2]); - AND_COMPL_HARD_REG_SET (intersection_set, no_unit_alloc_regs); - union_set = reg_class_contents[cl1] | reg_class_contents[cl2]; - AND_COMPL_HARD_REG_SET (union_set, no_unit_alloc_regs); + & reg_class_contents[cl2] + & ~no_unit_alloc_regs); + union_set = ((reg_class_contents[cl1] | reg_class_contents[cl2]) + & ~no_unit_alloc_regs); for (cl3 = 0; cl3 < N_REG_CLASSES; cl3++) { - temp_hard_regset = reg_class_contents[cl3]; - AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); + temp_hard_regset = reg_class_contents[cl3] & ~no_unit_alloc_regs; if (hard_reg_set_subset_p (temp_hard_regset, intersection_set)) { /* CL3 allocatable hard register set is inside of @@ -1280,7 +1267,7 @@ setup_reg_class_relations (void) temp_set2 = (reg_class_contents [ira_reg_class_intersect[cl1][cl2]]); - AND_COMPL_HARD_REG_SET (temp_set2, no_unit_alloc_regs); + temp_set2 &= ~no_unit_alloc_regs; if (! hard_reg_set_subset_p (temp_hard_regset, temp_set2) /* If the allocatable hard register sets are the same, prefer GENERAL_REGS or the @@ -1298,8 +1285,8 @@ setup_reg_class_relations (void) ira_reg_class_intersect[cl1][cl2] = (enum reg_class) cl3; } temp_set2 - = reg_class_contents[ira_reg_class_subset[cl1][cl2]]; - AND_COMPL_HARD_REG_SET (temp_set2, no_unit_alloc_regs); + = (reg_class_contents[ira_reg_class_subset[cl1][cl2]] + & ~no_unit_alloc_regs); if (! hard_reg_set_subset_p (temp_hard_regset, temp_set2) /* Ignore unavailable hard registers and prefer smallest class for debugging purposes. */ @@ -1317,8 +1304,8 @@ setup_reg_class_relations (void) union of allocatable hard register sets of CL1 and CL2. */ temp_set2 - = reg_class_contents[ira_reg_class_subunion[cl1][cl2]]; - AND_COMPL_HARD_REG_SET (temp_set2, no_unit_alloc_regs); + = (reg_class_contents[ira_reg_class_subunion[cl1][cl2]] + & ~no_unit_alloc_regs); if (ira_reg_class_subunion[cl1][cl2] == NO_REGS || (hard_reg_set_subset_p (temp_set2, temp_hard_regset) @@ -1341,8 +1328,8 @@ setup_reg_class_relations (void) of allocatable hard register sets of CL1 and CL2. */ temp_set2 - = reg_class_contents[ira_reg_class_superunion[cl1][cl2]]; - AND_COMPL_HARD_REG_SET (temp_set2, no_unit_alloc_regs); + = (reg_class_contents[ira_reg_class_superunion[cl1][cl2]] + & ~no_unit_alloc_regs); if (ira_reg_class_superunion[cl1][cl2] == NO_REGS || (hard_reg_set_subset_p (temp_hard_regset, temp_set2) @@ -1491,8 +1478,7 @@ setup_prohibited_class_mode_regs (void) for (cl = (int) N_REG_CLASSES - 1; cl >= 0; cl--) { - temp_hard_regset = reg_class_contents[cl]; - AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs); + temp_hard_regset = reg_class_contents[cl] & ~no_unit_alloc_regs; for (j = 0; j < NUM_MACHINE_MODES; j++) { count = 0; diff --git a/gcc/lra-assigns.c b/gcc/lra-assigns.c index ce6b07b..c2244f5 100644 --- a/gcc/lra-assigns.c +++ b/gcc/lra-assigns.c @@ -619,8 +619,7 @@ find_hard_regno_for_1 (int regno, int *cost, int try_only_hard_regno, biggest_nregs = hard_regno_nregs (hard_regno, biggest_mode); nregs_diff = (biggest_nregs - hard_regno_nregs (hard_regno, PSEUDO_REGNO_MODE (regno))); - available_regs = reg_class_contents[rclass]; - AND_COMPL_HARD_REG_SET (available_regs, lra_no_alloc_regs); + available_regs = reg_class_contents[rclass] & ~lra_no_alloc_regs; for (i = 0; i < rclass_size; i++) { if (try_only_hard_regno >= 0) diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index d4eea85..16d96c5 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -1854,8 +1854,7 @@ prohibited_class_reg_set_mode_p (enum reg_class rclass, HARD_REG_SET temp; lra_assert (hard_reg_set_subset_p (reg_class_contents[rclass], set)); - temp = set; - AND_COMPL_HARD_REG_SET (temp, lra_no_alloc_regs); + temp = set & ~lra_no_alloc_regs; return (hard_reg_set_subset_p (temp, ira_prohibited_class_mode_regs[rclass][mode])); } @@ -2513,13 +2512,11 @@ process_alt_operands (int only_alternative) if (this_alternative != NO_REGS) { - HARD_REG_SET available_regs; - - available_regs = reg_class_contents[this_alternative]; - AND_COMPL_HARD_REG_SET - (available_regs, - ira_prohibited_class_mode_regs[this_alternative][mode]); - AND_COMPL_HARD_REG_SET (available_regs, lra_no_alloc_regs); + HARD_REG_SET available_regs + = (reg_class_contents[this_alternative] + & ~((ira_prohibited_class_mode_regs + [this_alternative][mode]) + | lra_no_alloc_regs)); if (hard_reg_set_empty_p (available_regs)) { /* There are no hard regs holding a value of given @@ -6407,8 +6404,8 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail) else add_to_hard_reg_set (&s, PSEUDO_REGNO_MODE (dst_regno), reg_renumber[dst_regno]); - AND_COMPL_HARD_REG_SET (live_hard_regs, s); - AND_COMPL_HARD_REG_SET (potential_reload_hard_regs, s); + live_hard_regs &= ~s; + potential_reload_hard_regs &= ~s; } /* We should invalidate potential inheritance or splitting for the current insn usages to the next diff --git a/gcc/lra-eliminations.c b/gcc/lra-eliminations.c index 7e5fbe3..749834e 100644 --- a/gcc/lra-eliminations.c +++ b/gcc/lra-eliminations.c @@ -1203,7 +1203,7 @@ update_reg_eliminate (bitmap insns_with_changed_offsets) } } lra_no_alloc_regs |= temp_hard_reg_set; - AND_COMPL_HARD_REG_SET (eliminable_regset, temp_hard_reg_set); + eliminable_regset &= ~temp_hard_reg_set; spill_pseudos (temp_hard_reg_set); return result; } diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c index e046817..e1674b5 100644 --- a/gcc/lra-lives.c +++ b/gcc/lra-lives.c @@ -671,7 +671,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) sparseset_clear (pseudos_live_through_setjumps); CLEAR_HARD_REG_SET (last_call_used_reg_set); REG_SET_TO_HARD_REG_SET (hard_regs_live, reg_live_out); - AND_COMPL_HARD_REG_SET (hard_regs_live, eliminable_regset); + hard_regs_live &= ~eliminable_regset; EXECUTE_IF_SET_IN_BITMAP (reg_live_out, FIRST_PSEUDO_REGISTER, j, bi) { update_pseudo_point (j, curr_point, USE_POINT); diff --git a/gcc/reload1.c b/gcc/reload1.c index 6c95c9c..90cee06 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -3929,7 +3929,7 @@ update_eliminables_and_spill (void) HARD_REG_SET to_spill; CLEAR_HARD_REG_SET (to_spill); update_eliminables (&to_spill); - AND_COMPL_HARD_REG_SET (used_spill_regs, to_spill); + used_spill_regs &= ~to_spill; for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (TEST_HARD_REG_BIT (to_spill, i)) @@ -4783,8 +4783,8 @@ reload_as_needed (int live_known) be partially clobbered by the call. */ else if (CALL_P (insn)) { - AND_COMPL_HARD_REG_SET (reg_reloaded_valid, call_used_reg_set); - AND_COMPL_HARD_REG_SET (reg_reloaded_valid, reg_reloaded_call_part_clobbered); + reg_reloaded_valid &= ~(call_used_reg_set + | reg_reloaded_call_part_clobbered); /* If this is a call to a setjmp-type function, we must not reuse any reload reg contents across the call; that will diff --git a/gcc/resource.c b/gcc/resource.c index f13956b..2d30e08 100644 --- a/gcc/resource.c +++ b/gcc/resource.c @@ -450,8 +450,8 @@ find_dead_or_set_registers (rtx_insn *target, struct resources *res, case CODE_LABEL: /* After a label, any pending dead registers that weren't yet used can be made dead. */ - AND_COMPL_HARD_REG_SET (pending_dead_regs, needed.regs); - AND_COMPL_HARD_REG_SET (res->regs, pending_dead_regs); + pending_dead_regs &= ~needed.regs; + res->regs &= ~pending_dead_regs; CLEAR_HARD_REG_SET (pending_dead_regs); continue; @@ -565,14 +565,12 @@ find_dead_or_set_registers (rtx_insn *target, struct resources *res, } target_res = *res; - scratch = target_set.regs; - AND_COMPL_HARD_REG_SET (scratch, needed.regs); - AND_COMPL_HARD_REG_SET (target_res.regs, scratch); + scratch = target_set.regs & ~needed.regs; + target_res.regs &= ~scratch; fallthrough_res = *res; - scratch = set.regs; - AND_COMPL_HARD_REG_SET (scratch, needed.regs); - AND_COMPL_HARD_REG_SET (fallthrough_res.regs, scratch); + scratch = set.regs & ~needed.regs; + fallthrough_res.regs &= ~scratch; if (!ANY_RETURN_P (this_jump_insn->jump_label ())) find_dead_or_set_registers @@ -601,9 +599,8 @@ find_dead_or_set_registers (rtx_insn *target, struct resources *res, mark_referenced_resources (insn, &needed, true); mark_set_resources (insn, &set, 0, MARK_SRC_DEST_CALL); - scratch = set.regs; - AND_COMPL_HARD_REG_SET (scratch, needed.regs); - AND_COMPL_HARD_REG_SET (res->regs, scratch); + scratch = set.regs & ~needed.regs; + res->regs &= ~scratch; } return jump_insn; @@ -1048,8 +1045,7 @@ mark_target_live_regs (rtx_insn *insns, rtx target_maybe_return, struct resource /* CALL clobbers all call-used regs that aren't fixed except sp, ap, and fp. Do this before setting the result of the call live. */ - AND_COMPL_HARD_REG_SET (current_live_regs, - regs_invalidated_by_this_call); + current_live_regs &= ~regs_invalidated_by_this_call; } /* A CALL_INSN sets any global register live, since it may @@ -1097,7 +1093,7 @@ mark_target_live_regs (rtx_insn *insns, rtx target_maybe_return, struct resource /* A label clobbers the pending dead registers since neither reload nor jump will propagate a value across a label. */ - AND_COMPL_HARD_REG_SET (current_live_regs, pending_dead_regs); + current_live_regs &= ~pending_dead_regs; CLEAR_HARD_REG_SET (pending_dead_regs); /* We must conservatively assume that all registers that used @@ -1160,8 +1156,7 @@ mark_target_live_regs (rtx_insn *insns, rtx target_maybe_return, struct resource { mark_referenced_resources (insn, &needed, true); - scratch = needed.regs; - AND_COMPL_HARD_REG_SET (scratch, set.regs); + scratch = needed.regs & ~set.regs; new_resources.regs |= scratch; mark_set_resources (insn, &set, 0, MARK_SRC_DEST_CALL); diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c index 8031d72..36a6669 100644 --- a/gcc/sched-deps.c +++ b/gcc/sched-deps.c @@ -2885,7 +2885,7 @@ get_implicit_reg_pending_clobbers (HARD_REG_SET *temp, rtx_insn *insn) preprocess_constraints (insn); alternative_mask preferred = get_preferred_alternatives (insn); ira_implicitly_set_insn_hard_regs (temp, preferred); - AND_COMPL_HARD_REG_SET (*temp, ira_no_alloc_regs); + *temp &= ~ira_no_alloc_regs; } /* Analyze an INSN with pattern X to find all dependencies. */ diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c index e5b825a..9447b92 100644 --- a/gcc/sel-sched.c +++ b/gcc/sel-sched.c @@ -1248,8 +1248,8 @@ mark_unavailable_hard_regs (def_t def, struct reg_rename *reg_rename_p, /* Exclude registers that are partially call clobbered. */ if (def->crosses_call && !targetm.hard_regno_call_part_clobbered (NULL, regno, mode)) - AND_COMPL_HARD_REG_SET (reg_rename_p->available_for_renaming, - sel_hrd.regs_for_call_clobbered[mode]); + reg_rename_p->available_for_renaming + &= ~sel_hrd.regs_for_call_clobbered[mode]; /* Leave only those that are ok to rename. */ EXECUTE_IF_SET_IN_HARD_REG_SET (reg_rename_p->available_for_renaming, @@ -1270,8 +1270,7 @@ mark_unavailable_hard_regs (def_t def, struct reg_rename *reg_rename_p, cur_reg); } - AND_COMPL_HARD_REG_SET (reg_rename_p->available_for_renaming, - reg_rename_p->unavailable_hard_regs); + reg_rename_p->available_for_renaming &= ~reg_rename_p->unavailable_hard_regs; /* Regno is always ok from the renaming part of view, but it really could be in *unavailable_hard_regs already, so set it here instead @@ -2105,7 +2104,7 @@ implicit_clobber_conflict_p (insn_t through_insn, expr_t expr) preprocess_constraints (insn); alternative_mask prefrred = get_preferred_alternatives (insn); ira_implicitly_set_insn_hard_regs (&temp, prefrred); - AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs); + temp &= ~ira_no_alloc_regs; /* If any implicit clobber registers intersect with regular ones in through_insn, we have a dependency and thus bail out. */ diff --git a/gcc/shrink-wrap.c b/gcc/shrink-wrap.c index bf6d045..f1af1cb 100644 --- a/gcc/shrink-wrap.c +++ b/gcc/shrink-wrap.c @@ -76,7 +76,7 @@ requires_stack_frame_p (rtx_insn *insn, HARD_REG_SET prologue_used, } if (hard_reg_set_intersect_p (hardregs, prologue_used)) return true; - AND_COMPL_HARD_REG_SET (hardregs, call_used_reg_set); + hardregs &= ~call_used_reg_set; for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) if (TEST_HARD_REG_BIT (hardregs, regno) && df_regs_ever_live_p (regno)) @@ -687,7 +687,7 @@ try_shrink_wrapping (edge *entry_edge, rtx_insn *prologue_seq) HARD_REG_SET this_used; CLEAR_HARD_REG_SET (this_used); note_uses (&PATTERN (insn), record_hard_reg_uses, &this_used); - AND_COMPL_HARD_REG_SET (this_used, prologue_clobbered); + this_used &= ~prologue_clobbered; prologue_used |= this_used; note_stores (insn, record_hard_reg_sets, &prologue_clobbered); } -- cgit v1.1 From 4897c5aaa7a5db4c1ece28ef66acb3d5e41787b3 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Mon, 9 Sep 2019 17:59:29 +0000 Subject: Remove IOR_COMPL_HARD_REG_SET Use "x |= ~y" instead of "IOR_COMPL_HARD_REG_SET (x, y)", or just "x | ~y" if the result is a temporary. 2019-09-09 Richard Sandiford gcc/ * hard-reg-set.h (IOR_COMPL_HARD_REG_SET): Delete. * config/aarch64/cortex-a57-fma-steering.c (rename_single_chain): Use "|~" instead of IOR_COMPL_HARD_REG_SET. * config/aarch64/falkor-tag-collision-avoidance.c (init_unavailable): Likewise. * ira-build.c (ira_create_object, ira_set_allocno_class): Likewise. * ira.c (setup_reg_renumber): Likewise. * lra-assigns.c (find_hard_regno_for_1): Likewise. * regrename.c (regrename_find_superclass): Likewise. * reload1.c (find_reg): Likewise. From-SVN: r275533 --- gcc/ChangeLog | 13 +++++++++++++ gcc/config/aarch64/cortex-a57-fma-steering.c | 2 +- gcc/config/aarch64/falkor-tag-collision-avoidance.c | 2 +- gcc/hard-reg-set.h | 14 -------------- gcc/ira-build.c | 12 ++++-------- gcc/ira.c | 4 ++-- gcc/lra-assigns.c | 2 +- gcc/regrename.c | 3 +-- gcc/reload1.c | 5 +++-- 9 files changed, 26 insertions(+), 31 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1fc84ae..5a97cb9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,18 @@ 2019-09-09 Richard Sandiford + * hard-reg-set.h (IOR_COMPL_HARD_REG_SET): Delete. + * config/aarch64/cortex-a57-fma-steering.c (rename_single_chain): + Use "|~" instead of IOR_COMPL_HARD_REG_SET. + * config/aarch64/falkor-tag-collision-avoidance.c (init_unavailable): + Likewise. + * ira-build.c (ira_create_object, ira_set_allocno_class): Likewise. + * ira.c (setup_reg_renumber): Likewise. + * lra-assigns.c (find_hard_regno_for_1): Likewise. + * regrename.c (regrename_find_superclass): Likewise. + * reload1.c (find_reg): Likewise. + +2019-09-09 Richard Sandiford + * hard-reg-set.h (AND_COMPL_HARD_REG_SET): Delete. * caller-save.c (setup_save_areas): Use "&~" instead of AND_COMPL_HARD_REG_SET. diff --git a/gcc/config/aarch64/cortex-a57-fma-steering.c b/gcc/config/aarch64/cortex-a57-fma-steering.c index eb91662..3e890ad 100644 --- a/gcc/config/aarch64/cortex-a57-fma-steering.c +++ b/gcc/config/aarch64/cortex-a57-fma-steering.c @@ -267,7 +267,7 @@ rename_single_chain (du_head_p head, HARD_REG_SET *unavailable) if (DEBUG_INSN_P (tmp->insn)) continue; n_uses++; - IOR_COMPL_HARD_REG_SET (*unavailable, reg_class_contents[tmp->cl]); + *unavailable |= ~reg_class_contents[tmp->cl]; super_class = reg_class_superunion[(int) super_class][(int) tmp->cl]; } diff --git a/gcc/config/aarch64/falkor-tag-collision-avoidance.c b/gcc/config/aarch64/falkor-tag-collision-avoidance.c index 779dee8..9faed40 100644 --- a/gcc/config/aarch64/falkor-tag-collision-avoidance.c +++ b/gcc/config/aarch64/falkor-tag-collision-avoidance.c @@ -229,7 +229,7 @@ init_unavailable (tag_insn_info *insn_info, tag_map_t &tag_map, du_head_p head, if (DEBUG_INSN_P (tmp->insn)) continue; - IOR_COMPL_HARD_REG_SET (*unavailable, reg_class_contents[tmp->cl]); + *unavailable |= ~reg_class_contents[tmp->cl]; super_class = reg_class_superunion[(int) super_class][(int) tmp->cl]; } diff --git a/gcc/hard-reg-set.h b/gcc/hard-reg-set.h index 7d41162..793b869 100644 --- a/gcc/hard-reg-set.h +++ b/gcc/hard-reg-set.h @@ -127,11 +127,6 @@ struct hard_reg_set_container These take just one argument. Also define: - IOR_COMPL_HARD_REG_SET - This takes two arguments TO and FROM; it reads from FROM - and combines its complement bitwise into TO. - - Also define: hard_reg_set_subset_p (X, Y), which returns true if X is a subset of Y. hard_reg_set_equal_p (X, Y), which returns true if X and Y are equal. @@ -152,8 +147,6 @@ struct hard_reg_set_container #define CLEAR_HARD_REG_SET(TO) ((TO) = HARD_CONST (0)) #define SET_HARD_REG_SET(TO) ((TO) = ~ HARD_CONST (0)) -#define IOR_COMPL_HARD_REG_SET(TO, FROM) ((TO) |= ~ (FROM)) - static inline bool hard_reg_set_subset_p (const_hard_reg_set x, const_hard_reg_set y) { @@ -215,13 +208,6 @@ SET_HARD_REG_SET (HARD_REG_SET &set) set.elts[i] = -1; } -inline void -IOR_COMPL_HARD_REG_SET (HARD_REG_SET &to, const_hard_reg_set from) -{ - for (unsigned int i = 0; i < ARRAY_SIZE (to.elts); ++i) - to.elts[i] |= ~from.elts[i]; -} - static inline bool hard_reg_set_subset_p (const_hard_reg_set x, const_hard_reg_set y) { diff --git a/gcc/ira-build.c b/gcc/ira-build.c index 354f989..3170d7d 100644 --- a/gcc/ira-build.c +++ b/gcc/ira-build.c @@ -458,10 +458,8 @@ ira_create_object (ira_allocno_t a, int subword) OBJECT_NUM_CONFLICTS (obj) = 0; OBJECT_CONFLICT_HARD_REGS (obj) = ira_no_alloc_regs; OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) = ira_no_alloc_regs; - IOR_COMPL_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), - reg_class_contents[aclass]); - IOR_COMPL_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), - reg_class_contents[aclass]); + OBJECT_CONFLICT_HARD_REGS (obj) |= ~reg_class_contents[aclass]; + OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= ~reg_class_contents[aclass]; OBJECT_MIN (obj) = INT_MAX; OBJECT_MAX (obj) = -1; OBJECT_LIVE_RANGES (obj) = NULL; @@ -549,10 +547,8 @@ ira_set_allocno_class (ira_allocno_t a, enum reg_class aclass) ALLOCNO_CLASS (a) = aclass; FOR_EACH_ALLOCNO_OBJECT (a, obj, oi) { - IOR_COMPL_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), - reg_class_contents[aclass]); - IOR_COMPL_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), - reg_class_contents[aclass]); + OBJECT_CONFLICT_HARD_REGS (obj) |= ~reg_class_contents[aclass]; + OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= ~reg_class_contents[aclass]; } } diff --git a/gcc/ira.c b/gcc/ira.c index 7926ae0..344275a 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -2370,8 +2370,8 @@ setup_reg_renumber (void) for (i = 0; i < nwords; i++) { obj = ALLOCNO_OBJECT (a, i); - IOR_COMPL_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), - reg_class_contents[pclass]); + OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) + |= ~reg_class_contents[pclass]; } if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0 && ira_hard_reg_set_intersection_p (hard_regno, ALLOCNO_MODE (a), diff --git a/gcc/lra-assigns.c b/gcc/lra-assigns.c index c2244f5..0a34ea9 100644 --- a/gcc/lra-assigns.c +++ b/gcc/lra-assigns.c @@ -611,7 +611,7 @@ find_hard_regno_for_1 (int regno, int *cost, int try_only_hard_regno, } /* Make sure that all registers in a multi-word pseudo belong to the required class. */ - IOR_COMPL_HARD_REG_SET (conflict_set, reg_class_contents[rclass]); + conflict_set |= ~reg_class_contents[rclass]; lra_assert (rclass != NO_REGS); rclass_size = ira_class_hard_regs_num[rclass]; best_hard_regno = -1; diff --git a/gcc/regrename.c b/gcc/regrename.c index c28023e..d83e1e9 100644 --- a/gcc/regrename.c +++ b/gcc/regrename.c @@ -441,8 +441,7 @@ regrename_find_superclass (du_head_p head, int *pn_uses, if (DEBUG_INSN_P (tmp->insn)) continue; n_uses++; - IOR_COMPL_HARD_REG_SET (*punavailable, - reg_class_contents[tmp->cl]); + *punavailable |= ~reg_class_contents[tmp->cl]; super_class = reg_class_superunion[(int) super_class][(int) tmp->cl]; } diff --git a/gcc/reload1.c b/gcc/reload1.c index 90cee06..3c23e6e 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -1823,8 +1823,9 @@ find_reg (class insn_chain *chain, int order) static int regno_pseudo_regs[FIRST_PSEUDO_REGISTER]; static int best_regno_pseudo_regs[FIRST_PSEUDO_REGISTER]; - not_usable = bad_spill_regs | bad_spill_regs_global; - IOR_COMPL_HARD_REG_SET (not_usable, reg_class_contents[rl->rclass]); + not_usable = (bad_spill_regs + | bad_spill_regs_global + | ~reg_class_contents[rl->rclass]); CLEAR_HARD_REG_SET (used_by_other_reload); for (k = 0; k < order; k++) -- cgit v1.1 From a85796511b2b7985f79331c996761f7a87cb8116 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Mon, 9 Sep 2019 17:59:41 +0000 Subject: Remove hard_reg_set_equal_p Use "x == y" instead of "hard_reg_set_equal_p (x, y)". 2019-09-09 Richard Sandiford gcc/ * hard-reg-set.h (HARD_REG_SET::operator==): New function. (HARD_REG_SET::operator!=): Likewise. (hard_reg_set_equal_p): Delete. * cfgcleanup.c (old_insns_match_p): Use == instead of hard_reg_set_equal_p and != instead of !hard_reg_set_equal_p. * ira-color.c (allocno_hard_regs_hasher::equal): Likewise. (add_allocno_hard_regs_to_forest): Likewise. (setup_allocno_available_regs_num): Likewise. * ira.c (setup_pressure_classes): Likewise. (setup_allocno_and_important_classes): Likewise. (setup_reg_class_relations): Likewise. * lra-lives.c (process_bb_lives): Likewise. * reg-stack.c (change_stack, convert_regs_1): Likewise. From-SVN: r275534 --- gcc/ChangeLog | 16 ++++++++++++++++ gcc/cfgcleanup.c | 4 ++-- gcc/hard-reg-set.h | 31 +++++++++++++++---------------- gcc/ira-color.c | 7 +++---- gcc/ira.c | 21 ++++++++------------- gcc/lra-lives.c | 4 ++-- gcc/reg-stack.c | 5 ++--- 7 files changed, 48 insertions(+), 40 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5a97cb9..8c791dd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,21 @@ 2019-09-09 Richard Sandiford + * hard-reg-set.h (HARD_REG_SET::operator==): New function. + (HARD_REG_SET::operator!=): Likewise. + (hard_reg_set_equal_p): Delete. + * cfgcleanup.c (old_insns_match_p): Use == instead of + hard_reg_set_equal_p and != instead of !hard_reg_set_equal_p. + * ira-color.c (allocno_hard_regs_hasher::equal): Likewise. + (add_allocno_hard_regs_to_forest): Likewise. + (setup_allocno_available_regs_num): Likewise. + * ira.c (setup_pressure_classes): Likewise. + (setup_allocno_and_important_classes): Likewise. + (setup_reg_class_relations): Likewise. + * lra-lives.c (process_bb_lives): Likewise. + * reg-stack.c (change_stack, convert_regs_1): Likewise. + +2019-09-09 Richard Sandiford + * hard-reg-set.h (IOR_COMPL_HARD_REG_SET): Delete. * config/aarch64/cortex-a57-fma-steering.c (rename_single_chain): Use "|~" instead of IOR_COMPL_HARD_REG_SET. diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c index b930763..baa3809 100644 --- a/gcc/cfgcleanup.c +++ b/gcc/cfgcleanup.c @@ -1231,7 +1231,7 @@ old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx_insn *i1, rtx_insn *i2) get_call_reg_set_usage (i1, &i1_used, call_used_reg_set); get_call_reg_set_usage (i2, &i2_used, call_used_reg_set); - if (!hard_reg_set_equal_p (i1_used, i2_used)) + if (i1_used != i2_used) return dir_none; } @@ -1265,7 +1265,7 @@ old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx_insn *i1, rtx_insn *i2) if (REG_NOTE_KIND (note) == REG_DEAD && STACK_REG_P (XEXP (note, 0))) SET_HARD_REG_BIT (i2_regset, REGNO (XEXP (note, 0))); - if (!hard_reg_set_equal_p (i1_regset, i2_regset)) + if (i1_regset != i2_regset) return dir_none; } #endif diff --git a/gcc/hard-reg-set.h b/gcc/hard-reg-set.h index 793b869..e59779d 100644 --- a/gcc/hard-reg-set.h +++ b/gcc/hard-reg-set.h @@ -96,6 +96,21 @@ struct HARD_REG_SET return *this; } + bool + operator== (const HARD_REG_SET &other) const + { + HARD_REG_ELT_TYPE bad = 0; + for (unsigned int i = 0; i < ARRAY_SIZE (elts); ++i) + bad |= (elts[i] ^ other.elts[i]); + return bad == 0; + } + + bool + operator!= (const HARD_REG_SET &other) const + { + return !operator== (other); + } + HARD_REG_ELT_TYPE elts[HARD_REG_SET_LONGS]; }; typedef const HARD_REG_SET &const_hard_reg_set; @@ -129,7 +144,6 @@ struct hard_reg_set_container Also define: hard_reg_set_subset_p (X, Y), which returns true if X is a subset of Y. - hard_reg_set_equal_p (X, Y), which returns true if X and Y are equal. hard_reg_set_intersect_p (X, Y), which returns true if X and Y intersect. hard_reg_set_empty_p (X), which returns true if X is empty. */ @@ -154,12 +168,6 @@ hard_reg_set_subset_p (const_hard_reg_set x, const_hard_reg_set y) } static inline bool -hard_reg_set_equal_p (const_hard_reg_set x, const_hard_reg_set y) -{ - return x == y; -} - -static inline bool hard_reg_set_intersect_p (const_hard_reg_set x, const_hard_reg_set y) { return (x & y) != HARD_CONST (0); @@ -218,15 +226,6 @@ hard_reg_set_subset_p (const_hard_reg_set x, const_hard_reg_set y) } static inline bool -hard_reg_set_equal_p (const_hard_reg_set x, const_hard_reg_set y) -{ - HARD_REG_ELT_TYPE bad = 0; - for (unsigned int i = 0; i < ARRAY_SIZE (x.elts); ++i) - bad |= (x.elts[i] ^ y.elts[i]); - return bad == 0; -} - -static inline bool hard_reg_set_intersect_p (const_hard_reg_set x, const_hard_reg_set y) { HARD_REG_ELT_TYPE good = 0; diff --git a/gcc/ira-color.c b/gcc/ira-color.c index 8d68c87..eee9e0b 100644 --- a/gcc/ira-color.c +++ b/gcc/ira-color.c @@ -218,7 +218,7 @@ inline bool allocno_hard_regs_hasher::equal (const allocno_hard_regs *hv1, const allocno_hard_regs *hv2) { - return hard_reg_set_equal_p (hv1->set, hv2->set); + return hv1->set == hv2->set; } /* Hash table of unique allocno hard registers. */ @@ -371,7 +371,7 @@ add_allocno_hard_regs_to_forest (allocno_hard_regs_node_t *roots, start = hard_regs_node_vec.length (); for (node = *roots; node != NULL; node = node->next) { - if (hard_reg_set_equal_p (hv->set, node->hard_regs->set)) + if (hv->set == node->hard_regs->set) return; if (hard_reg_set_subset_p (hv->set, node->hard_regs->set)) { @@ -2688,8 +2688,7 @@ setup_allocno_available_regs_num (ira_allocno_t a) reg_class_names[aclass], ira_class_hard_regs_num[aclass], n); print_hard_reg_set (ira_dump_file, data->profitable_hard_regs, false); fprintf (ira_dump_file, ", %snode: ", - hard_reg_set_equal_p (data->profitable_hard_regs, - data->hard_regs_node->hard_regs->set) + data->profitable_hard_regs == data->hard_regs_node->hard_regs->set ? "" : "^"); print_hard_reg_set (ira_dump_file, data->hard_regs_node->hard_regs->set, false); diff --git a/gcc/ira.c b/gcc/ira.c index 344275a..029d690 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -841,8 +841,7 @@ setup_pressure_classes (void) temp_hard_regset2 = (reg_class_contents[cl2] & ~no_unit_alloc_regs); if (hard_reg_set_subset_p (temp_hard_regset, temp_hard_regset2) - && (! hard_reg_set_equal_p (temp_hard_regset, - temp_hard_regset2) + && (temp_hard_regset != temp_hard_regset2 || cl2 == (int) GENERAL_REGS)) { pressure_classes[curr++] = (enum reg_class) cl2; @@ -850,11 +849,10 @@ setup_pressure_classes (void) continue; } if (hard_reg_set_subset_p (temp_hard_regset2, temp_hard_regset) - && (! hard_reg_set_equal_p (temp_hard_regset2, - temp_hard_regset) + && (temp_hard_regset2 != temp_hard_regset || cl == (int) GENERAL_REGS)) continue; - if (hard_reg_set_equal_p (temp_hard_regset2, temp_hard_regset)) + if (temp_hard_regset2 == temp_hard_regset) insert_p = false; pressure_classes[curr++] = (enum reg_class) cl2; } @@ -999,8 +997,7 @@ setup_allocno_and_important_classes (void) { cl = classes[j]; temp_hard_regset2 = reg_class_contents[cl] & ~no_unit_alloc_regs; - if (hard_reg_set_equal_p (temp_hard_regset, - temp_hard_regset2)) + if (temp_hard_regset == temp_hard_regset2) break; } if (j >= n || targetm.additional_allocno_class_p (i)) @@ -1273,7 +1270,7 @@ setup_reg_class_relations (void) the same, prefer GENERAL_REGS or the smallest class for debugging purposes. */ - || (hard_reg_set_equal_p (temp_hard_regset, temp_set2) + || (temp_hard_regset == temp_set2 && (cl3 == GENERAL_REGS || ((ira_reg_class_intersect[cl1][cl2] != GENERAL_REGS) @@ -1290,7 +1287,7 @@ setup_reg_class_relations (void) if (! hard_reg_set_subset_p (temp_hard_regset, temp_set2) /* Ignore unavailable hard registers and prefer smallest class for debugging purposes. */ - || (hard_reg_set_equal_p (temp_hard_regset, temp_set2) + || (temp_hard_regset == temp_set2 && hard_reg_set_subset_p (reg_class_contents[cl3], reg_class_contents @@ -1309,8 +1306,7 @@ setup_reg_class_relations (void) if (ira_reg_class_subunion[cl1][cl2] == NO_REGS || (hard_reg_set_subset_p (temp_set2, temp_hard_regset) - && (! hard_reg_set_equal_p (temp_set2, - temp_hard_regset) + && (temp_set2 != temp_hard_regset || cl3 == GENERAL_REGS /* If the allocatable hard register sets are the same, prefer GENERAL_REGS or the smallest @@ -1333,8 +1329,7 @@ setup_reg_class_relations (void) if (ira_reg_class_superunion[cl1][cl2] == NO_REGS || (hard_reg_set_subset_p (temp_hard_regset, temp_set2) - && (! hard_reg_set_equal_p (temp_set2, - temp_hard_regset) + && (temp_set2 != temp_hard_regset || cl3 == GENERAL_REGS /* If the allocatable hard register sets are the same, prefer GENERAL_REGS or the smallest diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c index e1674b5..0bdba39 100644 --- a/gcc/lra-lives.c +++ b/gcc/lra-lives.c @@ -936,8 +936,8 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) call_used_reg_set); bool flush = (! hard_reg_set_empty_p (last_call_used_reg_set) - && ( ! hard_reg_set_equal_p (last_call_used_reg_set, - this_call_used_reg_set))) + && (last_call_used_reg_set + != this_call_used_reg_set)) || (last_call_insn && ! calls_have_same_clobbers_p (call_insn, last_call_insn)); diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c index 19f020a..6edcc6f 100644 --- a/gcc/reg-stack.c +++ b/gcc/reg-stack.c @@ -2643,7 +2643,7 @@ change_stack (rtx_insn *insn, stack_ptr old, stack_ptr new_stack, /* By now, the only difference should be the order of the stack, not their depth or liveliness. */ - gcc_assert (hard_reg_set_equal_p (old->reg_set, new_stack->reg_set)); + gcc_assert (old->reg_set == new_stack->reg_set); gcc_assert (old->top == new_stack->top); /* If the stack is not empty (new_stack->top != -1), loop here emitting @@ -3158,8 +3158,7 @@ convert_regs_1 (basic_block block) asms, we zapped the instruction itself, but that didn't produce the same pattern of register kills as before. */ - gcc_assert (hard_reg_set_equal_p (regstack.reg_set, bi->out_reg_set) - || any_malformed_asm); + gcc_assert (regstack.reg_set == bi->out_reg_set || any_malformed_asm); bi->stack_out = regstack; bi->done = true; -- cgit v1.1 From 75f4e3a1b322e16a1aca28bd0ced9af57cb0a683 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Mon, 9 Sep 2019 17:59:54 +0000 Subject: Tweak interface to ira-build.c:ior_hard_reg_conflicts This patch makes ior_hard_reg_conflicts take a const_hard_reg_set rather than a pointer, so that it can be passed a temporary object in later patches. 2019-09-09 Richard Sandiford gcc/ * ira-int.h (ior_hard_reg_conflicts): Take a const_hard_reg_set instead of a HARD_REG_SET *. * ira-build.c (ior_hard_reg_conflicts): Likewise. (ira_build): Update call accordingly. * ira-emit.c (add_range_and_copies_from_move_list): Likewise. From-SVN: r275535 --- gcc/ChangeLog | 8 ++++++++ gcc/ira-build.c | 8 ++++---- gcc/ira-emit.c | 4 ++-- gcc/ira-int.h | 2 +- 4 files changed, 15 insertions(+), 7 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8c791dd..7ae8c43 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 2019-09-09 Richard Sandiford + * ira-int.h (ior_hard_reg_conflicts): Take a const_hard_reg_set + instead of a HARD_REG_SET *. + * ira-build.c (ior_hard_reg_conflicts): Likewise. + (ira_build): Update call accordingly. + * ira-emit.c (add_range_and_copies_from_move_list): Likewise. + +2019-09-09 Richard Sandiford + * hard-reg-set.h (HARD_REG_SET::operator==): New function. (HARD_REG_SET::operator!=): Likewise. (hard_reg_set_equal_p): Delete. diff --git a/gcc/ira-build.c b/gcc/ira-build.c index 3170d7d..834bea7 100644 --- a/gcc/ira-build.c +++ b/gcc/ira-build.c @@ -614,15 +614,15 @@ merge_hard_reg_conflicts (ira_allocno_t from, ira_allocno_t to, /* Update hard register conflict information for all objects associated with A to include the regs in SET. */ void -ior_hard_reg_conflicts (ira_allocno_t a, HARD_REG_SET *set) +ior_hard_reg_conflicts (ira_allocno_t a, const_hard_reg_set set) { ira_allocno_object_iterator i; ira_object_t obj; FOR_EACH_ALLOCNO_OBJECT (a, obj, i) { - OBJECT_CONFLICT_HARD_REGS (obj) |= *set; - OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= *set; + OBJECT_CONFLICT_HARD_REGS (obj) |= set; + OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= set; } } @@ -3462,7 +3462,7 @@ ira_build (void) allocno crossing calls. */ FOR_EACH_ALLOCNO (a, ai) if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0) - ior_hard_reg_conflicts (a, &call_used_reg_set); + ior_hard_reg_conflicts (a, call_used_reg_set); } if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL) print_copies (ira_dump_file); diff --git a/gcc/ira-emit.c b/gcc/ira-emit.c index 255af30..9ac0521 100644 --- a/gcc/ira-emit.c +++ b/gcc/ira-emit.c @@ -1122,8 +1122,8 @@ add_range_and_copies_from_move_list (move_t list, ira_loop_tree_node_t node, ira_allocate_object_conflicts (to_obj, n); } } - ior_hard_reg_conflicts (from, &hard_regs_live); - ior_hard_reg_conflicts (to, &hard_regs_live); + ior_hard_reg_conflicts (from, hard_regs_live); + ior_hard_reg_conflicts (to, hard_regs_live); update_costs (from, true, freq); update_costs (to, false, freq); diff --git a/gcc/ira-int.h b/gcc/ira-int.h index 92b7dfb..95e22aa 100644 --- a/gcc/ira-int.h +++ b/gcc/ira-int.h @@ -998,7 +998,7 @@ extern void ira_set_allocno_class (ira_allocno_t, enum reg_class); extern bool ira_conflict_vector_profitable_p (ira_object_t, int); extern void ira_allocate_conflict_vec (ira_object_t, int); extern void ira_allocate_object_conflicts (ira_object_t, int); -extern void ior_hard_reg_conflicts (ira_allocno_t, HARD_REG_SET *); +extern void ior_hard_reg_conflicts (ira_allocno_t, const_hard_reg_set); extern void ira_print_expanded_allocno (ira_allocno_t); extern void ira_add_live_range_to_object (ira_object_t, int, int); extern live_range_t ira_create_live_range (ira_object_t, int, int, -- cgit v1.1 From 148909bc700e4f52aa582346a29abc5bc51a9bda Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Mon, 9 Sep 2019 18:01:47 +0000 Subject: Add "fast" conversions from arrays to bitmaps This patch adds a bitmap_view class that creates a read-only, on-stack bitmap representation of an array-like object X. The main use case is to allow HARD_REG_SETs to be used in REG_SET (i.e. bitmap) operations. For now it only handles constant-sized arrays, but I've tried to define the types in a way that could handle variable-sized arrays in future (although less efficiently). E.g. this might be useful for combining bitmaps and sbitmaps. For the read-only view to work as intended, I needed to make bitmap_bit_p take a const_bitmap instead of a bitmap. Logically the bitmap really is read-only, but we update the "current" and "indx" fields of the bitmap_head after doing a search. 2019-09-09 Richard Sandiford gcc/ * array-traits.h: New file. * coretypes.h (array_traits, bitmap_view): New types. * bitmap.h: Include "array-traits.h" (bitmap_bit_p): Take a const_bitmap instead of a bitmap. (base_bitmap_view, bitmap_view): New classes. * bitmap.c (bitmap_bit_p): Take a const_bitmap instead of a bitmap. * hard-reg-set.h: Include array-traits.h. (array_traits): New struct. * regset.h (IOR_REG_SET_HRS): New macro. * loop-iv.c (simplify_using_initial_values): Use IOR_REG_SET_HRS rather than iterating over each hard register. * sched-deps.c (sched_analyze_insn): Likewise. * sel-sched-ir.c (setup_id_implicit_regs): Likewise. From-SVN: r275536 --- gcc/ChangeLog | 16 +++++++ gcc/array-traits.h | 48 +++++++++++++++++++++ gcc/bitmap.c | 8 ++-- gcc/bitmap.h | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++- gcc/coretypes.h | 8 ++++ gcc/hard-reg-set.h | 12 ++++++ gcc/loop-iv.c | 10 +---- gcc/regset.h | 4 ++ gcc/sched-deps.c | 7 ++- gcc/sel-sched-ir.c | 5 +-- 10 files changed, 219 insertions(+), 21 deletions(-) create mode 100644 gcc/array-traits.h (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7ae8c43..248c5a5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,21 @@ 2019-09-09 Richard Sandiford + * array-traits.h: New file. + * coretypes.h (array_traits, bitmap_view): New types. + * bitmap.h: Include "array-traits.h" + (bitmap_bit_p): Take a const_bitmap instead of a bitmap. + (base_bitmap_view, bitmap_view): New classes. + * bitmap.c (bitmap_bit_p): Take a const_bitmap instead of a bitmap. + * hard-reg-set.h: Include array-traits.h. + (array_traits): New struct. + * regset.h (IOR_REG_SET_HRS): New macro. + * loop-iv.c (simplify_using_initial_values): Use IOR_REG_SET_HRS + rather than iterating over each hard register. + * sched-deps.c (sched_analyze_insn): Likewise. + * sel-sched-ir.c (setup_id_implicit_regs): Likewise. + +2019-09-09 Richard Sandiford + * ira-int.h (ior_hard_reg_conflicts): Take a const_hard_reg_set instead of a HARD_REG_SET *. * ira-build.c (ior_hard_reg_conflicts): Likewise. diff --git a/gcc/array-traits.h b/gcc/array-traits.h new file mode 100644 index 0000000..eb65ede --- /dev/null +++ b/gcc/array-traits.h @@ -0,0 +1,48 @@ +/* Descriptions of array-like objects. + Copyright (C) 2019 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_ARRAY_TRAITS_H +#define GCC_ARRAY_TRAITS_H + +/* Implementation for single integers (and similar types). */ +template +struct scalar_array_traits +{ + typedef T element_type; + static const bool has_constant_size = true; + static const size_t constant_size = 1; + static const T *base (const T &x) { return &x; } + static size_t size (const T &) { return 1; } +}; + +template +struct array_traits : scalar_array_traits {}; + +/* Implementation for arrays with a static size. */ +template +struct array_traits +{ + typedef T element_type; + static const bool has_constant_size = true; + static const size_t constant_size = N; + static const T *base (const T (&x)[N]) { return x; } + static size_t size (const T (&x)[N]) { return N; } +}; + +#endif diff --git a/gcc/bitmap.c b/gcc/bitmap.c index ce68a62..c6afa3f 100644 --- a/gcc/bitmap.c +++ b/gcc/bitmap.c @@ -979,17 +979,17 @@ bitmap_set_bit (bitmap head, int bit) /* Return whether a bit is set within a bitmap. */ int -bitmap_bit_p (bitmap head, int bit) +bitmap_bit_p (const_bitmap head, int bit) { unsigned int indx = bit / BITMAP_ELEMENT_ALL_BITS; - bitmap_element *ptr; + const bitmap_element *ptr; unsigned bit_num; unsigned word_num; if (!head->tree_form) - ptr = bitmap_list_find_element (head, indx); + ptr = bitmap_list_find_element (const_cast (head), indx); else - ptr = bitmap_tree_find_element (head, indx); + ptr = bitmap_tree_find_element (const_cast (head), indx); if (ptr == 0) return 0; diff --git a/gcc/bitmap.h b/gcc/bitmap.h index 5e080af..6502acb 100644 --- a/gcc/bitmap.h +++ b/gcc/bitmap.h @@ -210,6 +210,7 @@ along with GCC; see the file COPYING3. If not see on which many random-access membership tests will happen. */ #include "obstack.h" +#include "array-traits.h" /* Bitmap memory usage. */ class bitmap_usage: public mem_usage @@ -435,7 +436,7 @@ extern bool bitmap_clear_bit (bitmap, int); extern bool bitmap_set_bit (bitmap, int); /* Return true if a bit is set in a bitmap. */ -extern int bitmap_bit_p (bitmap, int); +extern int bitmap_bit_p (const_bitmap, int); /* Debug functions to print a bitmap. */ extern void debug_bitmap (const_bitmap); @@ -956,4 +957,123 @@ class auto_bitmap bitmap_head m_bits; }; +/* Base class for bitmap_view; see there for details. */ +template > +class base_bitmap_view +{ +public: + typedef typename Traits::element_type array_element_type; + + base_bitmap_view (const T &, bitmap_element *); + operator const_bitmap () const { return &m_head; } + +private: + base_bitmap_view (const base_bitmap_view &); + + bitmap_head m_head; +}; + +/* Provides a read-only bitmap view of a single integer bitmask or a + constant-sized array of integer bitmasks, or of a wrapper around such + bitmasks. */ +template +class bitmap_view : public base_bitmap_view +{ +public: + bitmap_view (const T &array) + : base_bitmap_view (array, m_bitmap_elements) {} + +private: + /* How many bitmap_elements we need to hold a full T. */ + static const size_t num_bitmap_elements + = CEIL (CHAR_BIT + * sizeof (typename Traits::element_type) + * Traits::constant_size, + BITMAP_ELEMENT_ALL_BITS); + bitmap_element m_bitmap_elements[num_bitmap_elements]; +}; + +/* Initialize the view for array ARRAY, using the array of bitmap + elements in BITMAP_ELEMENTS (which is known to contain enough + entries). */ +template +base_bitmap_view::base_bitmap_view (const T &array, + bitmap_element *bitmap_elements) +{ + m_head.obstack = NULL; + + /* The code currently assumes that each element of ARRAY corresponds + to exactly one bitmap_element. */ + const size_t array_element_bits = CHAR_BIT * sizeof (array_element_type); + STATIC_ASSERT (BITMAP_ELEMENT_ALL_BITS % array_element_bits == 0); + size_t array_step = BITMAP_ELEMENT_ALL_BITS / array_element_bits; + size_t array_size = Traits::size (array); + + /* Process each potential bitmap_element in turn. The loop is written + this way rather than per array element because usually there are + only a small number of array elements per bitmap element (typically + two or four). The inner loops should therefore unroll completely. */ + const array_element_type *array_elements = Traits::base (array); + unsigned int indx = 0; + for (size_t array_base = 0; + array_base < array_size; + array_base += array_step, indx += 1) + { + /* How many array elements are in this particular bitmap_element. */ + unsigned int array_count + = (STATIC_CONSTANT_P (array_size % array_step == 0) + ? array_step : MIN (array_step, array_size - array_base)); + + /* See whether we need this bitmap element. */ + array_element_type ior = array_elements[array_base]; + for (size_t i = 1; i < array_count; ++i) + ior |= array_elements[array_base + i]; + if (ior == 0) + continue; + + /* Grab the next bitmap element and chain it. */ + bitmap_element *bitmap_element = bitmap_elements++; + if (m_head.current) + m_head.current->next = bitmap_element; + else + m_head.first = bitmap_element; + bitmap_element->prev = m_head.current; + bitmap_element->next = NULL; + bitmap_element->indx = indx; + m_head.current = bitmap_element; + m_head.indx = indx; + + /* Fill in the bits of the bitmap element. */ + if (array_element_bits < BITMAP_WORD_BITS) + { + /* Multiple array elements fit in one element of + bitmap_element->bits. */ + size_t array_i = array_base; + for (unsigned int word_i = 0; word_i < BITMAP_ELEMENT_WORDS; + ++word_i) + { + BITMAP_WORD word = 0; + for (unsigned int shift = 0; + shift < BITMAP_WORD_BITS && array_i < array_size; + shift += array_element_bits) + word |= array_elements[array_i++] << shift; + bitmap_element->bits[word_i] = word; + } + } + else + { + /* Array elements are the same size as elements of + bitmap_element->bits, or are an exact multiple of that size. */ + unsigned int word_i = 0; + for (unsigned int i = 0; i < array_count; ++i) + for (unsigned int shift = 0; shift < array_element_bits; + shift += BITMAP_WORD_BITS) + bitmap_element->bits[word_i++] + = array_elements[array_base + i] >> shift; + while (word_i < BITMAP_ELEMENT_WORDS) + bitmap_element->bits[word_i++] = 0; + } + } +} + #endif /* GCC_BITMAP_H */ diff --git a/gcc/coretypes.h b/gcc/coretypes.h index eac2f39..fc0e09b 100644 --- a/gcc/coretypes.h +++ b/gcc/coretypes.h @@ -153,6 +153,14 @@ struct cl_option_handlers; struct diagnostic_context; class pretty_printer; +template struct array_traits; + +/* Provides a read-only bitmap view of a single integer bitmask or an + array of integer bitmasks, or of a wrapper around such bitmasks. */ +template, + bool has_constant_size = Traits::has_constant_size> +class bitmap_view; + /* Address space number for named address space support. */ typedef unsigned char addr_space_t; diff --git a/gcc/hard-reg-set.h b/gcc/hard-reg-set.h index e59779d..274956e 100644 --- a/gcc/hard-reg-set.h +++ b/gcc/hard-reg-set.h @@ -20,6 +20,8 @@ along with GCC; see the file COPYING3. If not see #ifndef GCC_HARD_REG_SET_H #define GCC_HARD_REG_SET_H +#include "array-traits.h" + /* Define the type of a set of hard registers. */ /* HARD_REG_ELT_TYPE is a typedef of the unsigned integral type which @@ -115,6 +117,16 @@ struct HARD_REG_SET }; typedef const HARD_REG_SET &const_hard_reg_set; +template<> +struct array_traits +{ + typedef HARD_REG_ELT_TYPE element_type; + static const bool has_constant_size = true; + static const size_t constant_size = HARD_REG_SET_LONGS; + static const element_type *base (const HARD_REG_SET &x) { return x.elts; } + static size_t size (const HARD_REG_SET &) { return HARD_REG_SET_LONGS; } +}; + #endif /* HARD_REG_SET wrapped into a structure, to make it possible to diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c index 82b329f..33be75a 100644 --- a/gcc/loop-iv.c +++ b/gcc/loop-iv.c @@ -1972,14 +1972,8 @@ simplify_using_initial_values (class loop *loop, enum rtx_code op, rtx *expr) CLEAR_REG_SET (this_altered); note_stores (insn, mark_altered, this_altered); if (CALL_P (insn)) - { - /* Kill all call clobbered registers. */ - unsigned int i; - hard_reg_set_iterator hrsi; - EXECUTE_IF_SET_IN_HARD_REG_SET (regs_invalidated_by_call, - 0, i, hrsi) - SET_REGNO_REG_SET (this_altered, i); - } + /* Kill all call clobbered registers. */ + IOR_REG_SET_HRS (this_altered, regs_invalidated_by_call); if (suitable_set_for_replacement (insn, &dest, &src)) { diff --git a/gcc/regset.h b/gcc/regset.h index 34a9eb4..f5e3d39 100644 --- a/gcc/regset.h +++ b/gcc/regset.h @@ -64,6 +64,10 @@ typedef bitmap regset; /* Inclusive or a register set with a second register set. */ #define IOR_REG_SET(TO, FROM) bitmap_ior_into (TO, FROM) +/* Same, but with FROM being a HARD_REG_SET. */ +#define IOR_REG_SET_HRS(TO, FROM) \ + bitmap_ior_into (TO, bitmap_view (FROM)) + /* Exclusive or a register set with a second register set. */ #define XOR_REG_SET(TO, FROM) bitmap_xor_into (TO, FROM) diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c index 36a6669..52db3cc 100644 --- a/gcc/sched-deps.c +++ b/gcc/sched-deps.c @@ -3332,10 +3332,9 @@ sched_analyze_insn (class deps_desc *deps, rtx x, rtx_insn *insn) IOR_REG_SET (&deps->reg_last_in_use, reg_pending_uses); IOR_REG_SET (&deps->reg_last_in_use, reg_pending_clobbers); IOR_REG_SET (&deps->reg_last_in_use, reg_pending_sets); - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (TEST_HARD_REG_BIT (implicit_reg_pending_uses, i) - || TEST_HARD_REG_BIT (implicit_reg_pending_clobbers, i)) - SET_REGNO_REG_SET (&deps->reg_last_in_use, i); + IOR_REG_SET_HRS (&deps->reg_last_in_use, + implicit_reg_pending_uses + | implicit_reg_pending_clobbers); /* Set up the pending barrier found. */ deps->last_reg_pending_barrier = reg_pending_barrier; diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c index bb8016b..e4f5a45 100644 --- a/gcc/sel-sched-ir.c +++ b/gcc/sel-sched-ir.c @@ -2661,12 +2661,9 @@ setup_id_implicit_regs (idata_t id, insn_t insn) return; HARD_REG_SET temp; - unsigned regno; - hard_reg_set_iterator hrsi; get_implicit_reg_pending_clobbers (&temp, insn); - EXECUTE_IF_SET_IN_HARD_REG_SET (temp, 0, regno, hrsi) - SET_REGNO_REG_SET (IDATA_REG_SETS (id), regno); + IOR_REG_SET_HRS (IDATA_REG_SETS (id), temp); } /* Setup register sets describing INSN in ID. */ -- cgit v1.1 From 0b0310e9a0e0d553bbe9f961c52e0851328aa8b0 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Mon, 9 Sep 2019 18:01:55 +0000 Subject: Remove global REG_SETs We currently maintain global REG_SET versions of fixed_reg_set and regs_invalidated_by_call. With bitmap_view, we can instead operate directly on the underlying HARD_REG_SETs, avoiding the need to keep the two pieces of data in sync. I have a series of patches that removes the assumption that there's a single global ABI for all functions in the translation unit, which includes not relying on having a global regs_invalidated_by_call. Removing the REG_SET equivalent is one step to doing that. Note that the affected DF code is used for EH edges or dumping only, so shouldn't be performance critical. 2019-09-09 Richard Sandiford gcc/ * regset.h (regs_invalidated_by_call_regset): Delete. (fixed_reg_set_regset): Likewise. * reginfo.c (regs_invalidated_by_call_regset): Likewise. (fixed_reg_set_regset, persistent_obstack): Likewise. (init_reg_sets_1, globalize_reg): Update accordingly. * df.h (df_print_regset, df_print_word_regset): Take a const_bitmap instead of a bitmap. * df-core.c (df_print_regset, df_print_word_regset): Likewise. * df-problems.c (df_rd_local_compute): Use regs_invalidated_by_call instead of regs_invalidated_by_call_regset. (df_lr_confluence_n, df_md_confluence_n): Likewise. * df-scan.c (df_scan_start_dump): Likewise. * dse.c (copy_fixed_regs): Likewise. * config/sh/sh.c (sh_find_equiv_gbr_addr): Likewise. From-SVN: r275537 --- gcc/ChangeLog | 17 +++++++++++++++++ gcc/config/sh/sh.c | 2 +- gcc/df-core.c | 4 ++-- gcc/df-problems.c | 20 +++++++++++--------- gcc/df-scan.c | 2 +- gcc/df.h | 4 ++-- gcc/dse.c | 2 +- gcc/reginfo.c | 42 ++++-------------------------------------- gcc/regset.h | 8 -------- 9 files changed, 39 insertions(+), 62 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 248c5a5..24e4fba 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,22 @@ 2019-09-09 Richard Sandiford + * regset.h (regs_invalidated_by_call_regset): Delete. + (fixed_reg_set_regset): Likewise. + * reginfo.c (regs_invalidated_by_call_regset): Likewise. + (fixed_reg_set_regset, persistent_obstack): Likewise. + (init_reg_sets_1, globalize_reg): Update accordingly. + * df.h (df_print_regset, df_print_word_regset): Take a const_bitmap + instead of a bitmap. + * df-core.c (df_print_regset, df_print_word_regset): Likewise. + * df-problems.c (df_rd_local_compute): Use regs_invalidated_by_call + instead of regs_invalidated_by_call_regset. + (df_lr_confluence_n, df_md_confluence_n): Likewise. + * df-scan.c (df_scan_start_dump): Likewise. + * dse.c (copy_fixed_regs): Likewise. + * config/sh/sh.c (sh_find_equiv_gbr_addr): Likewise. + +2019-09-09 Richard Sandiford + * array-traits.h: New file. * coretypes.h (array_traits, bitmap_view): New types. * bitmap.h: Include "array-traits.h" diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 7cc8857..b2fb56c 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -11695,7 +11695,7 @@ sh_find_equiv_gbr_addr (rtx_insn* insn, rtx mem) { if (CALL_P (DF_REF_INSN (d))) { - if (REGNO_REG_SET_P (regs_invalidated_by_call_regset, GBR_REG)) + if (TEST_HARD_REG_BIT (regs_invalidated_by_call, GBR_REG)) return NULL_RTX; else continue; diff --git a/gcc/df-core.c b/gcc/df-core.c index be19aba..7250c39 100644 --- a/gcc/df-core.c +++ b/gcc/df-core.c @@ -2052,7 +2052,7 @@ debug_regset (regset r) This is part of making a debugging dump. */ void -df_print_regset (FILE *file, bitmap r) +df_print_regset (FILE *file, const_bitmap r) { unsigned int i; bitmap_iterator bi; @@ -2077,7 +2077,7 @@ df_print_regset (FILE *file, bitmap r) debugging dump. */ void -df_print_word_regset (FILE *file, bitmap r) +df_print_word_regset (FILE *file, const_bitmap r) { unsigned int max_reg = max_reg_num (); diff --git a/gcc/df-problems.c b/gcc/df-problems.c index e8a45ae..89a9293 100644 --- a/gcc/df-problems.c +++ b/gcc/df-problems.c @@ -389,7 +389,6 @@ df_rd_local_compute (bitmap all_blocks) { unsigned int bb_index; bitmap_iterator bi; - unsigned int regno; class df_rd_problem_data *problem_data = (class df_rd_problem_data *) df_rd->problem_data; bitmap sparse_invalidated = &problem_data->sparse_invalidated_by_call; @@ -406,10 +405,9 @@ df_rd_local_compute (bitmap all_blocks) } /* Set up the knockout bit vectors to be applied across EH_EDGES. */ - EXECUTE_IF_SET_IN_BITMAP (regs_invalidated_by_call_regset, 0, regno, bi) - { - if (! HARD_REGISTER_NUM_P (regno) - || !(df->changeable_flags & DF_NO_HARD_REGS)) + if (!(df->changeable_flags & DF_NO_HARD_REGS)) + for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno) + if (TEST_HARD_REG_BIT (regs_invalidated_by_call, regno)) { if (DF_DEFS_COUNT (regno) > DF_SPARSE_THRESHOLD) bitmap_set_bit (sparse_invalidated, regno); @@ -418,7 +416,6 @@ df_rd_local_compute (bitmap all_blocks) DF_DEFS_BEGIN (regno), DF_DEFS_COUNT (regno)); } - } bitmap_release (&seen_in_block); bitmap_release (&seen_in_insn); @@ -983,7 +980,10 @@ df_lr_confluence_n (edge e) /* ??? Abnormal call edges ignored for the moment, as this gets confused by sibling call edges, which crashes reg-stack. */ if (e->flags & EDGE_EH) - changed = bitmap_ior_and_compl_into (op1, op2, regs_invalidated_by_call_regset); + { + bitmap_view eh_kills (regs_invalidated_by_call); + changed = bitmap_ior_and_compl_into (op1, op2, eh_kills); + } else changed = bitmap_ior_into (op1, op2); @@ -4635,8 +4635,10 @@ df_md_confluence_n (edge e) return false; if (e->flags & EDGE_EH) - return bitmap_ior_and_compl_into (op1, op2, - regs_invalidated_by_call_regset); + { + bitmap_view eh_kills (regs_invalidated_by_call); + return bitmap_ior_and_compl_into (op1, op2, eh_kills); + } else return bitmap_ior_into (op1, op2); } diff --git a/gcc/df-scan.c b/gcc/df-scan.c index 03294a8..d7bc2d8 100644 --- a/gcc/df-scan.c +++ b/gcc/df-scan.c @@ -313,7 +313,7 @@ df_scan_start_dump (FILE *file ATTRIBUTE_UNUSED) rtx_insn *insn; fprintf (file, ";; invalidated by call \t"); - df_print_regset (file, regs_invalidated_by_call_regset); + df_print_regset (file, bitmap_view (regs_invalidated_by_call)); fprintf (file, ";; hardware regs used \t"); df_print_regset (file, &df->hardware_regs_used); fprintf (file, ";; regular block artificial uses \t"); diff --git a/gcc/df.h b/gcc/df.h index 2e3b825..2454bfa 100644 --- a/gcc/df.h +++ b/gcc/df.h @@ -991,8 +991,8 @@ extern bool df_reg_defined (rtx_insn *, rtx); extern df_ref df_find_use (rtx_insn *, rtx); extern bool df_reg_used (rtx_insn *, rtx); extern void df_worklist_dataflow (struct dataflow *,bitmap, int *, int); -extern void df_print_regset (FILE *file, bitmap r); -extern void df_print_word_regset (FILE *file, bitmap r); +extern void df_print_regset (FILE *file, const_bitmap r); +extern void df_print_word_regset (FILE *file, const_bitmap r); extern void df_dump (FILE *); extern void df_dump_region (FILE *); extern void df_dump_start (FILE *); diff --git a/gcc/dse.c b/gcc/dse.c index 55b3cf1..c03b922 100644 --- a/gcc/dse.c +++ b/gcc/dse.c @@ -2392,7 +2392,7 @@ copy_fixed_regs (const_bitmap in) bitmap ret; ret = ALLOC_REG_SET (NULL); - bitmap_and (ret, in, fixed_reg_set_regset); + bitmap_and (ret, in, bitmap_view (fixed_reg_set)); return ret; } diff --git a/gcc/reginfo.c b/gcc/reginfo.c index 9b77261..48a3f66 100644 --- a/gcc/reginfo.c +++ b/gcc/reginfo.c @@ -92,17 +92,6 @@ char global_regs[FIRST_PSEUDO_REGISTER]; /* Declaration for the global register. */ tree global_regs_decl[FIRST_PSEUDO_REGISTER]; -/* Same information as REGS_INVALIDATED_BY_CALL but in regset form to be used - in dataflow more conveniently. */ -regset regs_invalidated_by_call_regset; - -/* Same information as FIXED_REG_SET but in regset form. */ -regset fixed_reg_set_regset; - -/* The bitmap_obstack is used to hold some static variables that - should not be reset after each function is compiled. */ -static bitmap_obstack persistent_obstack; - /* Used to initialize reg_alloc_order. */ #ifdef REG_ALLOC_ORDER static int initial_reg_alloc_order[FIRST_PSEUDO_REGISTER] = REG_ALLOC_ORDER; @@ -364,17 +353,6 @@ init_reg_sets_1 (void) CLEAR_HARD_REG_SET (call_used_reg_set); CLEAR_HARD_REG_SET (call_fixed_reg_set); CLEAR_HARD_REG_SET (regs_invalidated_by_call); - if (!regs_invalidated_by_call_regset) - { - bitmap_obstack_initialize (&persistent_obstack); - regs_invalidated_by_call_regset = ALLOC_REG_SET (&persistent_obstack); - } - else - CLEAR_REG_SET (regs_invalidated_by_call_regset); - if (!fixed_reg_set_regset) - fixed_reg_set_regset = ALLOC_REG_SET (&persistent_obstack); - else - CLEAR_REG_SET (fixed_reg_set_regset); operand_reg_set &= accessible_reg_set; for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) @@ -405,10 +383,7 @@ init_reg_sets_1 (void) #endif if (fixed_regs[i]) - { - SET_HARD_REG_BIT (fixed_reg_set, i); - SET_REGNO_REG_SET (fixed_reg_set_regset, i); - } + SET_HARD_REG_BIT (fixed_reg_set, i); if (call_used_regs[i]) SET_HARD_REG_BIT (call_used_reg_set, i); @@ -426,10 +401,7 @@ init_reg_sets_1 (void) if (i == STACK_POINTER_REGNUM) ; else if (global_regs[i]) - { - SET_HARD_REG_BIT (regs_invalidated_by_call, i); - SET_REGNO_REG_SET (regs_invalidated_by_call_regset, i); - } + SET_HARD_REG_BIT (regs_invalidated_by_call, i); else if (i == FRAME_POINTER_REGNUM) ; else if (!HARD_FRAME_POINTER_IS_FRAME_POINTER @@ -442,10 +414,7 @@ init_reg_sets_1 (void) && i == (unsigned) PIC_OFFSET_TABLE_REGNUM && fixed_regs[i]) ; else if (CALL_REALLY_USED_REGNO_P (i)) - { - SET_HARD_REG_BIT (regs_invalidated_by_call, i); - SET_REGNO_REG_SET (regs_invalidated_by_call_regset, i); - } + SET_HARD_REG_BIT (regs_invalidated_by_call, i); } call_fixed_reg_set = fixed_reg_set; @@ -800,10 +769,7 @@ globalize_reg (tree decl, int i) appropriate regs_invalidated_by_call bit, even if it's already set in fixed_regs. */ if (i != STACK_POINTER_REGNUM) - { - SET_HARD_REG_BIT (regs_invalidated_by_call, i); - SET_REGNO_REG_SET (regs_invalidated_by_call_regset, i); - } + SET_HARD_REG_BIT (regs_invalidated_by_call, i); /* If already fixed, nothing else to do. */ if (fixed_regs[i]) diff --git a/gcc/regset.h b/gcc/regset.h index f5e3d39..72ff458 100644 --- a/gcc/regset.h +++ b/gcc/regset.h @@ -111,14 +111,6 @@ typedef bitmap_iterator reg_set_iterator; #define EXECUTE_IF_AND_IN_REG_SET(REGSET1, REGSET2, MIN, REGNUM, RSI) \ EXECUTE_IF_AND_IN_BITMAP (REGSET1, REGSET2, MIN, REGNUM, RSI) \ -/* Same information as REGS_INVALIDATED_BY_CALL but in regset form to be used - in dataflow more conveniently. */ - -extern regset regs_invalidated_by_call_regset; - -/* Same information as FIXED_REG_SET but in regset form. */ -extern regset fixed_reg_set_regset; - /* An obstack for regsets. */ extern bitmap_obstack reg_obstack; -- cgit v1.1 From 4f0eaba24dfb46dd4b45251231fdf006a70888c5 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 9 Sep 2019 19:06:46 +0000 Subject: compiler: traverse types of constant expressions We forgot to ever traverse types of constant expressions. This rarely makes a difference--evidently, since nobody noticed--but it does matter when we inline constant expressions: we need to ensure that the type is visible to the importing code. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/194317 From-SVN: r275539 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/expressions.cc | 67 ++++++++++++++++++++++++++++++++++++++++ gcc/go/gofrontend/expressions.h | 3 ++ 3 files changed, 71 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 7b2d17e..d966638 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -8f2b844acda70330f7c50b360f8c983d2676ecbb +28c9053b3d507bef7bd56cb01c6b22deea354cdd The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 4db4e4a..cb09ec0 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -1812,6 +1812,9 @@ class Boolean_expression : public Expression do_import(Import_expression*, Location); protected: + int + do_traverse(Traverse*); + bool do_is_constant() const { return true; } @@ -1864,6 +1867,17 @@ class Boolean_expression : public Expression Type* type_; }; +// Traverse a boolean expression. We just need to traverse the type +// if there is one. + +int +Boolean_expression::do_traverse(Traverse* traverse) +{ + if (this->type_ != NULL) + return Type::traverse(this->type_, traverse); + return TRAVERSE_CONTINUE; +} + // Get the type. Type* @@ -1916,6 +1930,17 @@ Expression::make_boolean(bool val, Location location) // Class String_expression. +// Traverse a string expression. We just need to traverse the type +// if there is one. + +int +String_expression::do_traverse(Traverse* traverse) +{ + if (this->type_ != NULL) + return Type::traverse(this->type_, traverse); + return TRAVERSE_CONTINUE; +} + // Get the type. Type* @@ -2290,6 +2315,9 @@ class Integer_expression : public Expression dump_integer(Ast_dump_context* ast_dump_context, const mpz_t val); protected: + int + do_traverse(Traverse*); + bool do_is_constant() const { return true; } @@ -2353,6 +2381,17 @@ class Integer_expression : public Expression bool is_character_constant_; }; +// Traverse an integer expression. We just need to traverse the type +// if there is one. + +int +Integer_expression::do_traverse(Traverse* traverse) +{ + if (this->type_ != NULL) + return Type::traverse(this->type_, traverse); + return TRAVERSE_CONTINUE; +} + // Return a numeric constant for this expression. We have to mark // this as a character when appropriate. @@ -2714,6 +2753,9 @@ class Float_expression : public Expression dump_float(Ast_dump_context* ast_dump_context, const mpfr_t val); protected: + int + do_traverse(Traverse*); + bool do_is_constant() const { return true; } @@ -2773,6 +2815,17 @@ class Float_expression : public Expression Type* type_; }; +// Traverse a float expression. We just need to traverse the type if +// there is one. + +int +Float_expression::do_traverse(Traverse* traverse) +{ + if (this->type_ != NULL) + return Type::traverse(this->type_, traverse); + return TRAVERSE_CONTINUE; +} + // Return the current type. If we haven't set the type yet, we return // an abstract float type. @@ -2932,6 +2985,9 @@ class Complex_expression : public Expression dump_complex(Ast_dump_context* ast_dump_context, const mpc_t val); protected: + int + do_traverse(Traverse*); + bool do_is_constant() const { return true; } @@ -2995,6 +3051,17 @@ class Complex_expression : public Expression Type* type_; }; +// Traverse a complex expression. We just need to traverse the type +// if there is one. + +int +Complex_expression::do_traverse(Traverse* traverse) +{ + if (this->type_ != NULL) + return Type::traverse(this->type_, traverse); + return TRAVERSE_CONTINUE; +} + // Return the current type. If we haven't set the type yet, we return // an abstract complex type. diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h index 4c743da..2e3d1e0 100644 --- a/gcc/go/gofrontend/expressions.h +++ b/gcc/go/gofrontend/expressions.h @@ -1670,6 +1670,9 @@ class String_expression : public Expression do_import(Import_expression*, Location); protected: + int + do_traverse(Traverse*); + bool do_is_constant() const { return true; } -- cgit v1.1 From b7f55c8e35981c5f2cb7c65d7d69f58e02ab0bcd Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 9 Sep 2019 19:41:05 +0000 Subject: compiler: don't use predeclared location for implicit runtime import For the main package we add an implicit import of the runtime package, to ensure that it is initialized. That import used the predeclared location, which caused various tests, notably Named_type::is_builtin, to treat these imported names as builtin. Start using a real location, so that those tests do the right thing. By the way, this implicit import is a partial cause of golang/go#19773. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/194337 From-SVN: r275540 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/gogo.cc | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index d966638..79349d7 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -28c9053b3d507bef7bd56cb01c6b22deea354cdd +17bef47f464983fd8513f88f3f159d28e2423e79 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index d39a4fb..f6a8e7a 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -2589,9 +2589,11 @@ Gogo::define_global_names() if (this->is_main_package()) { // Every Go program has to import the runtime package, so that - // it is properly initialized. + // it is properly initialized. We can't use + // predeclared_location here as it will cause runtime functions + // to appear to be builtin functions. this->import_package("runtime", "_", false, false, - Linemap::predeclared_location()); + this->package_->location()); } for (Bindings::const_declarations_iterator p = -- cgit v1.1 From b3baefb205e22aef208192aaf02f7ab0fad7c025 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Mon, 9 Sep 2019 19:44:15 +0000 Subject: expmed.c (extract_bit_field): Update function comment regarding alt_rtl. 2019-09-09 Bernd Edlinger * expmed.c (extract_bit_field): Update function comment regarding alt_rtl. * expr.c (expand_expr_real): Update function comment regarding alt_rtl. (expand_misaligned_mem_ref): New helper function. (expand_expr_real_2): Use expand_misaligned_mem_ref. Remove duplicate assignment to "base" at case MEM_REF. Remove a shadowed variable "unsignedp" at case VCE. From-SVN: r275541 --- gcc/ChangeLog | 11 ++++++ gcc/expmed.c | 5 ++- gcc/expr.c | 113 +++++++++++++++++++++++----------------------------------- 3 files changed, 60 insertions(+), 69 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 24e4fba..fcf052a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2019-09-09 Bernd Edlinger + + * expmed.c (extract_bit_field): Update function comment + regarding alt_rtl. + * expr.c (expand_expr_real): Update function comment + regarding alt_rtl. + (expand_misaligned_mem_ref): New helper function. + (expand_expr_real_2): Use expand_misaligned_mem_ref. + Remove duplicate assignment to "base" at case MEM_REF. + Remove a shadowed variable "unsignedp" at case VCE. + 2019-09-09 Richard Sandiford * regset.h (regs_invalidated_by_call_regset): Delete. diff --git a/gcc/expmed.c b/gcc/expmed.c index c582f3a..f1975fe 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -2046,7 +2046,10 @@ extract_integral_bit_field (rtx op0, opt_scalar_int_mode op0_mode, If a TARGET is specified and we can store in it at no extra cost, we do so, and return TARGET. Otherwise, we return a REG of mode TMODE or MODE, with TMODE preferred - if they are equally easy. */ + if they are equally easy. + + If the result can be stored at TARGET, and ALT_RTL is non-NULL, + then *ALT_RTL is set to TARGET (before legitimziation). */ rtx extract_bit_field (rtx str_rtx, poly_uint64 bitsize, poly_uint64 bitnum, diff --git a/gcc/expr.c b/gcc/expr.c index 3f4c98c..2f2b53f 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -8261,6 +8261,8 @@ expand_constructor (tree exp, rtx target, enum expand_modifier modifier, DECL_RTL of the VAR_DECL. *ALT_RTL is also set if EXP is a COMPOUND_EXPR whose second argument is such a VAR_DECL, and so on recursively. + If the result can be stored at TARGET, and ALT_RTL is non-NULL, + then *ALT_RTL is set to TARGET (before legitimziation). If INNER_REFERENCE_P is true, we are expanding an inner reference. In this case, we don't adjust a returned MEM rtx that wouldn't be @@ -8398,6 +8400,40 @@ expand_cond_expr_using_cmove (tree treeop0 ATTRIBUTE_UNUSED, return NULL_RTX; } +/* A helper function for expand_expr_real_2 to be used with a + misaligned mem_ref TEMP. Assume an unsigned type if UNSIGNEDP + is nonzero, with alignment ALIGN in bits. + Store the value at TARGET if possible (if TARGET is nonzero). + Regardless of TARGET, we return the rtx for where the value is placed. + If the result can be stored at TARGET, and ALT_RTL is non-NULL, + then *ALT_RTL is set to TARGET (before legitimziation). */ + +static rtx +expand_misaligned_mem_ref (rtx temp, machine_mode mode, int unsignedp, + unsigned int align, rtx target, rtx *alt_rtl) +{ + enum insn_code icode; + + if ((icode = optab_handler (movmisalign_optab, mode)) + != CODE_FOR_nothing) + { + class expand_operand ops[2]; + + /* We've already validated the memory, and we're creating a + new pseudo destination. The predicates really can't fail, + nor can the generator. */ + create_output_operand (&ops[0], NULL_RTX, mode); + create_fixed_operand (&ops[1], temp); + expand_insn (icode, 2, ops); + temp = ops[0].value; + } + else if (targetm.slow_unaligned_access (mode, align)) + temp = extract_bit_field (temp, GET_MODE_BITSIZE (mode), + 0, unsignedp, target, + mode, mode, false, alt_rtl); + return temp; +} + rtx expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode, enum expand_modifier modifier) @@ -10077,27 +10113,8 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, && !inner_reference_p && mode != BLKmode && MEM_ALIGN (temp) < GET_MODE_ALIGNMENT (mode)) - { - enum insn_code icode; - - if ((icode = optab_handler (movmisalign_optab, mode)) - != CODE_FOR_nothing) - { - class expand_operand ops[2]; - - /* We've already validated the memory, and we're creating a - new pseudo destination. The predicates really can't fail, - nor can the generator. */ - create_output_operand (&ops[0], NULL_RTX, mode); - create_fixed_operand (&ops[1], temp); - expand_insn (icode, 2, ops); - temp = ops[0].value; - } - else if (targetm.slow_unaligned_access (mode, MEM_ALIGN (temp))) - temp = extract_bit_field (temp, GET_MODE_BITSIZE (mode), - 0, unsignedp, NULL_RTX, - mode, mode, false, NULL); - } + temp = expand_misaligned_mem_ref (temp, mode, unsignedp, + MEM_ALIGN (temp), NULL_RTX, NULL); return temp; } @@ -10325,27 +10342,8 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, && modifier != EXPAND_MEMORY && mode != BLKmode && align < GET_MODE_ALIGNMENT (mode)) - { - enum insn_code icode; - - if ((icode = optab_handler (movmisalign_optab, mode)) - != CODE_FOR_nothing) - { - class expand_operand ops[2]; - - /* We've already validated the memory, and we're creating a - new pseudo destination. The predicates really can't fail, - nor can the generator. */ - create_output_operand (&ops[0], NULL_RTX, mode); - create_fixed_operand (&ops[1], temp); - expand_insn (icode, 2, ops); - temp = ops[0].value; - } - else if (targetm.slow_unaligned_access (mode, align)) - temp = extract_bit_field (temp, GET_MODE_BITSIZE (mode), - 0, unsignedp, NULL_RTX, - mode, mode, false, NULL); - } + temp = expand_misaligned_mem_ref (temp, mode, unsignedp, + align, NULL_RTX, NULL); return temp; } @@ -10357,7 +10355,6 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, machine_mode address_mode; tree base = TREE_OPERAND (exp, 0); gimple *def_stmt; - enum insn_code icode; unsigned align; /* Handle expansion of non-aliased memory with non-BLKmode. That might end up in a register. */ @@ -10387,7 +10384,6 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, return expand_expr (exp, target, tmode, modifier); } address_mode = targetm.addr_space.address_mode (as); - base = TREE_OPERAND (exp, 0); if ((def_stmt = get_def_for_expr (base, BIT_AND_EXPR))) { tree mask = gimple_assign_rhs2 (def_stmt); @@ -10414,27 +10410,9 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, && !inner_reference_p && mode != BLKmode && align < GET_MODE_ALIGNMENT (mode)) - { - if ((icode = optab_handler (movmisalign_optab, mode)) - != CODE_FOR_nothing) - { - class expand_operand ops[2]; - - /* We've already validated the memory, and we're creating a - new pseudo destination. The predicates really can't fail, - nor can the generator. */ - create_output_operand (&ops[0], NULL_RTX, mode); - create_fixed_operand (&ops[1], temp); - expand_insn (icode, 2, ops); - temp = ops[0].value; - } - else if (targetm.slow_unaligned_access (mode, align)) - temp = extract_bit_field (temp, GET_MODE_BITSIZE (mode), - 0, TYPE_UNSIGNED (TREE_TYPE (exp)), - (modifier == EXPAND_STACK_PARM - ? NULL_RTX : target), - mode, mode, false, alt_rtl); - } + temp = expand_misaligned_mem_ref (temp, mode, unsignedp, align, + modifier == EXPAND_STACK_PARM + ? NULL_RTX : target, alt_rtl); if (reverse && modifier != EXPAND_MEMORY && modifier != EXPAND_WRITE) @@ -11109,11 +11087,10 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, machine_mode mode1; poly_int64 bitsize, bitpos, bytepos; tree offset; - int unsignedp, reversep, volatilep = 0; + int reversep, volatilep = 0; tree tem = get_inner_reference (treeop0, &bitsize, &bitpos, &offset, &mode1, &unsignedp, &reversep, &volatilep); - rtx orig_op0; /* ??? We should work harder and deal with non-zero offsets. */ if (!offset @@ -11123,7 +11100,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, && known_eq (wi::to_poly_offset (TYPE_SIZE (type)), bitsize)) { /* See the normal_inner_ref case for the rationale. */ - orig_op0 + rtx orig_op0 = expand_expr_real (tem, (TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE && (TREE_CODE (TYPE_SIZE (TREE_TYPE (tem))) -- cgit v1.1 From de0f55dbb314264d7858a9d98c805285c62f5b6b Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 9 Sep 2019 20:08:32 +0000 Subject: libgo: only build x/sys/cpu/cpu_gccgo.c on x86 systems The C file has a build tag, but the procedure we use for building C files ignores build tags. This should fix the libgo build on non-x86 systems. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/194378 From-SVN: r275544 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 79349d7..c75e959 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -17bef47f464983fd8513f88f3f159d28e2423e79 +03fa49394bb4b37453795bef3119e5b40c929aee The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From 8bdcbd013538dae97e72ba4c3c54f524daeeac72 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 9 Sep 2019 23:13:08 +0000 Subject: misc/cgo/testcshared: restore gofrontend-local changes They were lost when the files were moved in the update to Go1.13beta1. These changes should be made in the master repo for the 1.14 release, as riscv64 support is added there. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/194343 From-SVN: r275551 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index c75e959..21f9e48 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -03fa49394bb4b37453795bef3119e5b40c929aee +c6097f269d2b3dbfd5204cf7e3d0b9f8d7ec2b5e The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From fa412b7c52a8e023a16f853cc7f7efc7265b81ef Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Tue, 10 Sep 2019 00:16:23 +0000 Subject: Daily bump. From-SVN: r275555 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 4defdea..757af50 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20190909 +20190910 -- cgit v1.1 From 77df40e8127ec4f62c01c15f2d6f76d995424863 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Tue, 10 Sep 2019 02:29:13 +0000 Subject: PR c++/84374 - diagnose invalid uses of decltype(auto). * decl.c (grokdeclarator): Diagnose wrong usage of decltype(auto) in a function declaration. * g++.dg/cpp1y/auto-fn57.C: New test. From-SVN: r275557 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/decl.c | 10 ++++++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/cpp1y/auto-fn57.C | 18 ++++++++++++++++++ 4 files changed, 39 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp1y/auto-fn57.C (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 48582ce..2b98a06 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2019-09-09 Marek Polacek + + PR c++/84374 - diagnose invalid uses of decltype(auto). + * decl.c (grokdeclarator): Diagnose wrong usage of decltype(auto) in + a function declaration. + 2019-09-06 Nathan Sidwell PR c++/91125 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 88e2c3b..dfcd7b1 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -11681,6 +11681,16 @@ grokdeclarator (const cp_declarator *declarator, "allowed"); return error_mark_node; } + /* Only plain decltype(auto) is allowed. */ + if (tree a = type_uses_auto (type)) + { + if (AUTO_IS_DECLTYPE (a) && a != type) + { + error_at (typespec_loc, "%qT as type rather than " + "plain %", type); + return error_mark_node; + } + } if (ctype == NULL_TREE && decl_context == FIELD diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3d4ada8..f738a23 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-09 Marek Polacek + + PR c++/84374 - diagnose invalid uses of decltype(auto). + * g++.dg/cpp1y/auto-fn57.C: New test. + 2019-09-09 Segher Boessenkool * gcc.target/powerpc/rlwinm-0.c: Adjust expected instruction counts. diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn57.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn57.C new file mode 100644 index 0000000..e58df18 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn57.C @@ -0,0 +1,18 @@ +// PR c++/84374 - diagnose invalid uses of decltype(auto). +// { dg-do compile { target c++14 } } + +auto l = [](auto* r)->decltype(auto)* { return r; }; // { dg-error "as type rather than plain" } +auto m = [](auto* r)->decltype(auto)& { return *r; }; // { dg-error "as type rather than plain" } + +decltype(auto)* f(); // { dg-error "as type rather than plain" } +decltype(auto)& f2(); // { dg-error "as type rather than plain" } +decltype(auto)* f3() { return 42; } // { dg-error "as type rather than plain" } +decltype(auto)& f4() { return 42; } // { dg-error "as type rather than plain" } + + +class C { + decltype(auto)* g(); // { dg-error "as type rather than plain" } + decltype(auto)& g2(); // { dg-error "as type rather than plain" } + decltype(auto)* g3() { } // { dg-error "as type rather than plain" } + decltype(auto)& g4() { } // { dg-error "as type rather than plain" } +}; -- cgit v1.1 From 5447e8e2e249a12b0f22ccfb171ccc8fff9fcadc Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 10 Sep 2019 02:37:42 +0000 Subject: compiler: permit inlining constant expressions and expression statements This relatively minor change increases the number of inlinable functions/methods in the standard library from 983 to 2179. In particular it permits inlining math/bits/RotateLeftNN. This restores the speed of crypto/sha256 back to what it was before the update to 1.13beta1. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/194340 From-SVN: r275558 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/expressions.cc | 4 ++++ gcc/go/gofrontend/statements.cc | 12 ++++++++++++ gcc/go/gofrontend/statements.h | 7 +++++++ 4 files changed, 24 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 21f9e48..a762d6b 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -c6097f269d2b3dbfd5204cf7e3d0b9f8d7ec2b5e +5c3f52ffbae7a9bb59bce63cd2cffdd8af8f4a92 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index cb09ec0..7d8963e 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -3283,6 +3283,10 @@ class Const_expression : public Expression Bexpression* do_get_backend(Translate_context* context); + int + do_inlining_cost() const + { return 1; } + // When exporting a reference to a const as part of a const // expression, we export the value. We ignore the fact that it has // a name. diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc index 27c309e..3dc394a 100644 --- a/gcc/go/gofrontend/statements.cc +++ b/gcc/go/gofrontend/statements.cc @@ -158,6 +158,10 @@ Statement::import_statement(Import_function_body* ifb, Location loc) return Goto_statement::do_import(ifb, loc); Expression* lhs = Expression::import_expression(ifb, loc); + + if (ifb->match_c_string(" //")) + return Statement::make_statement(lhs, true); + ifb->require_c_string(" = "); Expression* rhs = Expression::import_expression(ifb, loc); return Statement::make_assignment(lhs, rhs, loc); @@ -2089,6 +2093,14 @@ Expression_statement::do_may_fall_through() const return true; } +// Export an expression statement. + +void +Expression_statement::do_export_statement(Export_function_body* efb) +{ + this->expr_->export_expression(efb); +} + // Convert to backend representation. Bstatement* diff --git a/gcc/go/gofrontend/statements.h b/gcc/go/gofrontend/statements.h index 311bbaa..f1c6be9 100644 --- a/gcc/go/gofrontend/statements.h +++ b/gcc/go/gofrontend/statements.h @@ -924,6 +924,13 @@ class Expression_statement : public Statement bool do_may_fall_through() const; + int + do_inlining_cost() + { return 0; } + + void + do_export_statement(Export_function_body*); + Bstatement* do_get_backend(Translate_context* context); -- cgit v1.1 From c96fc0812393c3e2744232c1f6e248776628397f Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 10 Sep 2019 02:48:24 +0000 Subject: cmd/go: look for tool build ID before hashing entire file Also fix the key used to store the ID. This is a significant speedup in cmd/go run time. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/194257 From-SVN: r275559 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index a762d6b..183dac5 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -5c3f52ffbae7a9bb59bce63cd2cffdd8af8f4a92 +68038b4fdf1456482af986cb05dcf3121bd43ffc The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From 4563bc4dc63664a64cb9ce6c426c689619c209e4 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Tue, 10 Sep 2019 09:32:41 +0200 Subject: [ARM/FDPIC 01/24] [ARM] FDPIC: Add -mfdpic option support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2019-09-10 Christophe Lyon Mickaël Guêné * config/arm/arm.opt: Add -mfdpic option. * doc/invoke.texi: Add documentation for -mfdpic. Co-Authored-By: Mickaël Guêné From-SVN: r275561 --- gcc/ChangeLog | 6 ++++++ gcc/config/arm/arm.opt | 4 ++++ gcc/doc/invoke.texi | 24 +++++++++++++++++++++++- 3 files changed, 33 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fcf052a..8fae4ec 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-09-10 Christophe Lyon + Mickaël Guêné + + * config/arm/arm.opt: Add -mfdpic option. + * doc/invoke.texi: Add documentation for -mfdpic. + 2019-09-09 Bernd Edlinger * expmed.c (extract_bit_field): Update function comment diff --git a/gcc/config/arm/arm.opt b/gcc/config/arm/arm.opt index 5ecc5e5..545ec49 100644 --- a/gcc/config/arm/arm.opt +++ b/gcc/config/arm/arm.opt @@ -306,3 +306,7 @@ Cost to assume for a branch insn. mgeneral-regs-only Target Report RejectNegative Mask(GENERAL_REGS_ONLY) Save Generate code which uses the core registers only (r0-r14). + +mfdpic +Target Report Mask(FDPIC) +Enable Function Descriptor PIC mode. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index ef23a7d..234c1b7 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -710,7 +710,8 @@ Objective-C and Objective-C++ Dialects}. -mrestrict-it @gol -mverbose-cost-dump @gol -mpure-code @gol --mcmse} +-mcmse @gol +-mfdpic} @emph{AVR Options} @gccoptlist{-mmcu=@var{mcu} -mabsdata -maccumulate-args @gol @@ -18029,6 +18030,27 @@ MOVT instruction. Generate secure code as per the "ARMv8-M Security Extensions: Requirements on Development Tools Engineering Specification", which can be found on @url{http://infocenter.arm.com/help/topic/com.arm.doc.ecm0359818/ECM0359818_armv8m_security_extensions_reqs_on_dev_tools_1_0.pdf}. + +@item -mfdpic +@itemx -mno-fdpic +@opindex mfdpic +@opindex mno-fdpic +Select the FDPIC ABI, which uses 64-bit function descriptors to +represent pointers to functions. When the compiler is configured for +@code{arm-*-uclinuxfdpiceabi} targets, this option is on by default +and implies @option{-fPIE} if none of the PIC/PIE-related options is +provided. On other targets, it only enables the FDPIC-specific code +generation features, and the user should explicitly provide the +PIC/PIE-related options as needed. + +Note that static linking is not supported because it would still +involve the dynamic linker when the program self-relocates. If such +behavior is acceptable, use -static and -Wl,-dynamic-linker options. + +The opposite @option{-mno-fdpic} option is useful (and required) to +build the Linux kernel using the same (@code{arm-*-uclinuxfdpiceabi}) +toolchain as the one used to build the userland programs. + @end table @node AVR Options -- cgit v1.1 From b1e21e5a5d19b436f948710e09157c5b3244f541 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Tue, 10 Sep 2019 09:37:00 +0200 Subject: [ARM/FDPIC v6 02/24] [ARM] FDPIC: Handle arm*-*-uclinuxfdpiceabi in configure scripts The new arm-uclinuxfdpiceabi target behaves pretty much like arm-linux-gnueabi. In order to enable the same set of features, we have to update several configure scripts that generally match targets like *-*-linux*: in most places, we add *-uclinux* where there is already *-linux*, or uclinux* when there is already linux*. In gcc/config.gcc and libgcc/config.host we use *-*-uclinuxfdpiceabi because there is already a different behaviour for *-*uclinux* target. In libtool.m4, we use uclinuxfdpiceabi in cases where ELF shared libraries support is required, as uclinux does not guarantee that. 2019-09-10 Christophe Lyon config/ * futex.m4: Handle *-uclinux*. * tls.m4 (GCC_CHECK_TLS): Likewise. gcc/ * config.gcc: Handle *-*-uclinuxfdpiceabi. libatomic/ * configure.tgt: Handle arm*-*-uclinux*. * configure: Regenerate. libgcc/ * config.host: Handle *-*-uclinuxfdpiceabi. libitm/ * configure.tgt: Handle *-*-uclinux*. * configure: Regenerate. * libtool.m4: Handle uclinuxfdpiceabi. From-SVN: r275564 --- gcc/ChangeLog | 4 ++++ gcc/config.gcc | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8fae4ec..d437968 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,8 @@ 2019-09-10 Christophe Lyon + + * config.gcc: Handle *-*-uclinuxfdpiceabi. + +2019-09-10 Christophe Lyon Mickaël Guêné * config/arm/arm.opt: Add -mfdpic option. diff --git a/gcc/config.gcc b/gcc/config.gcc index 0eba7ca..3554449 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -774,7 +774,7 @@ case ${target} in *-*-fuchsia*) native_system_header_dir=/include ;; -*-*-linux* | frv-*-*linux* | *-*-kfreebsd*-gnu | *-*-gnu* | *-*-kopensolaris*-gnu) +*-*-linux* | frv-*-*linux* | *-*-kfreebsd*-gnu | *-*-gnu* | *-*-kopensolaris*-gnu | *-*-uclinuxfdpiceabi) extra_options="$extra_options gnu-user.opt" gas=yes gnu_ld=yes @@ -803,7 +803,7 @@ case ${target} in *-*-*android*) tm_defines="$tm_defines DEFAULT_LIBC=LIBC_BIONIC" ;; - *-*-*uclibc*) + *-*-*uclibc* | *-*-uclinuxfdpiceabi) tm_defines="$tm_defines DEFAULT_LIBC=LIBC_UCLIBC" ;; *-*-*musl*) @@ -1201,7 +1201,7 @@ arm*-*-netbsdelf*) armv7*) target_cpu_cname="generic-armv7-a";; esac ;; -arm*-*-linux-*) # ARM GNU/Linux with ELF +arm*-*-linux-* | arm*-*-uclinuxfdpiceabi) tm_file="dbxelf.h elfos.h gnu-user.h linux.h linux-android.h glibc-stdint.h arm/elf.h arm/linux-gas.h arm/linux-elf.h" extra_options="${extra_options} linux-android.opt" case $target in -- cgit v1.1 From 45d53c679a5de20410818d1de40a09542fa1387e Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Tue, 10 Sep 2019 09:39:47 +0200 Subject: [ARM/FDPIC v6 03/24] [ARM] FDPIC: Force FDPIC related options unless -mno-fdpic is provided MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In FDPIC mode, we set -fPIE unless the user provides -fno-PIE, -fpie, -fPIC or -fpic: indeed FDPIC code is PIC, but we want to generate code for executables rather than shared libraries by default. We also make sure to use the --fdpic assembler option, and select the appropriate linker emulation. At link time, we also default to -pie, unless we are generating a shared library or a relocatable file (-r). Note that static link is not supported as it requires specifying the dynamic linker because the executable still has to relocate itself at startup. We also force 'now' binding since lazy binding is not supported. We should also apply the same behavior for -Wl,-Ur as for -r, but I couldn't find how to describe that in the specs fragment. 2019-09-10 Christophe Lyon Mickaël Guêné gcc/ * config.gcc: Handle arm*-*-uclinuxfdpiceabi. * config/arm/bpabi.h (TARGET_FDPIC_ASM_SPEC): New. (SUBTARGET_EXTRA_ASM_SPEC): Use TARGET_FDPIC_ASM_SPEC. * config/arm/linux-eabi.h (FDPIC_CC1_SPEC): New. (CC1_SPEC): Use FDPIC_CC1_SPEC. (MUSL_DYNAMIC_LINKER): Add -fdpic suffix when needed. * config/arm/uclinuxfdpiceabi.h: New file. libsanitizer/ * configure.tgt (arm*-*-*fdpiceabi): Sanitizers are unsupported in this configuration. Co-Authored-By: Mickaël Guêné From-SVN: r275565 --- gcc/ChangeLog | 13 +++++++++- gcc/config.gcc | 5 ++++ gcc/config/arm/bpabi.h | 5 +++- gcc/config/arm/linux-eabi.h | 7 +++-- gcc/config/arm/uclinuxfdpiceabi.h | 54 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 gcc/config/arm/uclinuxfdpiceabi.h (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d437968..90c7ecd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,17 @@ 2019-09-10 Christophe Lyon + Mickaël Guêné - * config.gcc: Handle *-*-uclinuxfdpiceabi. + * config.gcc: Handle arm*-*-uclinuxfdpiceabi. + * config/arm/bpabi.h (TARGET_FDPIC_ASM_SPEC): New. + (SUBTARGET_EXTRA_ASM_SPEC): Use TARGET_FDPIC_ASM_SPEC. + * config/arm/linux-eabi.h (FDPIC_CC1_SPEC): New. + (CC1_SPEC): Use FDPIC_CC1_SPEC. + (MUSL_DYNAMIC_LINKER): Add -fdpic suffix when needed. + * config/arm/uclinuxfdpiceabi.h: New file. + +2019-09-10 Christophe Lyon + + * config.gcc: Handle *-*-uclinuxfdpiceabi. 2019-09-10 Christophe Lyon Mickaël Guêné diff --git a/gcc/config.gcc b/gcc/config.gcc index 3554449..69d0a02 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -1211,6 +1211,11 @@ arm*-*-linux-* | arm*-*-uclinuxfdpiceabi) esac tmake_file="${tmake_file} arm/t-arm arm/t-arm-elf arm/t-bpabi arm/t-linux-eabi" tm_file="$tm_file arm/bpabi.h arm/linux-eabi.h arm/aout.h arm/arm.h" + case $target in + arm*-*-uclinuxfdpiceabi) + tm_file="$tm_file arm/uclinuxfdpiceabi.h" + ;; + esac # Generation of floating-point instructions requires at least ARMv5te. if [ "$with_float" = "hard" -o "$with_float" = "softfp" ] ; then target_cpu_cname="arm10e" diff --git a/gcc/config/arm/bpabi.h b/gcc/config/arm/bpabi.h index e1bacf4..75d9a99 100644 --- a/gcc/config/arm/bpabi.h +++ b/gcc/config/arm/bpabi.h @@ -55,6 +55,8 @@ #define TARGET_FIX_V4BX_SPEC " %{mcpu=arm8|mcpu=arm810|mcpu=strongarm*"\ "|march=armv4|mcpu=fa526|mcpu=fa626:--fix-v4bx}" +#define TARGET_FDPIC_ASM_SPEC "" + #define BE8_LINK_SPEC \ "%{!r:%{!mbe32:%:be8_linkopt(%{mlittle-endian:little}" \ " %{mbig-endian:big}" \ @@ -64,7 +66,8 @@ /* Tell the assembler to build BPABI binaries. */ #undef SUBTARGET_EXTRA_ASM_SPEC #define SUBTARGET_EXTRA_ASM_SPEC \ - "%{mabi=apcs-gnu|mabi=atpcs:-meabi=gnu;:-meabi=5}" TARGET_FIX_V4BX_SPEC + "%{mabi=apcs-gnu|mabi=atpcs:-meabi=gnu;:-meabi=5}" TARGET_FIX_V4BX_SPEC \ + TARGET_FDPIC_ASM_SPEC #ifndef SUBTARGET_EXTRA_LINK_SPEC #define SUBTARGET_EXTRA_LINK_SPEC "" diff --git a/gcc/config/arm/linux-eabi.h b/gcc/config/arm/linux-eabi.h index 66ec0ea..b348971 100644 --- a/gcc/config/arm/linux-eabi.h +++ b/gcc/config/arm/linux-eabi.h @@ -89,7 +89,7 @@ #define MUSL_DYNAMIC_LINKER_E "%{mbig-endian:eb}" #endif #define MUSL_DYNAMIC_LINKER \ - "/lib/ld-musl-arm" MUSL_DYNAMIC_LINKER_E "%{mfloat-abi=hard:hf}.so.1" + "/lib/ld-musl-arm" MUSL_DYNAMIC_LINKER_E "%{mfloat-abi=hard:hf}%{mfdpic:-fdpic}.so.1" /* At this point, bpabi.h will have clobbered LINK_SPEC. We want to use the GNU/Linux version, not the generic BPABI version. */ @@ -101,9 +101,12 @@ #undef ASAN_CC1_SPEC #define ASAN_CC1_SPEC "%{%:sanitize(address):-funwind-tables}" +#define FDPIC_CC1_SPEC "" + #undef CC1_SPEC #define CC1_SPEC \ - LINUX_OR_ANDROID_CC (GNU_USER_TARGET_CC1_SPEC " " ASAN_CC1_SPEC, \ + LINUX_OR_ANDROID_CC (GNU_USER_TARGET_CC1_SPEC " " ASAN_CC1_SPEC " " \ + FDPIC_CC1_SPEC, \ GNU_USER_TARGET_CC1_SPEC " " ASAN_CC1_SPEC " " \ ANDROID_CC1_SPEC) diff --git a/gcc/config/arm/uclinuxfdpiceabi.h b/gcc/config/arm/uclinuxfdpiceabi.h new file mode 100644 index 0000000..328adcb --- /dev/null +++ b/gcc/config/arm/uclinuxfdpiceabi.h @@ -0,0 +1,54 @@ +/* Configuration file for ARM GNU/Linux FDPIC EABI targets. + Copyright (C) 2018,2019 Free Software Foundation, Inc. + Contributed by STMicroelectronics. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +/* On uClibc EABI GNU/Linux, we want to force -mfdpic by default, + which also means we produce PIE code by default. */ +#undef FDPIC_CC1_SPEC +#define FDPIC_CC1_SPEC \ + "%{!mno-fdpic:-mfdpic %{!fno-PIE:%{!fpie:%{!fPIC:%{!fpic: -fPIE}}}}}" + +/* Add --fdpic assembler flag by default. */ +#undef TARGET_FDPIC_ASM_SPEC +#define TARGET_FDPIC_ASM_SPEC "%{!mno-fdpic: --fdpic}" + +/* TARGET_BIG_ENDIAN_DEFAULT is set in + config.gcc for big endian configurations. */ +#if TARGET_BIG_ENDIAN_DEFAULT +#define TARGET_FDPIC_LINKER_EMULATION "armelfb_linux_fdpiceabi" +#else +#define TARGET_FDPIC_LINKER_EMULATION "armelf_linux_fdpiceabi" +#endif + +/* Unless we generate a shared library or a relocatable object, we + force -pie. */ +/* -static is not supported, because we have to define the + dynamic-linker, as we have some relocations to resolve at load + time. We do not generate an error in case the user explictly passes + the -dynamic-linker option to the linker. */ +#undef SUBTARGET_EXTRA_LINK_SPEC +#define SUBTARGET_EXTRA_LINK_SPEC \ + "%{!mno-fdpic: -m " TARGET_FDPIC_LINKER_EMULATION \ + "%{!shared:%{!r: -pie}} }" \ + "%{mno-fdpic: -m " TARGET_LINKER_EMULATION "}" \ + "%{!r:%{!mno-fdpic: -z now}}" + +#undef STARTFILE_SPEC +#define STARTFILE_SPEC "%{!mno-fdpic:%{!shared:crtreloc.o%s}} " \ + LINUX_OR_ANDROID_LD (GNU_USER_TARGET_STARTFILE_SPEC, ANDROID_STARTFILE_SPEC) -- cgit v1.1 From 8b63716e87e138e7e2a01309367da9c720e07949 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Tue, 10 Sep 2019 09:41:59 +0200 Subject: [ARM/FDPIC v6 04/24] [ARM] FDPIC: Add support for FDPIC for arm architecture MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The FDPIC register is hard-coded to r9, as defined in the ABI. We have to disable tailcall optimizations if we don't know if the target function is in the same module. If not, we have to set r9 to the value associated with the target module. When generating a symbol address, we have to take into account whether it is a pointer to data or to a function, because different relocations are needed. 2019-09-10 Christophe Lyon Mickaël Guêné gcc/ * config/arm/arm-c.c (__FDPIC__): Define new pre-processor macro in FDPIC mode. * config/arm/arm-protos.h (arm_load_function_descriptor): Declare new function. * config/arm/arm.c (arm_option_override): Define pic register to FDPIC_REGNUM. (arm_function_ok_for_sibcall): Disable sibcall optimization if we have no decl or go through PLT. (calculate_pic_address_constant): New function. (legitimize_pic_address): Call calculate_pic_address_constant. (arm_load_pic_register): Handle TARGET_FDPIC. (arm_is_segment_info_known): New function. (arm_pic_static_addr): Add support for FDPIC. (arm_load_function_descriptor): New function. (arm_emit_call_insn): Add support for FDPIC. (arm_assemble_integer): Add support for FDPIC. * config/arm/arm.h (PIC_OFFSET_TABLE_REG_CALL_CLOBBERED): Define. (FDPIC_REGNUM): New define. * config/arm/arm.md (call): Add support for FDPIC. (call_value): Likewise. (restore_pic_register_after_call): New pattern. (untyped_call): Disable if FDPIC. (untyped_return): Likewise. * config/arm/unspecs.md (UNSPEC_PIC_RESTORE): New. gcc/testsuite/ * gcc.target/arm/fp16-aapcs-2.c: Adjust scan-assembler-times. * gcc.target/arm/fp16-aapcs-4.c: Likewise. Co-Authored-By: Mickaël Guêné From-SVN: r275566 --- gcc/ChangeLog | 28 ++++ gcc/config/arm/arm-c.c | 2 + gcc/config/arm/arm-protos.h | 1 + gcc/config/arm/arm.c | 237 ++++++++++++++++++++++++---- gcc/config/arm/arm.h | 7 + gcc/config/arm/arm.md | 49 +++++- gcc/config/arm/unspecs.md | 1 + gcc/testsuite/ChangeLog | 6 + gcc/testsuite/gcc.target/arm/fp16-aapcs-2.c | 2 +- gcc/testsuite/gcc.target/arm/fp16-aapcs-4.c | 2 +- 10 files changed, 303 insertions(+), 32 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 90c7ecd..62fb38a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,34 @@ 2019-09-10 Christophe Lyon Mickaël Guêné + * config/arm/arm-c.c (__FDPIC__): Define new pre-processor macro + in FDPIC mode. + * config/arm/arm-protos.h (arm_load_function_descriptor): Declare + new function. + * config/arm/arm.c (arm_option_override): Define pic register to + FDPIC_REGNUM. + (arm_function_ok_for_sibcall): Disable sibcall optimization if we + have no decl or go through PLT. + (calculate_pic_address_constant): New function. + (legitimize_pic_address): Call calculate_pic_address_constant. + (arm_load_pic_register): Handle TARGET_FDPIC. + (arm_is_segment_info_known): New function. + (arm_pic_static_addr): Add support for FDPIC. + (arm_load_function_descriptor): New function. + (arm_emit_call_insn): Add support for FDPIC. + (arm_assemble_integer): Add support for FDPIC. + * config/arm/arm.h (PIC_OFFSET_TABLE_REG_CALL_CLOBBERED): + Define. (FDPIC_REGNUM): New define. + * config/arm/arm.md (call): Add support for FDPIC. + (call_value): Likewise. + (restore_pic_register_after_call): New pattern. + (untyped_call): Disable if FDPIC. + (untyped_return): Likewise. + * config/arm/unspecs.md (UNSPEC_PIC_RESTORE): New. + +2019-09-10 Christophe Lyon + Mickaël Guêné + * config.gcc: Handle arm*-*-uclinuxfdpiceabi. * config/arm/bpabi.h (TARGET_FDPIC_ASM_SPEC): New. (SUBTARGET_EXTRA_ASM_SPEC): Use TARGET_FDPIC_ASM_SPEC. diff --git a/gcc/config/arm/arm-c.c b/gcc/config/arm/arm-c.c index 6e256ee..34695fa 100644 --- a/gcc/config/arm/arm-c.c +++ b/gcc/config/arm/arm-c.c @@ -203,6 +203,8 @@ arm_cpu_builtins (struct cpp_reader* pfile) builtin_define ("__ARM_EABI__"); } + def_or_undef_macro (pfile, "__FDPIC__", TARGET_FDPIC); + def_or_undef_macro (pfile, "__ARM_ARCH_EXT_IDIV__", TARGET_IDIV); def_or_undef_macro (pfile, "__ARM_FEATURE_IDIV", TARGET_IDIV); diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index 8386d89..f995974 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -139,6 +139,7 @@ extern int arm_max_const_double_inline_cost (void); extern int arm_const_double_inline_cost (rtx); extern bool arm_const_double_by_parts (rtx); extern bool arm_const_double_by_immediates (rtx); +extern rtx arm_load_function_descriptor (rtx funcdesc); extern void arm_emit_call_insn (rtx, rtx, bool); bool detect_cmse_nonsecure_call (tree); extern const char *output_call (rtx *); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 8576431..c34aab8 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -3456,6 +3456,14 @@ arm_option_override (void) if (flag_pic && TARGET_VXWORKS_RTP) arm_pic_register = 9; + /* If in FDPIC mode then force arm_pic_register to be r9. */ + if (TARGET_FDPIC) + { + arm_pic_register = FDPIC_REGNUM; + if (TARGET_THUMB1) + sorry ("FDPIC mode is not supported in Thumb-1 mode"); + } + if (arm_pic_register_string != NULL) { int pic_register = decode_reg_name (arm_pic_register_string); @@ -7251,6 +7259,15 @@ arm_function_ok_for_sibcall (tree decl, tree exp) if (cfun->machine->sibcall_blocked) return false; + if (TARGET_FDPIC) + { + /* In FDPIC, never tailcall something for which we have no decl: + the target function could be in a different module, requiring + a different FDPIC register value. */ + if (decl == NULL) + return false; + } + /* Never tailcall something if we are generating code for Thumb-1. */ if (TARGET_THUMB1) return false; @@ -7461,6 +7478,24 @@ require_pic_register (rtx pic_reg, bool compute_now) } } +/* Generate insns to calculate the address of ORIG in pic mode. */ +static rtx_insn * +calculate_pic_address_constant (rtx reg, rtx pic_reg, rtx orig) +{ + rtx pat; + rtx mem; + + pat = gen_calculate_pic_address (reg, pic_reg, orig); + + /* Make the MEM as close to a constant as possible. */ + mem = SET_SRC (pat); + gcc_assert (MEM_P (mem) && !MEM_VOLATILE_P (mem)); + MEM_READONLY_P (mem) = 1; + MEM_NOTRAP_P (mem) = 1; + + return emit_insn (pat); +} + /* Legitimize PIC load to ORIG into REG. If REG is NULL, a new pseudo is created to hold the result of the load. If not NULL, PIC_REG indicates which register to use as PIC register, otherwise it is decided by register @@ -7505,24 +7540,13 @@ legitimize_pic_address (rtx orig, machine_mode mode, rtx reg, rtx pic_reg, insn = arm_pic_static_addr (orig, reg); else { - rtx pat; - rtx mem; - /* If this function doesn't have a pic register, create one now. */ require_pic_register (pic_reg, compute_now); if (pic_reg == NULL_RTX) pic_reg = cfun->machine->pic_reg; - pat = gen_calculate_pic_address (reg, pic_reg, orig); - - /* Make the MEM as close to a constant as possible. */ - mem = SET_SRC (pat); - gcc_assert (MEM_P (mem) && !MEM_VOLATILE_P (mem)); - MEM_READONLY_P (mem) = 1; - MEM_NOTRAP_P (mem) = 1; - - insn = emit_insn (pat); + insn = calculate_pic_address_constant (reg, pic_reg, orig); } /* Put a REG_EQUAL note on this insn, so that it can be optimized @@ -7677,7 +7701,9 @@ arm_load_pic_register (unsigned long saved_regs ATTRIBUTE_UNUSED, rtx pic_reg) { rtx l1, labelno, pic_tmp, pic_rtx; - if (crtl->uses_pic_offset_table == 0 || TARGET_SINGLE_PIC_BASE) + if (crtl->uses_pic_offset_table == 0 + || TARGET_SINGLE_PIC_BASE + || TARGET_FDPIC) return; gcc_assert (flag_pic); @@ -7746,28 +7772,128 @@ arm_load_pic_register (unsigned long saved_regs ATTRIBUTE_UNUSED, rtx pic_reg) emit_use (pic_reg); } +/* Try to determine whether an object, referenced via ORIG, will be + placed in the text or data segment. This is used in FDPIC mode, to + decide which relocations to use when accessing ORIG. *IS_READONLY + is set to true if ORIG is a read-only location, false otherwise. + Return true if we could determine the location of ORIG, false + otherwise. *IS_READONLY is valid only when we return true. */ +static bool +arm_is_segment_info_known (rtx orig, bool *is_readonly) +{ + *is_readonly = false; + + if (GET_CODE (orig) == LABEL_REF) + { + *is_readonly = true; + return true; + } + + if (SYMBOL_REF_P (orig)) + { + if (CONSTANT_POOL_ADDRESS_P (orig)) + { + *is_readonly = true; + return true; + } + if (SYMBOL_REF_LOCAL_P (orig) + && !SYMBOL_REF_EXTERNAL_P (orig) + && SYMBOL_REF_DECL (orig) + && (!DECL_P (SYMBOL_REF_DECL (orig)) + || !DECL_COMMON (SYMBOL_REF_DECL (orig)))) + { + tree decl = SYMBOL_REF_DECL (orig); + tree init = (TREE_CODE (decl) == VAR_DECL) + ? DECL_INITIAL (decl) : (TREE_CODE (decl) == CONSTRUCTOR) + ? decl : 0; + int reloc = 0; + bool named_section, readonly; + + if (init && init != error_mark_node) + reloc = compute_reloc_for_constant (init); + + named_section = TREE_CODE (decl) == VAR_DECL + && lookup_attribute ("section", DECL_ATTRIBUTES (decl)); + readonly = decl_readonly_section (decl, reloc); + + /* We don't know where the link script will put a named + section, so return false in such a case. */ + if (named_section) + return false; + + *is_readonly = readonly; + return true; + } + + /* We don't know. */ + return false; + } + + gcc_unreachable (); +} + /* Generate code to load the address of a static var when flag_pic is set. */ static rtx_insn * arm_pic_static_addr (rtx orig, rtx reg) { rtx l1, labelno, offset_rtx; + rtx_insn *insn; gcc_assert (flag_pic); - /* We use an UNSPEC rather than a LABEL_REF because this label - never appears in the code stream. */ - labelno = GEN_INT (pic_labelno++); - l1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL); - l1 = gen_rtx_CONST (VOIDmode, l1); + bool is_readonly = false; + bool info_known = false; - /* On the ARM the PC register contains 'dot + 8' at the time of the - addition, on the Thumb it is 'dot + 4'. */ - offset_rtx = plus_constant (Pmode, l1, TARGET_ARM ? 8 : 4); - offset_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, orig, offset_rtx), - UNSPEC_SYMBOL_OFFSET); - offset_rtx = gen_rtx_CONST (Pmode, offset_rtx); + if (TARGET_FDPIC + && SYMBOL_REF_P (orig) + && !SYMBOL_REF_FUNCTION_P (orig)) + info_known = arm_is_segment_info_known (orig, &is_readonly); - return emit_insn (gen_pic_load_addr_unified (reg, offset_rtx, labelno)); + if (TARGET_FDPIC + && SYMBOL_REF_P (orig) + && !SYMBOL_REF_FUNCTION_P (orig) + && !info_known) + { + /* We don't know where orig is stored, so we have be + pessimistic and use a GOT relocation. */ + rtx pic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM); + + insn = calculate_pic_address_constant (reg, pic_reg, orig); + } + else if (TARGET_FDPIC + && SYMBOL_REF_P (orig) + && (SYMBOL_REF_FUNCTION_P (orig) + || !is_readonly)) + { + /* We use the GOTOFF relocation. */ + rtx pic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM); + + rtx l1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, orig), UNSPEC_PIC_SYM); + emit_insn (gen_movsi (reg, l1)); + insn = emit_insn (gen_addsi3 (reg, reg, pic_reg)); + } + else + { + /* Not FDPIC, not SYMBOL_REF_P or readonly: we can use + PC-relative access. */ + /* We use an UNSPEC rather than a LABEL_REF because this label + never appears in the code stream. */ + labelno = GEN_INT (pic_labelno++); + l1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL); + l1 = gen_rtx_CONST (VOIDmode, l1); + + /* On the ARM the PC register contains 'dot + 8' at the time of the + addition, on the Thumb it is 'dot + 4'. */ + offset_rtx = plus_constant (Pmode, l1, TARGET_ARM ? 8 : 4); + offset_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, orig, offset_rtx), + UNSPEC_SYMBOL_OFFSET); + offset_rtx = gen_rtx_CONST (Pmode, offset_rtx); + + insn = emit_insn (gen_pic_load_addr_unified (reg, offset_rtx, + labelno)); + } + + return insn; } /* Return nonzero if X is valid as an ARM state addressing register. */ @@ -16051,9 +16177,32 @@ get_jump_table_size (rtx_jump_table_data *insn) return 0; } +/* Emit insns to load the function address from FUNCDESC (an FDPIC + function descriptor) into a register and the GOT address into the + FDPIC register, returning an rtx for the register holding the + function address. */ + +rtx +arm_load_function_descriptor (rtx funcdesc) +{ + rtx fnaddr_reg = gen_reg_rtx (Pmode); + rtx pic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM); + rtx fnaddr = gen_rtx_MEM (Pmode, funcdesc); + rtx gotaddr = gen_rtx_MEM (Pmode, plus_constant (Pmode, funcdesc, 4)); + + emit_move_insn (fnaddr_reg, fnaddr); + + /* The ABI requires the entry point address to be loaded first, but + since we cannot support lazy binding for lack of atomic load of + two 32-bits values, we do not need to bother to prevent the + previous load from being moved after that of the GOT address. */ + emit_insn (gen_restore_pic_register_after_call (pic_reg, gotaddr)); + + return fnaddr_reg; +} + /* Return the maximum amount of padding that will be inserted before label LABEL. */ - static HOST_WIDE_INT get_label_padding (rtx label) { @@ -18188,6 +18337,12 @@ arm_emit_call_insn (rtx pat, rtx addr, bool sibcall) use_reg (&CALL_INSN_FUNCTION_USAGE (insn), cfun->machine->pic_reg); } + if (TARGET_FDPIC) + { + rtx fdpic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM); + use_reg (&CALL_INSN_FUNCTION_USAGE (insn), fdpic_reg); + } + if (TARGET_AAPCS_BASED) { /* For AAPCS, IP and CC can be clobbered by veneers inserted by the @@ -23010,10 +23165,36 @@ arm_assemble_integer (rtx x, unsigned int size, int aligned_p) && (!SYMBOL_REF_LOCAL_P (x) || (SYMBOL_REF_DECL (x) ? DECL_WEAK (SYMBOL_REF_DECL (x)) : 0)))) - fputs ("(GOT)", asm_out_file); + { + if (TARGET_FDPIC && SYMBOL_REF_FUNCTION_P (x)) + fputs ("(GOTFUNCDESC)", asm_out_file); + else + fputs ("(GOT)", asm_out_file); + } else - fputs ("(GOTOFF)", asm_out_file); + { + if (TARGET_FDPIC && SYMBOL_REF_FUNCTION_P (x)) + fputs ("(GOTOFFFUNCDESC)", asm_out_file); + else + { + bool is_readonly; + + if (!TARGET_FDPIC + || arm_is_segment_info_known (x, &is_readonly)) + fputs ("(GOTOFF)", asm_out_file); + else + fputs ("(GOT)", asm_out_file); + } + } } + + /* For FDPIC we also have to mark symbol for .data section. */ + if (TARGET_FDPIC + && !making_const_table + && SYMBOL_REF_P (x) + && SYMBOL_REF_FUNCTION_P (x)) + fputs ("(FUNCDESC)", asm_out_file); + fputc ('\n', asm_out_file); return true; } diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 8b92c83..e404e2c 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -885,6 +885,9 @@ extern int arm_arch_cmse; Pascal), so the following is not true. */ #define STATIC_CHAIN_REGNUM 12 +/* r9 is the FDPIC register (base register for GOT and FUNCDESC accesses). */ +#define FDPIC_REGNUM 9 + /* Define this to be where the real frame pointer is if it is not possible to work out the offset between the frame pointer and the automatic variables until after register allocation has taken place. FRAME_POINTER_REGNUM @@ -1941,6 +1944,10 @@ extern unsigned arm_pic_register; data addresses in memory. */ #define PIC_OFFSET_TABLE_REGNUM arm_pic_register +/* For FDPIC, the FDPIC register is call-clobbered (otherwise PLT + entries would need to handle saving and restoring it). */ +#define PIC_OFFSET_TABLE_REG_CALL_CLOBBERED TARGET_FDPIC + /* We can't directly access anything that contains a symbol, nor can we indirect via the constant pool. One exception is UNSPEC_TLS, which is always PIC. */ diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index e236831..027febb 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -7601,6 +7601,11 @@ : !REG_P (callee)) XEXP (operands[0], 0) = force_reg (Pmode, callee); + if (TARGET_FDPIC && !SYMBOL_REF_P (XEXP (operands[0], 0))) + /* Indirect call: set r9 with FDPIC value of callee. */ + XEXP (operands[0], 0) + = arm_load_function_descriptor (XEXP (operands[0], 0)); + if (detect_cmse_nonsecure_call (addr)) { pat = gen_nonsecure_call_internal (operands[0], operands[1], @@ -7612,10 +7617,33 @@ pat = gen_call_internal (operands[0], operands[1], operands[2]); arm_emit_call_insn (pat, XEXP (operands[0], 0), false); } + + /* Restore FDPIC register (r9) after call. */ + if (TARGET_FDPIC) + { + rtx fdpic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM); + rtx initial_fdpic_reg + = get_hard_reg_initial_val (Pmode, FDPIC_REGNUM); + + emit_insn (gen_restore_pic_register_after_call (fdpic_reg, + initial_fdpic_reg)); + } + DONE; }" ) +(define_insn "restore_pic_register_after_call" + [(set (match_operand:SI 0 "s_register_operand" "+r,r") + (unspec:SI [(match_dup 0) + (match_operand:SI 1 "nonimmediate_operand" "r,m")] + UNSPEC_PIC_RESTORE))] + "" + "@ + mov\t%0, %1 + ldr\t%0, %1" +) + (define_expand "call_internal" [(parallel [(call (match_operand 0 "memory_operand") (match_operand 1 "general_operand")) @@ -7689,6 +7717,11 @@ : !REG_P (callee)) XEXP (operands[1], 0) = force_reg (Pmode, callee); + if (TARGET_FDPIC && !SYMBOL_REF_P (XEXP (operands[1], 0))) + /* Indirect call: set r9 with FDPIC value of callee. */ + XEXP (operands[1], 0) + = arm_load_function_descriptor (XEXP (operands[1], 0)); + if (detect_cmse_nonsecure_call (addr)) { pat = gen_nonsecure_call_value_internal (operands[0], operands[1], @@ -7701,6 +7734,18 @@ operands[2], operands[3]); arm_emit_call_insn (pat, XEXP (operands[1], 0), false); } + + /* Restore FDPIC register (r9) after call. */ + if (TARGET_FDPIC) + { + rtx fdpic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM); + rtx initial_fdpic_reg + = get_hard_reg_initial_val (Pmode, FDPIC_REGNUM); + + emit_insn (gen_restore_pic_register_after_call (fdpic_reg, + initial_fdpic_reg)); + } + DONE; }" ) @@ -8043,7 +8088,7 @@ (const_int 0)) (match_operand 1 "" "") (match_operand 2 "" "")])] - "TARGET_EITHER" + "TARGET_EITHER && !TARGET_FDPIC" " { int i; @@ -8110,7 +8155,7 @@ (define_expand "untyped_return" [(match_operand:BLK 0 "memory_operand") (match_operand 1 "" "")] - "TARGET_EITHER" + "TARGET_EITHER && !TARGET_FDPIC" " { int i; diff --git a/gcc/config/arm/unspecs.md b/gcc/config/arm/unspecs.md index 41068ba..a9f99d0 100644 --- a/gcc/config/arm/unspecs.md +++ b/gcc/config/arm/unspecs.md @@ -89,6 +89,7 @@ UNSPEC_SP_SET ; Represent the setting of stack protector's canary UNSPEC_SP_TEST ; Represent the testing of stack protector's canary ; against the guard. + UNSPEC_PIC_RESTORE ; Use to restore fdpic register ]) (define_c_enum "unspec" [ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f738a23..f277621 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2019-09-10 Christophe Lyon + Mickaël Guêné + + * gcc.target/arm/fp16-aapcs-2.c: Adjust scan-assembler-times. + * gcc.target/arm/fp16-aapcs-4.c: Likewise. + 2019-09-09 Marek Polacek PR c++/84374 - diagnose invalid uses of decltype(auto). diff --git a/gcc/testsuite/gcc.target/arm/fp16-aapcs-2.c b/gcc/testsuite/gcc.target/arm/fp16-aapcs-2.c index 4753e36..51a76fc 100644 --- a/gcc/testsuite/gcc.target/arm/fp16-aapcs-2.c +++ b/gcc/testsuite/gcc.target/arm/fp16-aapcs-2.c @@ -17,5 +17,5 @@ F (__fp16 a, __fp16 b, __fp16 c) } /* { dg-final { scan-assembler-times {mov\tr[0-9]+, r[0-2]} 3 } } */ -/* { dg-final { scan-assembler-times {mov\tr1, r0} 1 } } */ +/* { dg-final { scan-assembler-times {mov\tr1, r[03]} 1 } } */ /* { dg-final { scan-assembler-times {mov\tr0, r[0-9]+} 2 } } */ diff --git a/gcc/testsuite/gcc.target/arm/fp16-aapcs-4.c b/gcc/testsuite/gcc.target/arm/fp16-aapcs-4.c index 41c7ab7..ae65fb8 100644 --- a/gcc/testsuite/gcc.target/arm/fp16-aapcs-4.c +++ b/gcc/testsuite/gcc.target/arm/fp16-aapcs-4.c @@ -16,5 +16,5 @@ F (__fp16 a, __fp16 b, __fp16 c) } /* { dg-final { scan-assembler-times {mov\tr[0-9]+, r[0-2]} 3 } } */ -/* { dg-final { scan-assembler-times {mov\tr1, r0} 1 } } */ +/* { dg-final { scan-assembler-times {mov\tr1, r[03]} 1 } } */ /* { dg-final { scan-assembler-times {mov\tr0, r[0-9]+} 2 } } */ -- cgit v1.1 From 5d727a4b20257275df59182b00f3bf240772cd0d Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Tue, 10 Sep 2019 09:47:49 +0200 Subject: [ARM/FDPIC v6 06/24] [ARM] FDPIC: Add support for c++ exceptions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The main difference with existing support is that function addresses are function descriptor addresses instead. This means that all code dealing with function pointers now has to cope with function descriptors instead. For the same reason, Linux kernel helpers can no longer be called by dereferencing their address, so we implement wrappers that directly call the kernel helpers. When restoring a function address, we also have to restore the FDPIC register value (r9). 2019-09-10 Christophe Lyon Mickaël Guêné gcc/ * ginclude/unwind-arm-common.h (unwinder_cache): Add reserved5 field. libgcc/ * config/arm/linux-atomic.c (__kernel_cmpxchg): Add FDPIC support. (__kernel_dmb): Likewise. (__fdpic_cmpxchg): New function. (__fdpic_dmb): New function. * config/arm/unwind-arm.h (FDPIC_REGNUM): New define. (gnu_Unwind_Find_got): New function. (_Unwind_decode_typeinfo_ptr): Add FDPIC support. * unwind-arm-common.inc (UCB_PR_GOT): New. (funcdesc_t): New struct. (get_eit_entry): Add FDPIC support. (unwind_phase2): Likewise. (unwind_phase2_forced): Likewise. (__gnu_Unwind_RaiseException): Likewise. (__gnu_Unwind_Resume): Likewise. (__gnu_Unwind_Backtrace): Likewise. * unwind-pe.h (read_encoded_value_with_base): Likewise. libstdc++/ * libsupc++/eh_personality.cc (get_ttype_entry): Add FDPIC support. Co-Authored-By: Mickaël Guêné From-SVN: r275568 --- gcc/ChangeLog | 6 ++++++ gcc/ginclude/unwind-arm-common.h | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 62fb38a..a212eb3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,12 @@ 2019-09-10 Christophe Lyon Mickaël Guêné + * ginclude/unwind-arm-common.h (unwinder_cache): Add reserved5 + field. + +2019-09-10 Christophe Lyon + Mickaël Guêné + * config/arm/arm-c.c (__FDPIC__): Define new pre-processor macro in FDPIC mode. * config/arm/arm-protos.h (arm_load_function_descriptor): Declare diff --git a/gcc/ginclude/unwind-arm-common.h b/gcc/ginclude/unwind-arm-common.h index 6df783e..d4eb03e 100644 --- a/gcc/ginclude/unwind-arm-common.h +++ b/gcc/ginclude/unwind-arm-common.h @@ -91,7 +91,7 @@ extern "C" { _uw reserved2; /* Personality routine address */ _uw reserved3; /* Saved callsite address */ _uw reserved4; /* Forced unwind stop arg */ - _uw reserved5; + _uw reserved5; /* Personality routine GOT value in FDPIC mode. */ } unwinder_cache; /* Propagation barrier cache (valid after phase 1): */ -- cgit v1.1 From 4997c9aed45b4439474005c4c71fac65151d1719 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Tue, 10 Sep 2019 09:49:20 +0200 Subject: [ARM/FDPIC v6 07/24] [ARM] FDPIC: Avoid saving/restoring r9 on stack since it is read-only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2019-09-10 Christophe Lyon Mickaël Guêné gcc/ * config/arm/arm.h (PIC_REGISTER_MAY_NEED_SAVING): New helper. * config/arm/arm.c (arm_compute_save_reg0_reg12_mask): Handle FDPIC. Co-Authored-By: Mickaël Guêné From-SVN: r275569 --- gcc/ChangeLog | 7 +++++++ gcc/config/arm/arm.c | 8 ++------ gcc/config/arm/arm.h | 7 +++++++ 3 files changed, 16 insertions(+), 6 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a212eb3..7b061d1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,13 @@ 2019-09-10 Christophe Lyon Mickaël Guêné + * config/arm/arm.h (PIC_REGISTER_MAY_NEED_SAVING): New helper. + * config/arm/arm.c (arm_compute_save_reg0_reg12_mask): Handle + FDPIC. + +2019-09-10 Christophe Lyon + Mickaël Guêné + * ginclude/unwind-arm-common.h (unwinder_cache): Add reserved5 field. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index c34aab8..6ff3001 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -19571,9 +19571,7 @@ arm_compute_save_reg0_reg12_mask (void) save_reg_mask |= (1 << reg); /* Also save the pic base register if necessary. */ - if (flag_pic - && !TARGET_SINGLE_PIC_BASE - && arm_pic_register != INVALID_REGNUM + if (PIC_REGISTER_MAY_NEED_SAVING && crtl->uses_pic_offset_table) save_reg_mask |= 1 << PIC_OFFSET_TABLE_REGNUM; } @@ -19605,9 +19603,7 @@ arm_compute_save_reg0_reg12_mask (void) /* If we aren't loading the PIC register, don't stack it even though it may be live. */ - if (flag_pic - && !TARGET_SINGLE_PIC_BASE - && arm_pic_register != INVALID_REGNUM + if (PIC_REGISTER_MAY_NEED_SAVING && (df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM) || crtl->uses_pic_offset_table)) save_reg_mask |= 1 << PIC_OFFSET_TABLE_REGNUM; diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index e404e2c..490d22d 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -1960,6 +1960,13 @@ extern unsigned arm_pic_register; || label_mentioned_p (get_pool_constant (X))))) \ || tls_mentioned_p (X)) +/* We may want to save the PIC register if it is a dedicated one. */ +#define PIC_REGISTER_MAY_NEED_SAVING \ + (flag_pic \ + && !TARGET_SINGLE_PIC_BASE \ + && !TARGET_FDPIC \ + && arm_pic_register != INVALID_REGNUM) + /* We need to know when we are making a constant pool; this determines whether data needs to be in the GOT or can be referenced via a GOT offset. */ -- cgit v1.1 From 96ef8d00f70f076933eea68124043e9ba675412d Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Tue, 10 Sep 2019 09:50:43 +0200 Subject: [ARM/FDPIC v6 08/24] [ARM] FDPIC: Enforce local/global binding for function descriptors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use local binding rules to decide whether we can use GOTOFFFUNCDESC to compute the function address. 2019-09-10 Christophe Lyon Mickaël Guêné gcc/ * config/arm/arm.c (arm_fdpic_local_funcdesc_p): New function. (legitimize_pic_address): Enforce binding rules on function pointers in FDPIC mode. (arm_assemble_integer): Likewise. Co-Authored-By: Mickaël Guêné From-SVN: r275570 --- gcc/ChangeLog | 8 ++++++++ gcc/config/arm/arm.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 50 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7b061d1..36a20df 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,14 @@ 2019-09-10 Christophe Lyon Mickaël Guêné + * config/arm/arm.c (arm_fdpic_local_funcdesc_p): New function. + (legitimize_pic_address): Enforce binding rules on function + pointers in FDPIC mode. + (arm_assemble_integer): Likewise. + +2019-09-10 Christophe Lyon + Mickaël Guêné + * config/arm/arm.h (PIC_REGISTER_MAY_NEED_SAVING): New helper. * config/arm/arm.c (arm_compute_save_reg0_reg12_mask): Handle FDPIC. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 6ff3001..6b0c95f 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -3754,6 +3754,42 @@ arm_options_perform_arch_sanity_checks (void) } } +/* Test whether a local function descriptor is canonical, i.e., + whether we can use GOTOFFFUNCDESC to compute the address of the + function. */ +static bool +arm_fdpic_local_funcdesc_p (rtx fnx) +{ + tree fn; + enum symbol_visibility vis; + bool ret; + + if (!TARGET_FDPIC) + return true; + + if (! SYMBOL_REF_LOCAL_P (fnx)) + return false; + + fn = SYMBOL_REF_DECL (fnx); + + if (! fn) + return false; + + vis = DECL_VISIBILITY (fn); + + if (vis == VISIBILITY_PROTECTED) + /* Private function descriptors for protected functions are not + canonical. Temporarily change the visibility to global so that + we can ensure uniqueness of funcdesc pointers. */ + DECL_VISIBILITY (fn) = VISIBILITY_DEFAULT; + + ret = default_binds_local_p_1 (fn, flag_pic); + + DECL_VISIBILITY (fn) = vis; + + return ret; +} + static void arm_add_gc_roots (void) { @@ -7534,7 +7570,9 @@ legitimize_pic_address (rtx orig, machine_mode mode, rtx reg, rtx pic_reg, || (GET_CODE (orig) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (orig) && (SYMBOL_REF_DECL (orig) - ? !DECL_WEAK (SYMBOL_REF_DECL (orig)) : 1))) + ? !DECL_WEAK (SYMBOL_REF_DECL (orig)) : 1) + && (!SYMBOL_REF_FUNCTION_P (orig) + || arm_fdpic_local_funcdesc_p (orig)))) && NEED_GOT_RELOC && arm_pic_data_is_text_relative) insn = arm_pic_static_addr (orig, reg); @@ -23160,7 +23198,9 @@ arm_assemble_integer (rtx x, unsigned int size, int aligned_p) || (GET_CODE (x) == SYMBOL_REF && (!SYMBOL_REF_LOCAL_P (x) || (SYMBOL_REF_DECL (x) - ? DECL_WEAK (SYMBOL_REF_DECL (x)) : 0)))) + ? DECL_WEAK (SYMBOL_REF_DECL (x)) : 0) + || (SYMBOL_REF_FUNCTION_P (x) + && !arm_fdpic_local_funcdesc_p (x))))) { if (TARGET_FDPIC && SYMBOL_REF_FUNCTION_P (x)) fputs ("(GOTFUNCDESC)", asm_out_file); -- cgit v1.1 From bc87cffb13c836cc72b37dfd90544c7c21268702 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Tue, 10 Sep 2019 09:52:02 +0200 Subject: [ARM/FDPIC v6 09/24] [ARM] FDPIC: Add support for taking address of nested function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In FDPIC mode, the trampoline generated to support pointers to nested functions looks like: .word trampoline address .word trampoline GOT address ldr r12, [pc, #8] ldr r9, [pc, #8] ldr pc, [pc, #8] .word static chain value .word GOT address .word function's address because in FDPIC function pointers are actually pointers to function descriptors, we have to actually generate a function descriptor for the trampoline. 2019--09-10 Christophe Lyon Mickaël Guêné gcc/ * config/arm/arm.c (arm_asm_trampoline_template): Add FDPIC support. (arm_trampoline_init): Likewise. (arm_trampoline_adjust_address): Likewise. * config/arm/arm.h (TRAMPOLINE_SIZE): Likewise. Co-Authored-By: Mickaël Guêné From-SVN: r275571 --- gcc/ChangeLog | 10 +++++++ gcc/config/arm/arm.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++----- gcc/config/arm/arm.h | 2 +- 3 files changed, 87 insertions(+), 9 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 36a20df..1bfa16d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,16 @@ 2019-09-10 Christophe Lyon Mickaël Guêné + gcc/ + * config/arm/arm.c (arm_asm_trampoline_template): Add FDPIC + support. + (arm_trampoline_init): Likewise. + (arm_trampoline_adjust_address): Likewise. + * config/arm/arm.h (TRAMPOLINE_SIZE): Likewise. + +2019-09-10 Christophe Lyon + Mickaël Guêné + * config/arm/arm.c (arm_fdpic_local_funcdesc_p): New function. (legitimize_pic_address): Enforce binding rules on function pointers in FDPIC mode. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 6b0c95f..d01fae3 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -3939,14 +3939,52 @@ arm_warn_func_return (tree decl) ldr pc, [pc] .word static chain value .word function's address - XXX FIXME: When the trampoline returns, r8 will be clobbered. */ + XXX FIXME: When the trampoline returns, r8 will be clobbered. + + In FDPIC mode, the trampoline looks like: + .word trampoline address + .word trampoline GOT address + ldr r12, [pc, #8] ; #4 for Arm mode + ldr r9, [pc, #8] ; #4 for Arm mode + ldr pc, [pc, #8] ; #4 for Arm mode + .word static chain value + .word GOT address + .word function's address +*/ static void arm_asm_trampoline_template (FILE *f) { fprintf (f, "\t.syntax unified\n"); - if (TARGET_ARM) + if (TARGET_FDPIC) + { + /* The first two words are a function descriptor pointing to the + trampoline code just below. */ + if (TARGET_ARM) + fprintf (f, "\t.arm\n"); + else if (TARGET_THUMB2) + fprintf (f, "\t.thumb\n"); + else + /* Only ARM and Thumb-2 are supported. */ + gcc_unreachable (); + + assemble_aligned_integer (UNITS_PER_WORD, const0_rtx); + assemble_aligned_integer (UNITS_PER_WORD, const0_rtx); + /* Trampoline code which sets the static chain register but also + PIC register before jumping into real code. */ + asm_fprintf (f, "\tldr\t%r, [%r, #%d]\n", + STATIC_CHAIN_REGNUM, PC_REGNUM, + TARGET_THUMB2 ? 8 : 4); + asm_fprintf (f, "\tldr\t%r, [%r, #%d]\n", + PIC_OFFSET_TABLE_REGNUM, PC_REGNUM, + TARGET_THUMB2 ? 8 : 4); + asm_fprintf (f, "\tldr\t%r, [%r, #%d]\n", + PC_REGNUM, PC_REGNUM, + TARGET_THUMB2 ? 8 : 4); + assemble_aligned_integer (UNITS_PER_WORD, const0_rtx); + } + else if (TARGET_ARM) { fprintf (f, "\t.arm\n"); asm_fprintf (f, "\tldr\t%r, [%r, #0]\n", STATIC_CHAIN_REGNUM, PC_REGNUM); @@ -3987,12 +4025,40 @@ arm_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) emit_block_move (m_tramp, assemble_trampoline_template (), GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL); - mem = adjust_address (m_tramp, SImode, TARGET_32BIT ? 8 : 12); - emit_move_insn (mem, chain_value); + if (TARGET_FDPIC) + { + rtx funcdesc = XEXP (DECL_RTL (fndecl), 0); + rtx fnaddr = gen_rtx_MEM (Pmode, funcdesc); + rtx gotaddr = gen_rtx_MEM (Pmode, plus_constant (Pmode, funcdesc, 4)); + /* The function start address is at offset 8, but in Thumb mode + we want bit 0 set to 1 to indicate Thumb-ness, hence 9 + below. */ + rtx trampoline_code_start + = plus_constant (Pmode, XEXP (m_tramp, 0), TARGET_THUMB2 ? 9 : 8); + + /* Write initial funcdesc which points to the trampoline. */ + mem = adjust_address (m_tramp, SImode, 0); + emit_move_insn (mem, trampoline_code_start); + mem = adjust_address (m_tramp, SImode, 4); + emit_move_insn (mem, gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM)); + /* Setup static chain. */ + mem = adjust_address (m_tramp, SImode, 20); + emit_move_insn (mem, chain_value); + /* GOT + real function entry point. */ + mem = adjust_address (m_tramp, SImode, 24); + emit_move_insn (mem, gotaddr); + mem = adjust_address (m_tramp, SImode, 28); + emit_move_insn (mem, fnaddr); + } + else + { + mem = adjust_address (m_tramp, SImode, TARGET_32BIT ? 8 : 12); + emit_move_insn (mem, chain_value); - mem = adjust_address (m_tramp, SImode, TARGET_32BIT ? 12 : 16); - fnaddr = XEXP (DECL_RTL (fndecl), 0); - emit_move_insn (mem, fnaddr); + mem = adjust_address (m_tramp, SImode, TARGET_32BIT ? 12 : 16); + fnaddr = XEXP (DECL_RTL (fndecl), 0); + emit_move_insn (mem, fnaddr); + } a_tramp = XEXP (m_tramp, 0); emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__clear_cache"), @@ -4006,7 +4072,9 @@ arm_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) static rtx arm_trampoline_adjust_address (rtx addr) { - if (TARGET_THUMB) + /* For FDPIC don't fix trampoline address since it's a function + descriptor and not a function address. */ + if (TARGET_THUMB && !TARGET_FDPIC) addr = expand_simple_binop (Pmode, IOR, addr, const1_rtx, NULL, 0, OPTAB_LIB_WIDEN); return addr; diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 490d22d..8b67c9c 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -1595,7 +1595,7 @@ typedef struct #define INIT_EXPANDERS arm_init_expanders () /* Length in units of the trampoline for entering a nested function. */ -#define TRAMPOLINE_SIZE (TARGET_32BIT ? 16 : 20) +#define TRAMPOLINE_SIZE (TARGET_FDPIC ? 32 : (TARGET_32BIT ? 16 : 20)) /* Alignment required for a trampoline in bits. */ #define TRAMPOLINE_ALIGNMENT 32 -- cgit v1.1 From e844c94f2a178b8f529a484ed0600b546c59c549 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Tue, 10 Sep 2019 09:53:12 +0200 Subject: [ARM/FDPIC v6 10/24] [ARM] FDPIC: Implement TLS support. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Support additional relocations: TLS_GD32_FDPIC, TLS_LDM32_FDPIC, and TLS_IE32_FDPIC. We do not support the GNU2 TLS dialect. 2019-09-10 Christophe Lyon Mickaël Guêné gcc/ * config/arm/arm.c (tls_reloc): Add TLS_GD32_FDPIC, TLS_LDM32_FDPIC and TLS_IE32_FDPIC. (arm_call_tls_get_addr): Add FDPIC support. (legitimize_tls_address): Likewise. (arm_emit_tls_decoration): Likewise. Co-Authored-By: Mickaël Guêné From-SVN: r275572 --- gcc/ChangeLog | 10 ++++++ gcc/config/arm/arm.c | 98 ++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 82 insertions(+), 26 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1bfa16d..eff0141 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -2,6 +2,16 @@ Mickaël Guêné gcc/ + * config/arm/arm.c (tls_reloc): Add TLS_GD32_FDPIC, + TLS_LDM32_FDPIC and TLS_IE32_FDPIC. + (arm_call_tls_get_addr): Add FDPIC support. + (legitimize_tls_address): Likewise. + (arm_emit_tls_decoration): Likewise. + +2019-09-10 Christophe Lyon + Mickaël Guêné + + gcc/ * config/arm/arm.c (arm_asm_trampoline_template): Add FDPIC support. (arm_trampoline_init): Likewise. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index d01fae3..5f1d2d4 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -2350,9 +2350,12 @@ char arm_arch_name[] = "__ARM_ARCH_PROFILE__"; enum tls_reloc { TLS_GD32, + TLS_GD32_FDPIC, TLS_LDM32, + TLS_LDM32_FDPIC, TLS_LDO32, TLS_IE32, + TLS_IE32_FDPIC, TLS_LE32, TLS_DESCSEQ /* GNU scheme */ }; @@ -8708,22 +8711,33 @@ load_tls_operand (rtx x, rtx reg) static rtx_insn * arm_call_tls_get_addr (rtx x, rtx reg, rtx *valuep, int reloc) { - rtx label, labelno, sum; + rtx label, labelno = NULL_RTX, sum; gcc_assert (reloc != TLS_DESCSEQ); start_sequence (); - labelno = GEN_INT (pic_labelno++); - label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL); - label = gen_rtx_CONST (VOIDmode, label); + if (TARGET_FDPIC) + { + sum = gen_rtx_UNSPEC (Pmode, + gen_rtvec (2, x, GEN_INT (reloc)), + UNSPEC_TLS); + } + else + { + labelno = GEN_INT (pic_labelno++); + label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL); + label = gen_rtx_CONST (VOIDmode, label); - sum = gen_rtx_UNSPEC (Pmode, - gen_rtvec (4, x, GEN_INT (reloc), label, - GEN_INT (TARGET_ARM ? 8 : 4)), - UNSPEC_TLS); + sum = gen_rtx_UNSPEC (Pmode, + gen_rtvec (4, x, GEN_INT (reloc), label, + GEN_INT (TARGET_ARM ? 8 : 4)), + UNSPEC_TLS); + } reg = load_tls_operand (sum, reg); - if (TARGET_ARM) + if (TARGET_FDPIC) + emit_insn (gen_addsi3 (reg, reg, gen_rtx_REG (Pmode, FDPIC_REGNUM))); + else if (TARGET_ARM) emit_insn (gen_pic_add_dot_plus_eight (reg, reg, labelno)); else emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno)); @@ -8761,6 +8775,7 @@ arm_tls_descseq_addr (rtx x, rtx reg) return reg; } + rtx legitimize_tls_address (rtx x, rtx reg) { @@ -8773,6 +8788,8 @@ legitimize_tls_address (rtx x, rtx reg) case TLS_MODEL_GLOBAL_DYNAMIC: if (TARGET_GNU2_TLS) { + gcc_assert (!TARGET_FDPIC); + reg = arm_tls_descseq_addr (x, reg); tp = arm_load_tp (NULL_RTX); @@ -8782,7 +8799,10 @@ legitimize_tls_address (rtx x, rtx reg) else { /* Original scheme */ - insns = arm_call_tls_get_addr (x, reg, &ret, TLS_GD32); + if (TARGET_FDPIC) + insns = arm_call_tls_get_addr (x, reg, &ret, TLS_GD32_FDPIC); + else + insns = arm_call_tls_get_addr (x, reg, &ret, TLS_GD32); dest = gen_reg_rtx (Pmode); emit_libcall_block (insns, dest, ret, x); } @@ -8791,6 +8811,8 @@ legitimize_tls_address (rtx x, rtx reg) case TLS_MODEL_LOCAL_DYNAMIC: if (TARGET_GNU2_TLS) { + gcc_assert (!TARGET_FDPIC); + reg = arm_tls_descseq_addr (x, reg); tp = arm_load_tp (NULL_RTX); @@ -8799,7 +8821,10 @@ legitimize_tls_address (rtx x, rtx reg) } else { - insns = arm_call_tls_get_addr (x, reg, &ret, TLS_LDM32); + if (TARGET_FDPIC) + insns = arm_call_tls_get_addr (x, reg, &ret, TLS_LDM32_FDPIC); + else + insns = arm_call_tls_get_addr (x, reg, &ret, TLS_LDM32); /* Attach a unique REG_EQUIV, to allow the RTL optimizers to share the LDM result with other LD model accesses. */ @@ -8818,23 +8843,35 @@ legitimize_tls_address (rtx x, rtx reg) return dest; case TLS_MODEL_INITIAL_EXEC: - labelno = GEN_INT (pic_labelno++); - label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL); - label = gen_rtx_CONST (VOIDmode, label); - sum = gen_rtx_UNSPEC (Pmode, - gen_rtvec (4, x, GEN_INT (TLS_IE32), label, - GEN_INT (TARGET_ARM ? 8 : 4)), - UNSPEC_TLS); - reg = load_tls_operand (sum, reg); - - if (TARGET_ARM) - emit_insn (gen_tls_load_dot_plus_eight (reg, reg, labelno)); - else if (TARGET_THUMB2) - emit_insn (gen_tls_load_dot_plus_four (reg, NULL, reg, labelno)); + if (TARGET_FDPIC) + { + sum = gen_rtx_UNSPEC (Pmode, + gen_rtvec (2, x, GEN_INT (TLS_IE32_FDPIC)), + UNSPEC_TLS); + reg = load_tls_operand (sum, reg); + emit_insn (gen_addsi3 (reg, reg, gen_rtx_REG (Pmode, FDPIC_REGNUM))); + emit_move_insn (reg, gen_rtx_MEM (Pmode, reg)); + } else { - emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno)); - emit_move_insn (reg, gen_const_mem (SImode, reg)); + labelno = GEN_INT (pic_labelno++); + label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL); + label = gen_rtx_CONST (VOIDmode, label); + sum = gen_rtx_UNSPEC (Pmode, + gen_rtvec (4, x, GEN_INT (TLS_IE32), label, + GEN_INT (TARGET_ARM ? 8 : 4)), + UNSPEC_TLS); + reg = load_tls_operand (sum, reg); + + if (TARGET_ARM) + emit_insn (gen_tls_load_dot_plus_eight (reg, reg, labelno)); + else if (TARGET_THUMB2) + emit_insn (gen_tls_load_dot_plus_four (reg, NULL, reg, labelno)); + else + { + emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno)); + emit_move_insn (reg, gen_const_mem (SImode, reg)); + } } tp = arm_load_tp (NULL_RTX); @@ -28158,15 +28195,24 @@ arm_emit_tls_decoration (FILE *fp, rtx x) case TLS_GD32: fputs ("(tlsgd)", fp); break; + case TLS_GD32_FDPIC: + fputs ("(tlsgd_fdpic)", fp); + break; case TLS_LDM32: fputs ("(tlsldm)", fp); break; + case TLS_LDM32_FDPIC: + fputs ("(tlsldm_fdpic)", fp); + break; case TLS_LDO32: fputs ("(tlsldo)", fp); break; case TLS_IE32: fputs ("(gottpoff)", fp); break; + case TLS_IE32_FDPIC: + fputs ("(gottpoff_fdpic)", fp); + break; case TLS_LE32: fputs ("(tpoff)", fp); break; -- cgit v1.1 From bb33a88e3d4746470d3f969c6d764d20d726f9f1 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Tue, 10 Sep 2019 09:56:43 +0200 Subject: [ARM/FDPIC v6 12/24] [ARM] FDPIC: Restore r9 after we call __aeabi_read_tp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We call __aeabi_read_tp() to get the thread pointer. Since this is a function call, we have to restore the FDPIC register afterwards. 2019-09-10 Christophe Lyon Mickaël Guêné gcc/ * config/arm/arm.c (arm_load_tp): Add FDPIC support. * config/arm/arm.md (FDPIC_REGNUM): New constant. (load_tp_soft_fdpic): New pattern. (load_tp_soft): Disable in FDPIC mode. Co-Authored-By: Mickaël Guêné From-SVN: r275574 --- gcc/ChangeLog | 10 ++++++++-- gcc/config/arm/arm.c | 13 ++++++++++++- gcc/config/arm/arm.md | 16 +++++++++++++++- 3 files changed, 35 insertions(+), 4 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index eff0141..afe73b5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,7 +1,14 @@ 2019-09-10 Christophe Lyon Mickaël Guêné - gcc/ + * config/arm/arm.c (arm_load_tp): Add FDPIC support. + * config/arm/arm.md (FDPIC_REGNUM): New constant. + (load_tp_soft_fdpic): New pattern. + (load_tp_soft): Disable in FDPIC mode. + +2019-09-10 Christophe Lyon + Mickaël Guêné + * config/arm/arm.c (tls_reloc): Add TLS_GD32_FDPIC, TLS_LDM32_FDPIC and TLS_IE32_FDPIC. (arm_call_tls_get_addr): Add FDPIC support. @@ -11,7 +18,6 @@ 2019-09-10 Christophe Lyon Mickaël Guêné - gcc/ * config/arm/arm.c (arm_asm_trampoline_template): Add FDPIC support. (arm_trampoline_init): Likewise. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 5f1d2d4..c452771 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -8685,7 +8685,18 @@ arm_load_tp (rtx target) rtx tmp; - emit_insn (gen_load_tp_soft ()); + if (TARGET_FDPIC) + { + rtx fdpic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM); + rtx initial_fdpic_reg = get_hard_reg_initial_val (Pmode, FDPIC_REGNUM); + + emit_insn (gen_load_tp_soft_fdpic ()); + + /* Restore r9. */ + emit_insn (gen_restore_pic_register_after_call(fdpic_reg, initial_fdpic_reg)); + } + else + emit_insn (gen_load_tp_soft ()); tmp = gen_rtx_REG (SImode, R0_REGNUM); emit_move_insn (target, tmp); diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 027febb..918271d 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -31,6 +31,7 @@ [(R0_REGNUM 0) ; First CORE register (R1_REGNUM 1) ; Second CORE register (R4_REGNUM 4) ; Fifth CORE register + (FDPIC_REGNUM 9) ; FDPIC register (IP_REGNUM 12) ; Scratch register (SP_REGNUM 13) ; Stack pointer (LR_REGNUM 14) ; Return address register @@ -11165,12 +11166,25 @@ ) ;; Doesn't clobber R1-R3. Must use r0 for the first operand. +(define_insn "load_tp_soft_fdpic" + [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS)) + (clobber (reg:SI FDPIC_REGNUM)) + (clobber (reg:SI LR_REGNUM)) + (clobber (reg:SI IP_REGNUM)) + (clobber (reg:CC CC_REGNUM))] + "TARGET_SOFT_TP && TARGET_FDPIC" + "bl\\t__aeabi_read_tp\\t@ load_tp_soft" + [(set_attr "conds" "clob") + (set_attr "type" "branch")] +) + +;; Doesn't clobber R1-R3. Must use r0 for the first operand. (define_insn "load_tp_soft" [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS)) (clobber (reg:SI LR_REGNUM)) (clobber (reg:SI IP_REGNUM)) (clobber (reg:CC CC_REGNUM))] - "TARGET_SOFT_TP" + "TARGET_SOFT_TP && !TARGET_FDPIC" "bl\\t__aeabi_read_tp\\t@ load_tp_soft" [(set_attr "conds" "clob") (set_attr "type" "branch")] -- cgit v1.1 From 488bd12977b8bd6f9d5d236607ced609cc21be92 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Tue, 10 Sep 2019 10:01:15 +0200 Subject: [ARM/FDPIC v6 14/24] [ARM][testsuite] FDPIC: Skip unsupported tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Several tests cannot work on ARM-FDPIC for various reasons: skip them, or skip some directives. gcc.dg/20020312-2.c: Skip since it forces -fno-pic. gcc.target/arm/: * Skip since r9 is clobbered by assembly code: 20051215-1.c mmx-1.c pr61948.c pr77933-1.c pr77933-2.c * Skip since the test forces armv5te which is not supported by FDPIC: pr40887.c pr19599.c * Skip since FDPIC disables sibcall to external functions: sibcall-1.c tail-long-call vfp-longcall-apcs * Skip size check since it's different for FDPIC: ivopts-2.c ivopts-3.c ivopts-4.c ivopts-5.c pr43597.c pr43920-2.c * Disable assembler scanning invalid for FDPIC: pr45701-1.c pr45701-2.c stack-red-zone.c * gnu2 TLS dialect is not supported by FDPIC: tlscall.c * Test relies on symbols not generated in FDPIC: data-rel-2.c data-rel-3.c 2019-09-10 Christophe Lyon Mickaël Guêné gcc/testsuite/ * gcc.dg/20020312-2.c: Skip on arm*-*-uclinuxfdpiceabi. * gcc.target/arm/20051215-1.c: Likewise. * gcc.target/arm/mmx-1.c: Likewise. * gcc.target/arm/pr19599.c: Likewise. * gcc.target/arm/pr40887.c: Likewise. * gcc.target/arm/pr61948.c: Likewise. * gcc.target/arm/pr77933-1.c: Likewise. * gcc.target/arm/pr77933-2.c: Likewise. * gcc.target/arm/sibcall-1.c: Likewise. * gcc.target/arm/data-rel-2.c: Likewise. * gcc.target/arm/data-rel-3.c: Likewise. * gcc.target/arm/tail-long-call: Likewise. * gcc.target/arm/tlscall.c: Likewise. * gcc.target/arm/vfp-longcall-apcs: Likewise. * gcc.target/arm/ivopts-2.c: Skip object-size test on arm*-*-uclinuxfdpiceabi. * gcc.target/arm/ivopts-3.c: Likewise. * gcc.target/arm/ivopts-4.c: Likewise. * gcc.target/arm/ivopts-5.c: Likewise. * gcc.target/arm/pr43597.c: Likewise. * gcc.target/arm/pr43920-2.c: Likewise. * gcc.target/arm/pr45701-1.c: Skip scan-assembler on arm*-*-uclinuxfdpiceabi. * gcc.target/arm/pr45701-2.c: Likewise. * gcc.target/arm/stack-red-zone.c: Likewise. Co-Authored-By: Mickaël Guêné From-SVN: r275576 --- gcc/testsuite/ChangeLog | 29 ++++++++++++++++++++++++ gcc/testsuite/gcc.dg/20020312-2.c | 1 + gcc/testsuite/gcc.target/arm/20051215-1.c | 1 + gcc/testsuite/gcc.target/arm/data-rel-2.c | 1 + gcc/testsuite/gcc.target/arm/data-rel-3.c | 1 + gcc/testsuite/gcc.target/arm/ivopts-2.c | 2 +- gcc/testsuite/gcc.target/arm/ivopts-3.c | 2 +- gcc/testsuite/gcc.target/arm/ivopts-4.c | 2 +- gcc/testsuite/gcc.target/arm/ivopts-5.c | 2 +- gcc/testsuite/gcc.target/arm/mmx-1.c | 1 + gcc/testsuite/gcc.target/arm/pr19599.c | 1 + gcc/testsuite/gcc.target/arm/pr40887.c | 1 + gcc/testsuite/gcc.target/arm/pr43597.c | 2 +- gcc/testsuite/gcc.target/arm/pr43920-2.c | 2 +- gcc/testsuite/gcc.target/arm/pr45701-1.c | 4 ++-- gcc/testsuite/gcc.target/arm/pr45701-2.c | 4 ++-- gcc/testsuite/gcc.target/arm/pr61948.c | 1 + gcc/testsuite/gcc.target/arm/pr77933-1.c | 1 + gcc/testsuite/gcc.target/arm/pr77933-2.c | 1 + gcc/testsuite/gcc.target/arm/sibcall-1.c | 1 + gcc/testsuite/gcc.target/arm/stack-red-zone.c | 2 +- gcc/testsuite/gcc.target/arm/tail-long-call.c | 1 + gcc/testsuite/gcc.target/arm/tlscall.c | 1 + gcc/testsuite/gcc.target/arm/vfp-longcall-apcs.c | 1 + 24 files changed, 54 insertions(+), 11 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f277621..9b96065 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,35 @@ 2019-09-10 Christophe Lyon Mickaël Guêné + * gcc.dg/20020312-2.c: Skip on arm*-*-uclinuxfdpiceabi. + * gcc.target/arm/20051215-1.c: Likewise. + * gcc.target/arm/mmx-1.c: Likewise. + * gcc.target/arm/pr19599.c: Likewise. + * gcc.target/arm/pr40887.c: Likewise. + * gcc.target/arm/pr61948.c: Likewise. + * gcc.target/arm/pr77933-1.c: Likewise. + * gcc.target/arm/pr77933-2.c: Likewise. + * gcc.target/arm/sibcall-1.c: Likewise. + * gcc.target/arm/data-rel-2.c: Likewise. + * gcc.target/arm/data-rel-3.c: Likewise. + * gcc.target/arm/tail-long-call: Likewise. + * gcc.target/arm/tlscall.c: Likewise. + * gcc.target/arm/vfp-longcall-apcs: Likewise. + * gcc.target/arm/ivopts-2.c: Skip object-size test on + arm*-*-uclinuxfdpiceabi. + * gcc.target/arm/ivopts-3.c: Likewise. + * gcc.target/arm/ivopts-4.c: Likewise. + * gcc.target/arm/ivopts-5.c: Likewise. + * gcc.target/arm/pr43597.c: Likewise. + * gcc.target/arm/pr43920-2.c: Likewise. + * gcc.target/arm/pr45701-1.c: Skip scan-assembler on + arm*-*-uclinuxfdpiceabi. + * gcc.target/arm/pr45701-2.c: Likewise. + * gcc.target/arm/stack-red-zone.c: Likewise. + +2019-09-10 Christophe Lyon + Mickaël Guêné + * gcc.target/arm/fp16-aapcs-2.c: Adjust scan-assembler-times. * gcc.target/arm/fp16-aapcs-4.c: Likewise. diff --git a/gcc/testsuite/gcc.dg/20020312-2.c b/gcc/testsuite/gcc.dg/20020312-2.c index 98af0d4..52c33d0 100644 --- a/gcc/testsuite/gcc.dg/20020312-2.c +++ b/gcc/testsuite/gcc.dg/20020312-2.c @@ -9,6 +9,7 @@ /* { dg-options "-O -fno-pic" } */ /* { dg-additional-options "-no-pie" { target pie_enabled } } */ /* { dg-require-effective-target nonlocal_goto } */ +/* { dg-skip-if "" { arm*-*-uclinuxfdpiceabi } "*" "" } */ extern void abort (void); diff --git a/gcc/testsuite/gcc.target/arm/20051215-1.c b/gcc/testsuite/gcc.target/arm/20051215-1.c index 0519dc7..cc07693 100644 --- a/gcc/testsuite/gcc.target/arm/20051215-1.c +++ b/gcc/testsuite/gcc.target/arm/20051215-1.c @@ -3,6 +3,7 @@ the call would need an output reload. */ /* { dg-do run } */ /* { dg-options "-O2 -fno-omit-frame-pointer" } */ +/* { dg-skip-if "r9 is reserved in FDPIC" { arm*-*-uclinuxfdpiceabi } "*" "" } */ extern void abort (void); typedef void (*callback) (void); diff --git a/gcc/testsuite/gcc.target/arm/data-rel-2.c b/gcc/testsuite/gcc.target/arm/data-rel-2.c index 6ba47d6..7d37a8c 100644 --- a/gcc/testsuite/gcc.target/arm/data-rel-2.c +++ b/gcc/testsuite/gcc.target/arm/data-rel-2.c @@ -1,3 +1,4 @@ +/* { dg-skip-if "Not supported in FDPIC" { arm*-*-uclinuxfdpiceabi } "*" "" } */ /* { dg-options "-fPIC -mno-pic-data-is-text-relative -mno-single-pic-base" } */ /* { dg-final { scan-assembler-not "j-\\(.LPIC" } } */ /* { dg-final { scan-assembler "_GLOBAL_OFFSET_TABLE_-\\(.LPIC" } } */ diff --git a/gcc/testsuite/gcc.target/arm/data-rel-3.c b/gcc/testsuite/gcc.target/arm/data-rel-3.c index 2ce1e66..534c6c4 100644 --- a/gcc/testsuite/gcc.target/arm/data-rel-3.c +++ b/gcc/testsuite/gcc.target/arm/data-rel-3.c @@ -1,3 +1,4 @@ +/* { dg-skip-if "Not supported in FDPIC" { arm*-*-uclinuxfdpiceabi } "*" "" } */ /* { dg-options "-fPIC -mpic-data-is-text-relative" } */ /* { dg-final { scan-assembler "j-\\(.LPIC" } } */ /* { dg-final { scan-assembler-not "_GLOBAL_OFFSET_TABLE_-\\(.LPIC" } } */ diff --git a/gcc/testsuite/gcc.target/arm/ivopts-2.c b/gcc/testsuite/gcc.target/arm/ivopts-2.c index afe91aa..f1d5edb 100644 --- a/gcc/testsuite/gcc.target/arm/ivopts-2.c +++ b/gcc/testsuite/gcc.target/arm/ivopts-2.c @@ -14,4 +14,4 @@ tr4 (short array[], int n) /* { dg-final { scan-tree-dump-times "PHI Date: Tue, 10 Sep 2019 10:02:38 +0200 Subject: [ARM/FDPIC v6 15/24] [ARM][testsuite] FDPIC: Adjust scan-assembler patterns. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In FDPIC mode, r9 is saved in addition to other registers, so update the expected patterns accordingly. 2019-09-10 Christophe Lyon Mickaël Guêné gcc/testsuite/ * gcc.target/arm/interrupt-1.c: Add scan-assembler pattern for arm*-*-uclinuxfdpiceabi. * gcc.target/arm/interrupt-2.c: Likewise. * gcc.target/arm/pr70830.c: Likewise. Co-Authored-By: Mickaël Guêné From-SVN: r275577 --- gcc/testsuite/ChangeLog | 8 ++++++++ gcc/testsuite/gcc.target/arm/interrupt-1.c | 6 ++++-- gcc/testsuite/gcc.target/arm/interrupt-2.c | 6 ++++-- gcc/testsuite/gcc.target/arm/pr70830.c | 3 ++- 4 files changed, 18 insertions(+), 5 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9b96065..6c94bea 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,14 @@ 2019-09-10 Christophe Lyon Mickaël Guêné + * gcc.target/arm/interrupt-1.c: Add scan-assembler pattern for + arm*-*-uclinuxfdpiceabi. + * gcc.target/arm/interrupt-2.c: Likewise. + * gcc.target/arm/pr70830.c: Likewise. + +2019-09-10 Christophe Lyon + Mickaël Guêné + * gcc.dg/20020312-2.c: Skip on arm*-*-uclinuxfdpiceabi. * gcc.target/arm/20051215-1.c: Likewise. * gcc.target/arm/mmx-1.c: Likewise. diff --git a/gcc/testsuite/gcc.target/arm/interrupt-1.c b/gcc/testsuite/gcc.target/arm/interrupt-1.c index fe94877..493763d 100644 --- a/gcc/testsuite/gcc.target/arm/interrupt-1.c +++ b/gcc/testsuite/gcc.target/arm/interrupt-1.c @@ -13,5 +13,7 @@ void foo () bar (0); } -/* { dg-final { scan-assembler "push\t{r0, r1, r2, r3, r4, fp, ip, lr}" } } */ -/* { dg-final { scan-assembler "ldmfd\tsp!, {r0, r1, r2, r3, r4, fp, ip, pc}\\^" } } */ +/* { dg-final { scan-assembler "push\t{r0, r1, r2, r3, r4, fp, ip, lr}" { target { ! arm*-*-uclinuxfdpiceabi } } } } */ +/* { dg-final { scan-assembler "ldmfd\tsp!, {r0, r1, r2, r3, r4, fp, ip, pc}\\^" { target { ! arm*-*-uclinuxfdpiceabi } } } } */ +/* { dg-final { scan-assembler "push\t{r0, r1, r2, r3, r4, r5, r9, fp, ip, lr}" { target arm*-*-uclinuxfdpiceabi } } } */ +/* { dg-final { scan-assembler "ldmfd\tsp!, {r0, r1, r2, r3, r4, r5, r9, fp, ip, pc}\\^" { target arm*-*-uclinuxfdpiceabi } } } */ diff --git a/gcc/testsuite/gcc.target/arm/interrupt-2.c b/gcc/testsuite/gcc.target/arm/interrupt-2.c index 289eca0..5be1f16 100644 --- a/gcc/testsuite/gcc.target/arm/interrupt-2.c +++ b/gcc/testsuite/gcc.target/arm/interrupt-2.c @@ -15,5 +15,7 @@ void test() foo = 0; } -/* { dg-final { scan-assembler "push\t{r0, r1, r2, r3, r4, r5, ip, lr}" } } */ -/* { dg-final { scan-assembler "ldmfd\tsp!, {r0, r1, r2, r3, r4, r5, ip, pc}\\^" } } */ +/* { dg-final { scan-assembler "push\t{r0, r1, r2, r3, r4, r5, ip, lr}" { target { ! arm*-*-uclinuxfdpiceabi } } } } */ +/* { dg-final { scan-assembler "ldmfd\tsp!, {r0, r1, r2, r3, r4, r5, ip, pc}\\^" { target { ! arm*-*-uclinuxfdpiceabi } } } } */ +/* { dg-final { scan-assembler "push\t{r0, r1, r2, r3, r4, r5, r6, r9, ip, lr}" { target arm*-*-uclinuxfdpiceabi } } } */ +/* { dg-final { scan-assembler "ldmfd\tsp!, {r0, r1, r2, r3, r4, r5, r6, r9, ip, pc}\\^" { target arm*-*-uclinuxfdpiceabi } } } */ diff --git a/gcc/testsuite/gcc.target/arm/pr70830.c b/gcc/testsuite/gcc.target/arm/pr70830.c index cad903b..cd84c42 100644 --- a/gcc/testsuite/gcc.target/arm/pr70830.c +++ b/gcc/testsuite/gcc.target/arm/pr70830.c @@ -11,4 +11,5 @@ void __attribute__ ((interrupt ("IRQ"))) dm3730_IRQHandler(void) { prints("IRQ" ); } -/* { dg-final { scan-assembler "ldmfd\tsp!, {r0, r1, r2, r3, ip, pc}\\^" } } */ +/* { dg-final { scan-assembler "ldmfd\tsp!, {r0, r1, r2, r3, ip, pc}\\^" { target { ! arm*-*-uclinuxfdpiceabi } } } } */ +/* { dg-final { scan-assembler "ldmfd\tsp!, {r0, r1, r2, r3, r4, r9, ip, pc}\\^" { target arm*-*-uclinuxfdpiceabi } } } */ -- cgit v1.1 From ee442e15c0c7f26174a857aa5bbbfc9cbbfdbcef Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Tue, 10 Sep 2019 10:04:00 +0200 Subject: [ARM/FDPIC v6 16/24] [ARM][testsuite] FDPIC: Skip tests that don't work in PIC mode Some tests fail on arm*-*-uclinuxfdpiceabi because it generates PIC code and they don't support it: skip them. They also fail on arm*-linux* when forcing -fPIC. 2019-09-10 Christophe Lyon gcc/testsuite/ * gcc.target/arm/eliminate.c: Accept only nonpic targets. * g++.dg/other/anon5.C: Likewise. From-SVN: r275578 --- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/other/anon5.C | 1 + gcc/testsuite/gcc.target/arm/eliminate.c | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6c94bea..97c14f9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,4 +1,9 @@ 2019-09-10 Christophe Lyon + + * gcc.target/arm/eliminate.c: Accept only nonpic targets. + * g++.dg/other/anon5.C: Likewise. + +2019-09-10 Christophe Lyon Mickaël Guêné * gcc.target/arm/interrupt-1.c: Add scan-assembler pattern for diff --git a/gcc/testsuite/g++.dg/other/anon5.C b/gcc/testsuite/g++.dg/other/anon5.C index ee4601e..dadd92e 100644 --- a/gcc/testsuite/g++.dg/other/anon5.C +++ b/gcc/testsuite/g++.dg/other/anon5.C @@ -1,5 +1,6 @@ // PR c++/34094 // { dg-do link { target { ! { *-*-darwin* *-*-hpux* *-*-solaris2.* } } } } +// { dg-require-effective-target nonpic } // { dg-options "-gdwarf-2" } // Ignore additional message on powerpc-ibm-aix // { dg-prune-output "obtain more information" } */ diff --git a/gcc/testsuite/gcc.target/arm/eliminate.c b/gcc/testsuite/gcc.target/arm/eliminate.c index f254dd8..299d4df 100644 --- a/gcc/testsuite/gcc.target/arm/eliminate.c +++ b/gcc/testsuite/gcc.target/arm/eliminate.c @@ -1,4 +1,4 @@ -/* { dg-do compile } */ +/* { dg-do compile { target { nonpic } } } */ /* { dg-options "-O2" } */ struct X -- cgit v1.1 From e8977296e13df4062e9fa163ca44f961c05561d6 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Tue, 10 Sep 2019 10:05:26 +0200 Subject: [ARM/FDPIC v6 17/24] [ARM][testsuite] FDPIC: Handle *-*-uclinux* Add *-*-uclinux* to tests that work on this target. 2019-09-10 Christophe Lyon gcc/testsuite/ * g++.dg/abi/forced.C: Add *-*-uclinux*. * g++.dg/abi/guard2.C: Likewise. * g++.dg/ext/cleanup-10.C: Likewise. * g++.dg/ext/cleanup-11.C: Likewise. * g++.dg/ext/cleanup-8.C: Likewise. * g++.dg/ext/cleanup-9.C: Likewise. * g++.dg/ext/sync-4.C: Likewise. * g++.dg/ipa/comdat.C: Likewise. * gcc.dg/20041106-1.c: Likewise. * gcc.dg/cleanup-10.c: Likewise. * gcc.dg/cleanup-11.c: Likewise. * gcc.dg/cleanup-8.c: Likewise. * gcc.dg/cleanup-9.c: Likewise. * gcc.dg/fdata-sections-1.c: Likewise. * gcc.dg/fdata-sections-2.c: Likewise. * gcc.dg/pr39323-1.c: Likewise. * gcc.dg/pr39323-2.c: Likewise. * gcc.dg/pr39323-3.c: Likewise. * gcc.dg/pr65780-1.c: Likewise. * gcc.dg/pr65780-2.c: Likewise. * gcc.dg/pr67338.c: Likewise. * gcc.dg/pr78185.c: Likewise. * gcc.dg/pr83100-1.c: Likewise. * gcc.dg/pr83100-4.c: Likewise. * gcc.dg/strlenopt-12g.c: Likewise. * gcc.dg/strlenopt-14g.c: Likewise. * gcc.dg/strlenopt-14gf.c: Likewise. * gcc.dg/strlenopt-16g.c: Likewise. * gcc.dg/strlenopt-17g.c: Likewise. * gcc.dg/strlenopt-18g.c: Likewise. * gcc.dg/strlenopt-1f.c: Likewise. * gcc.dg/strlenopt-22g.c: Likewise. * gcc.dg/strlenopt-2f.c: Likewise. * gcc.dg/strlenopt-31g.c: Likewise. * gcc.dg/strlenopt-33g.c: Likewise. * gcc.dg/strlenopt-4g.c: Likewise. * gcc.dg/strlenopt-4gf.c: Likewise. * gcc.dg/strncmp-2.c: Likewise. * gcc.dg/struct-ret-3.c: Likewise. * gcc.dg/torture/pr69760.c: Likewise. * gcc.target/arm/div64-unwinding.c: Likewise. * gcc.target/arm/stack-checking.c: Likewise. * gcc.target/arm/synchronize.c: Likewise. * gcc.target/arm/pr66912.c: Add arm*-*-uclinuxfdpiceabi. * lib/target-supports.exp (check_effective_target_pie): Likewise. (check_effective_target_sync_long_long_runtime): Likewise. (check_effective_target_sync_int_long): Likewise. (check_effective_target_sync_char_short): Likewise. From-SVN: r275579 --- gcc/testsuite/ChangeLog | 51 ++++++++++++++++++++++++++ gcc/testsuite/g++.dg/abi/forced.C | 2 +- gcc/testsuite/g++.dg/abi/guard2.C | 2 +- gcc/testsuite/g++.dg/ext/cleanup-10.C | 2 +- gcc/testsuite/g++.dg/ext/cleanup-11.C | 2 +- gcc/testsuite/g++.dg/ext/cleanup-8.C | 2 +- gcc/testsuite/g++.dg/ext/cleanup-9.C | 2 +- gcc/testsuite/g++.dg/ext/sync-4.C | 2 +- gcc/testsuite/g++.dg/ipa/comdat.C | 2 +- gcc/testsuite/gcc.dg/20041106-1.c | 2 +- gcc/testsuite/gcc.dg/cleanup-10.c | 2 +- gcc/testsuite/gcc.dg/cleanup-11.c | 2 +- gcc/testsuite/gcc.dg/cleanup-8.c | 2 +- gcc/testsuite/gcc.dg/cleanup-9.c | 2 +- gcc/testsuite/gcc.dg/fdata-sections-1.c | 2 +- gcc/testsuite/gcc.dg/fdata-sections-2.c | 2 +- gcc/testsuite/gcc.dg/pr39323-1.c | 2 +- gcc/testsuite/gcc.dg/pr39323-2.c | 2 +- gcc/testsuite/gcc.dg/pr39323-3.c | 2 +- gcc/testsuite/gcc.dg/pr65780-1.c | 2 +- gcc/testsuite/gcc.dg/pr65780-2.c | 2 +- gcc/testsuite/gcc.dg/pr67338.c | 2 +- gcc/testsuite/gcc.dg/pr78185.c | 2 +- gcc/testsuite/gcc.dg/pr83100-1.c | 2 +- gcc/testsuite/gcc.dg/pr83100-4.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-12g.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-14g.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-14gf.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-16g.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-17g.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-18g.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-1f.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-22g.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-2f.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-31g.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-33g.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-4g.c | 2 +- gcc/testsuite/gcc.dg/strlenopt-4gf.c | 2 +- gcc/testsuite/gcc.dg/strncmp-2.c | 2 +- gcc/testsuite/gcc.dg/struct-ret-3.c | 2 +- gcc/testsuite/gcc.dg/torture/pr69760.c | 2 +- gcc/testsuite/gcc.target/arm/div64-unwinding.c | 2 +- gcc/testsuite/gcc.target/arm/pr66912.c | 2 +- gcc/testsuite/gcc.target/arm/stack-checking.c | 2 +- gcc/testsuite/gcc.target/arm/synchronize.c | 2 +- gcc/testsuite/lib/target-supports.exp | 4 ++ 46 files changed, 99 insertions(+), 44 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 97c14f9..8d23b97 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,56 @@ 2019-09-10 Christophe Lyon + * g++.dg/abi/forced.C: Add *-*-uclinux*. + * g++.dg/abi/guard2.C: Likewise. + * g++.dg/ext/cleanup-10.C: Likewise. + * g++.dg/ext/cleanup-11.C: Likewise. + * g++.dg/ext/cleanup-8.C: Likewise. + * g++.dg/ext/cleanup-9.C: Likewise. + * g++.dg/ext/sync-4.C: Likewise. + * g++.dg/ipa/comdat.C: Likewise. + * gcc.dg/20041106-1.c: Likewise. + * gcc.dg/cleanup-10.c: Likewise. + * gcc.dg/cleanup-11.c: Likewise. + * gcc.dg/cleanup-8.c: Likewise. + * gcc.dg/cleanup-9.c: Likewise. + * gcc.dg/fdata-sections-1.c: Likewise. + * gcc.dg/fdata-sections-2.c: Likewise. + * gcc.dg/pr39323-1.c: Likewise. + * gcc.dg/pr39323-2.c: Likewise. + * gcc.dg/pr39323-3.c: Likewise. + * gcc.dg/pr65780-1.c: Likewise. + * gcc.dg/pr65780-2.c: Likewise. + * gcc.dg/pr67338.c: Likewise. + * gcc.dg/pr78185.c: Likewise. + * gcc.dg/pr83100-1.c: Likewise. + * gcc.dg/pr83100-4.c: Likewise. + * gcc.dg/strlenopt-12g.c: Likewise. + * gcc.dg/strlenopt-14g.c: Likewise. + * gcc.dg/strlenopt-14gf.c: Likewise. + * gcc.dg/strlenopt-16g.c: Likewise. + * gcc.dg/strlenopt-17g.c: Likewise. + * gcc.dg/strlenopt-18g.c: Likewise. + * gcc.dg/strlenopt-1f.c: Likewise. + * gcc.dg/strlenopt-22g.c: Likewise. + * gcc.dg/strlenopt-2f.c: Likewise. + * gcc.dg/strlenopt-31g.c: Likewise. + * gcc.dg/strlenopt-33g.c: Likewise. + * gcc.dg/strlenopt-4g.c: Likewise. + * gcc.dg/strlenopt-4gf.c: Likewise. + * gcc.dg/strncmp-2.c: Likewise. + * gcc.dg/struct-ret-3.c: Likewise. + * gcc.dg/torture/pr69760.c: Likewise. + * gcc.target/arm/div64-unwinding.c: Likewise. + * gcc.target/arm/stack-checking.c: Likewise. + * gcc.target/arm/synchronize.c: Likewise. + * gcc.target/arm/pr66912.c: Add arm*-*-uclinuxfdpiceabi. + * lib/target-supports.exp (check_effective_target_pie): Likewise. + (check_effective_target_sync_long_long_runtime): Likewise. + (check_effective_target_sync_int_long): Likewise. + (check_effective_target_sync_char_short): Likewise. + +2019-09-10 Christophe Lyon + * gcc.target/arm/eliminate.c: Accept only nonpic targets. * g++.dg/other/anon5.C: Likewise. diff --git a/gcc/testsuite/g++.dg/abi/forced.C b/gcc/testsuite/g++.dg/abi/forced.C index 0e6be28..2d1ec53 100644 --- a/gcc/testsuite/g++.dg/abi/forced.C +++ b/gcc/testsuite/g++.dg/abi/forced.C @@ -1,4 +1,4 @@ -// { dg-do run { target *-*-linux* *-*-gnu* } } +// { dg-do run { target *-*-linux* *-*-gnu* *-*-uclinux* } } // { dg-options "-pthread" } #include diff --git a/gcc/testsuite/g++.dg/abi/guard2.C b/gcc/testsuite/g++.dg/abi/guard2.C index c35fa7e..74139a8 100644 --- a/gcc/testsuite/g++.dg/abi/guard2.C +++ b/gcc/testsuite/g++.dg/abi/guard2.C @@ -1,6 +1,6 @@ // PR c++/41611 // Test that the guard gets its own COMDAT group. -// { dg-final { scan-assembler "_ZGVZN1A1fEvE1i,comdat" { target *-*-linux* *-*-gnu* } } } +// { dg-final { scan-assembler "_ZGVZN1A1fEvE1i,comdat" { target *-*-linux* *-*-gnu* *-*-uclinux* } } } struct A { static int f() diff --git a/gcc/testsuite/g++.dg/ext/cleanup-10.C b/gcc/testsuite/g++.dg/ext/cleanup-10.C index 66c7b76..56aeb66 100644 --- a/gcc/testsuite/g++.dg/ext/cleanup-10.C +++ b/gcc/testsuite/g++.dg/ext/cleanup-10.C @@ -1,4 +1,4 @@ -/* { dg-do run { target hppa*-*-hpux* *-*-linux* *-*-gnu* powerpc*-*-darwin* *-*-darwin[912]* } } */ +/* { dg-do run { target hppa*-*-hpux* *-*-linux* *-*-gnu* powerpc*-*-darwin* *-*-darwin[912]* *-*-uclinux* } } */ /* { dg-options "-fexceptions -fnon-call-exceptions -O2" } */ /* Verify that cleanups work with exception handling through signal frames on alternate stack. */ diff --git a/gcc/testsuite/g++.dg/ext/cleanup-11.C b/gcc/testsuite/g++.dg/ext/cleanup-11.C index 6e96521..c6d3560 100644 --- a/gcc/testsuite/g++.dg/ext/cleanup-11.C +++ b/gcc/testsuite/g++.dg/ext/cleanup-11.C @@ -1,4 +1,4 @@ -/* { dg-do run { target hppa*-*-hpux* *-*-linux* *-*-gnu* powerpc*-*-darwin* *-*-darwin[912]* } } */ +/* { dg-do run { target hppa*-*-hpux* *-*-linux* *-*-gnu* powerpc*-*-darwin* *-*-darwin[912]* *-*-uclinux* } } */ /* { dg-options "-fexceptions -fnon-call-exceptions -O2" } */ /* Verify that cleanups work with exception handling through realtime signal frames on alternate stack. */ diff --git a/gcc/testsuite/g++.dg/ext/cleanup-8.C b/gcc/testsuite/g++.dg/ext/cleanup-8.C index ccf9bef..e99508d 100644 --- a/gcc/testsuite/g++.dg/ext/cleanup-8.C +++ b/gcc/testsuite/g++.dg/ext/cleanup-8.C @@ -1,4 +1,4 @@ -/* { dg-do run { target hppa*-*-hpux* *-*-linux* *-*-gnu* powerpc*-*-darwin* *-*-darwin[912]* } } */ +/* { dg-do run { target hppa*-*-hpux* *-*-linux* *-*-gnu* powerpc*-*-darwin* *-*-darwin[912]* *-*-uclinux* } } */ /* { dg-options "-fexceptions -fnon-call-exceptions -O2" } */ /* Verify that cleanups work with exception handling through signal frames. */ diff --git a/gcc/testsuite/g++.dg/ext/cleanup-9.C b/gcc/testsuite/g++.dg/ext/cleanup-9.C index dcdfcae..45e5f90 100644 --- a/gcc/testsuite/g++.dg/ext/cleanup-9.C +++ b/gcc/testsuite/g++.dg/ext/cleanup-9.C @@ -1,4 +1,4 @@ -/* { dg-do run { target hppa*-*-hpux* *-*-linux* *-*-gnu* powerpc*-*-darwin* *-*-darwin[912]* } } */ +/* { dg-do run { target hppa*-*-hpux* *-*-linux* *-*-gnu* powerpc*-*-darwin* *-*-darwin[912]* *-*-uclinux* } } */ /* { dg-options "-fexceptions -fnon-call-exceptions -O2" } */ /* Verify that cleanups work with exception handling through realtime signal frames. */ diff --git a/gcc/testsuite/g++.dg/ext/sync-4.C b/gcc/testsuite/g++.dg/ext/sync-4.C index 8a2de48..029afb0 100644 --- a/gcc/testsuite/g++.dg/ext/sync-4.C +++ b/gcc/testsuite/g++.dg/ext/sync-4.C @@ -1,4 +1,4 @@ -/* { dg-do run { target hppa*-*-hpux* *-*-linux* *-*-gnu* powerpc*-*-darwin* *-*-darwin[912]* } } */ +/* { dg-do run { target hppa*-*-hpux* *-*-linux* *-*-gnu* powerpc*-*-darwin* *-*-darwin[912]* *-*-uclinux* } } */ /* FIXME The following additional option should be removed after the fix for radr://19802258. /* { dg-xfail-run-if "PR60563 radr://19802258" { *-*-darwin* } } */ /* { dg-require-effective-target sync_long_long_runtime } */ diff --git a/gcc/testsuite/g++.dg/ipa/comdat.C b/gcc/testsuite/g++.dg/ipa/comdat.C index 1945e32..f3df99a 100644 --- a/gcc/testsuite/g++.dg/ipa/comdat.C +++ b/gcc/testsuite/g++.dg/ipa/comdat.C @@ -1,4 +1,4 @@ -/* { dg-do compile { target *-*-linux* *-*-gnu* } } */ +/* { dg-do compile { target *-*-linux* *-*-gnu* *-*-uclinux* } } */ /* { dg-options "-O2 -fdump-ipa-comdats" } */ #include __attribute__ ((noinline)) diff --git a/gcc/testsuite/gcc.dg/20041106-1.c b/gcc/testsuite/gcc.dg/20041106-1.c index cba4a06..95579ff 100644 --- a/gcc/testsuite/gcc.dg/20041106-1.c +++ b/gcc/testsuite/gcc.dg/20041106-1.c @@ -1,4 +1,4 @@ -/* { dg-do run { target *-*-linux* *-*-gnu* *-*-solaris* } } */ +/* { dg-do run { target *-*-linux* *-*-gnu* *-*-solaris* *-*-uclinux* } } */ /* { dg-options -O2 } */ #include diff --git a/gcc/testsuite/gcc.dg/cleanup-10.c b/gcc/testsuite/gcc.dg/cleanup-10.c index 1af63ea..9fc8658 100644 --- a/gcc/testsuite/gcc.dg/cleanup-10.c +++ b/gcc/testsuite/gcc.dg/cleanup-10.c @@ -1,4 +1,4 @@ -/* { dg-do run { target hppa*-*-hpux* *-*-linux* *-*-gnu* powerpc*-*-darwin* *-*-darwin[912]* } } */ +/* { dg-do run { target hppa*-*-hpux* *-*-linux* *-*-gnu* powerpc*-*-darwin* *-*-darwin[912]* *-*-uclinux* } } */ /* { dg-options "-fexceptions -fnon-call-exceptions -O2" } */ /* { dg-require-effective-target exceptions } */ /* Verify that cleanups work with exception handling through signal frames diff --git a/gcc/testsuite/gcc.dg/cleanup-11.c b/gcc/testsuite/gcc.dg/cleanup-11.c index c1f19fe..6b499d4 100644 --- a/gcc/testsuite/gcc.dg/cleanup-11.c +++ b/gcc/testsuite/gcc.dg/cleanup-11.c @@ -1,4 +1,4 @@ -/* { dg-do run { target hppa*-*-hpux* *-*-linux* *-*-gnu* powerpc*-*-darwin* *-*-darwin[912]* } } */ +/* { dg-do run { target hppa*-*-hpux* *-*-linux* *-*-gnu* powerpc*-*-darwin* *-*-darwin[912]* *-*-uclinux* } } */ /* { dg-options "-fexceptions -fnon-call-exceptions -O2" } */ /* { dg-require-effective-target exceptions } */ /* Verify that cleanups work with exception handling through realtime signal diff --git a/gcc/testsuite/gcc.dg/cleanup-8.c b/gcc/testsuite/gcc.dg/cleanup-8.c index 45abdb2..87f4186 100644 --- a/gcc/testsuite/gcc.dg/cleanup-8.c +++ b/gcc/testsuite/gcc.dg/cleanup-8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target hppa*-*-hpux* *-*-linux* *-*-gnu* powerpc*-*-darwin* *-*-darwin[912]* } } */ +/* { dg-do run { target hppa*-*-hpux* *-*-linux* *-*-gnu* powerpc*-*-darwin* *-*-darwin[912]* *-*-uclinux* } } */ /* { dg-options "-fexceptions -fnon-call-exceptions -O2" } */ /* { dg-require-effective-target exceptions } */ /* Verify that cleanups work with exception handling through signal diff --git a/gcc/testsuite/gcc.dg/cleanup-9.c b/gcc/testsuite/gcc.dg/cleanup-9.c index 98dc268..d34ce12 100644 --- a/gcc/testsuite/gcc.dg/cleanup-9.c +++ b/gcc/testsuite/gcc.dg/cleanup-9.c @@ -1,4 +1,4 @@ -/* { dg-do run { target hppa*-*-hpux* *-*-linux* *-*-gnu* powerpc*-*-darwin* *-*-darwin[912]* } } */ +/* { dg-do run { target hppa*-*-hpux* *-*-linux* *-*-gnu* powerpc*-*-darwin* *-*-darwin[912]* *-*-uclinux* } } */ /* { dg-options "-fexceptions -fnon-call-exceptions -O2" } */ /* { dg-require-effective-target exceptions } */ /* Verify that cleanups work with exception handling through realtime diff --git a/gcc/testsuite/gcc.dg/fdata-sections-1.c b/gcc/testsuite/gcc.dg/fdata-sections-1.c index 51686b9..e8a6639 100644 --- a/gcc/testsuite/gcc.dg/fdata-sections-1.c +++ b/gcc/testsuite/gcc.dg/fdata-sections-1.c @@ -1,7 +1,7 @@ /* PR middle-end/15486 */ /* Origin: Jonathan Larmour */ -/* { dg-do compile { target *-*-linux* *-*-gnu* } } */ +/* { dg-do compile { target *-*-linux* *-*-gnu* *-*-uclinux* } } */ /* { dg-options "-fdata-sections" } */ int x; diff --git a/gcc/testsuite/gcc.dg/fdata-sections-2.c b/gcc/testsuite/gcc.dg/fdata-sections-2.c index dda90ba..48d44a2 100644 --- a/gcc/testsuite/gcc.dg/fdata-sections-2.c +++ b/gcc/testsuite/gcc.dg/fdata-sections-2.c @@ -4,7 +4,7 @@ /* This checks that string constants are put in per-function rodata sections, so that they can be garbage collected. */ -/* { dg-do compile { target *-*-linux* } } */ +/* { dg-do compile { target *-*-linux* *-*-uclinux* } } */ /* { dg-options "-O -ffunction-sections -fdata-sections" } */ const char *f1(void) { return "falderalde"; } diff --git a/gcc/testsuite/gcc.dg/pr39323-1.c b/gcc/testsuite/gcc.dg/pr39323-1.c index 7a7fd63..d84009c 100644 --- a/gcc/testsuite/gcc.dg/pr39323-1.c +++ b/gcc/testsuite/gcc.dg/pr39323-1.c @@ -1,5 +1,5 @@ /* PR c/39323 - MAX_OFILE_ALIGNMENT in elfos.h is too big */ -/* { dg-do compile { target *-*-linux* *-*-gnu* } } */ +/* { dg-do compile { target *-*-linux* *-*-gnu* *-*-uclinux* } } */ int foo __attribute__ ((aligned(1 << 29))) = 20; /* { dg-error "requested alignment" } */ typedef int __attribute__ ((aligned(1 << 29))) int29; /* { dg-error "requested alignment" } */ diff --git a/gcc/testsuite/gcc.dg/pr39323-2.c b/gcc/testsuite/gcc.dg/pr39323-2.c index a870729..6b6cb2e 100644 --- a/gcc/testsuite/gcc.dg/pr39323-2.c +++ b/gcc/testsuite/gcc.dg/pr39323-2.c @@ -1,5 +1,5 @@ /* PR c/39323 */ -/* { dg-do compile { target *-*-linux* *-*-gnu* } } */ +/* { dg-do compile { target *-*-linux* *-*-gnu* *-*-uclinux* } } */ int bar __attribute__ ((aligned(1 << 28))) = 20; diff --git a/gcc/testsuite/gcc.dg/pr39323-3.c b/gcc/testsuite/gcc.dg/pr39323-3.c index b452d3c..2e2c1a2 100644 --- a/gcc/testsuite/gcc.dg/pr39323-3.c +++ b/gcc/testsuite/gcc.dg/pr39323-3.c @@ -1,5 +1,5 @@ /* PR c/39323 */ -/* { dg-do compile { target *-*-linux* *-*-gnu* } } */ +/* { dg-do compile { target *-*-linux* *-*-gnu* *-*-uclinux* } } */ typedef int __attribute__ ((aligned(1 << 28))) int28; int28 foo = 20; diff --git a/gcc/testsuite/gcc.dg/pr65780-1.c b/gcc/testsuite/gcc.dg/pr65780-1.c index b586211..5e3226e 100644 --- a/gcc/testsuite/gcc.dg/pr65780-1.c +++ b/gcc/testsuite/gcc.dg/pr65780-1.c @@ -1,5 +1,5 @@ /* PR target/65780 */ -/* { dg-do link { target *-*-linux* *-*-gnu* } } */ +/* { dg-do link { target *-*-linux* *-*-gnu* *-*-uclinux* } } */ /* { dg-options "-O2" } */ int optopt; diff --git a/gcc/testsuite/gcc.dg/pr65780-2.c b/gcc/testsuite/gcc.dg/pr65780-2.c index bff3323..932cbe1 100644 --- a/gcc/testsuite/gcc.dg/pr65780-2.c +++ b/gcc/testsuite/gcc.dg/pr65780-2.c @@ -1,5 +1,5 @@ /* PR target/65780 */ -/* { dg-do link { target *-*-linux* *-*-gnu* } } */ +/* { dg-do link { target *-*-linux* *-*-gnu* *-*-uclinux* } } */ /* { dg-require-effective-target pie } */ /* { dg-options "-O2 -fpie" } */ diff --git a/gcc/testsuite/gcc.dg/pr67338.c b/gcc/testsuite/gcc.dg/pr67338.c index 0fdc302..7bfbef2 100644 --- a/gcc/testsuite/gcc.dg/pr67338.c +++ b/gcc/testsuite/gcc.dg/pr67338.c @@ -1,4 +1,4 @@ /* PR c/67338 */ -/* { dg-do compile { target *-*-linux* *-*-gnu* } } */ +/* { dg-do compile { target *-*-linux* *-*-gnu* *-*-uclinux* } } */ struct S { __attribute__((aligned (1 << 28))) double a; }; diff --git a/gcc/testsuite/gcc.dg/pr78185.c b/gcc/testsuite/gcc.dg/pr78185.c index 405f748..d7781b2 100644 --- a/gcc/testsuite/gcc.dg/pr78185.c +++ b/gcc/testsuite/gcc.dg/pr78185.c @@ -1,4 +1,4 @@ -/* { dg-do run { target *-*-linux* *-*-gnu* } } */ +/* { dg-do run { target *-*-linux* *-*-gnu* *-*-uclinux* } } */ /* { dg-options "-O" } */ #include diff --git a/gcc/testsuite/gcc.dg/pr83100-1.c b/gcc/testsuite/gcc.dg/pr83100-1.c index 233c1f6..ccfb8c6 100644 --- a/gcc/testsuite/gcc.dg/pr83100-1.c +++ b/gcc/testsuite/gcc.dg/pr83100-1.c @@ -1,5 +1,5 @@ /* PR target/83100 */ -/* { dg-do compile { target *-*-linux* *-*-gnu* } } */ +/* { dg-do compile { target *-*-linux* *-*-gnu* *-*-uclinux* } } */ /* { dg-options "-O2 -fcommon -fdata-sections" } */ const int a; diff --git a/gcc/testsuite/gcc.dg/pr83100-4.c b/gcc/testsuite/gcc.dg/pr83100-4.c index bb26735..2f83247 100644 --- a/gcc/testsuite/gcc.dg/pr83100-4.c +++ b/gcc/testsuite/gcc.dg/pr83100-4.c @@ -1,5 +1,5 @@ /* PR target/83100 */ -/* { dg-do compile { target *-*-linux* *-*-gnu* } } */ +/* { dg-do compile { target *-*-linux* *-*-gnu* *-*-uclinux* } } */ /* { dg-options "-O2 -fno-common -fdata-sections" } */ const int a; diff --git a/gcc/testsuite/gcc.dg/strlenopt-12g.c b/gcc/testsuite/gcc.dg/strlenopt-12g.c index f1dec1f..fb0eeb2 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-12g.c +++ b/gcc/testsuite/gcc.dg/strlenopt-12g.c @@ -1,5 +1,5 @@ /* This test needs runtime that provides stpcpy function. */ -/* { dg-do run { target *-*-linux* *-*-gnu* } } */ +/* { dg-do run { target *-*-linux* *-*-gnu* *-*-uclinux* } } */ /* { dg-options "-O2" } */ #define USE_GNU diff --git a/gcc/testsuite/gcc.dg/strlenopt-14g.c b/gcc/testsuite/gcc.dg/strlenopt-14g.c index 1368ed3..81ddcc2 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-14g.c +++ b/gcc/testsuite/gcc.dg/strlenopt-14g.c @@ -1,5 +1,5 @@ /* This test needs runtime that provides stpcpy and mempcpy functions. */ -/* { dg-do run { target *-*-linux* *-*-gnu* } } */ +/* { dg-do run { target *-*-linux* *-*-gnu* *-*-uclinux* } } */ /* { dg-options "-O2 -fdump-tree-strlen" } */ /* Bionic targets don't have mempcpy */ /* { dg-require-effective-target non_bionic } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-14gf.c b/gcc/testsuite/gcc.dg/strlenopt-14gf.c index f7db2a8..54cff83 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-14gf.c +++ b/gcc/testsuite/gcc.dg/strlenopt-14gf.c @@ -1,6 +1,6 @@ /* This test needs runtime that provides stpcpy, mempcpy and __*_chk functions. */ -/* { dg-do run { target *-*-linux* *-*-gnu* } } */ +/* { dg-do run { target *-*-linux* *-*-gnu* *-*-uclinux* } } */ /* { dg-options "-O2 -fdump-tree-strlen" } */ /* Bionic targets don't have mempcpy */ /* { dg-require-effective-target non_bionic } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-16g.c b/gcc/testsuite/gcc.dg/strlenopt-16g.c index 816cbbc..e847a7a 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-16g.c +++ b/gcc/testsuite/gcc.dg/strlenopt-16g.c @@ -1,5 +1,5 @@ /* This test needs runtime that provides stpcpy function. */ -/* { dg-do run { target *-*-linux* *-*-gnu* } } */ +/* { dg-do run { target *-*-linux* *-*-gnu* *-*-uclinux* } } */ /* { dg-options "-O2 -fdump-tree-strlen" } */ #define USE_GNU diff --git a/gcc/testsuite/gcc.dg/strlenopt-17g.c b/gcc/testsuite/gcc.dg/strlenopt-17g.c index aa86f78..9e6373c 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-17g.c +++ b/gcc/testsuite/gcc.dg/strlenopt-17g.c @@ -1,5 +1,5 @@ /* This test needs runtime that provides stpcpy function. */ -/* { dg-do run { target *-*-linux* *-*-gnu* } } */ +/* { dg-do run { target *-*-linux* *-*-gnu* *-*-uclinux* } } */ /* { dg-options "-O2 -fdump-tree-strlen" } */ #define USE_GNU diff --git a/gcc/testsuite/gcc.dg/strlenopt-18g.c b/gcc/testsuite/gcc.dg/strlenopt-18g.c index de692e0..0c219b8 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-18g.c +++ b/gcc/testsuite/gcc.dg/strlenopt-18g.c @@ -1,5 +1,5 @@ /* This test needs runtime that provides stpcpy function. */ -/* { dg-do run { target *-*-linux* *-*-gnu* } } */ +/* { dg-do run { target *-*-linux* *-*-gnu* *-*-uclinux* } } */ /* { dg-options "-O2 -fdump-tree-strlen" } */ #define USE_GNU diff --git a/gcc/testsuite/gcc.dg/strlenopt-1f.c b/gcc/testsuite/gcc.dg/strlenopt-1f.c index 4e3abd9..e7d817f 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-1f.c +++ b/gcc/testsuite/gcc.dg/strlenopt-1f.c @@ -1,5 +1,5 @@ /* This test needs runtime that provides __*_chk functions. */ -/* { dg-do run { target *-*-linux* *-*-gnu* } } */ +/* { dg-do run { target *-*-linux* *-*-gnu* *-*-uclinu* } } */ /* { dg-options "-O2 -fdump-tree-strlen" } */ #define FORTIFY_SOURCE 2 diff --git a/gcc/testsuite/gcc.dg/strlenopt-22g.c b/gcc/testsuite/gcc.dg/strlenopt-22g.c index 1ecb85e..6ee6bef 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-22g.c +++ b/gcc/testsuite/gcc.dg/strlenopt-22g.c @@ -1,5 +1,5 @@ /* This test needs runtime that provides stpcpy function. */ -/* { dg-do run { target *-*-linux* *-*-gnu* } } */ +/* { dg-do run { target *-*-linux* *-*-gnu* *-*-uclinux* } } */ /* { dg-options "-O2 -fdump-tree-strlen" } */ #define USE_GNU diff --git a/gcc/testsuite/gcc.dg/strlenopt-2f.c b/gcc/testsuite/gcc.dg/strlenopt-2f.c index 5786f8a..c0c7f38 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-2f.c +++ b/gcc/testsuite/gcc.dg/strlenopt-2f.c @@ -1,5 +1,5 @@ /* This test needs runtime that provides __*_chk functions. */ -/* { dg-do run { target *-*-linux* *-*-gnu* } } */ +/* { dg-do run { target *-*-linux* *-*-gnu* *-*-uclinux* } } */ /* { dg-options "-O2 -fdump-tree-strlen" } */ #define FORTIFY_SOURCE 2 diff --git a/gcc/testsuite/gcc.dg/strlenopt-31g.c b/gcc/testsuite/gcc.dg/strlenopt-31g.c index 4eff864..eee4b57 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-31g.c +++ b/gcc/testsuite/gcc.dg/strlenopt-31g.c @@ -1,4 +1,4 @@ -/* { dg-do run { target *-*-linux* *-*-gnu* } } */ +/* { dg-do run { target *-*-linux* *-*-gnu* *-*-uclinux* } } */ /* { dg-options "-O2 -fdump-tree-strlen" } */ #define USE_GNU diff --git a/gcc/testsuite/gcc.dg/strlenopt-33g.c b/gcc/testsuite/gcc.dg/strlenopt-33g.c index a814160..1950008 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-33g.c +++ b/gcc/testsuite/gcc.dg/strlenopt-33g.c @@ -1,4 +1,4 @@ -/* { dg-do run { target *-*-linux* *-*-gnu* } } */ +/* { dg-do run { target *-*-linux* *-*-gnu* *-*-uclinux* } } */ /* { dg-options "-O2 -fdump-tree-strlen" } */ #define USE_GNU diff --git a/gcc/testsuite/gcc.dg/strlenopt-4g.c b/gcc/testsuite/gcc.dg/strlenopt-4g.c index 88dcec6..bf8aebb 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-4g.c +++ b/gcc/testsuite/gcc.dg/strlenopt-4g.c @@ -1,5 +1,5 @@ /* This test needs runtime that provides stpcpy function. */ -/* { dg-do run { target *-*-linux* *-*-gnu* } } */ +/* { dg-do run { target *-*-linux* *-*-gnu* *-*-uclinux* } } */ /* { dg-options "-O2 -fdump-tree-strlen" } */ #define USE_GNU diff --git a/gcc/testsuite/gcc.dg/strlenopt-4gf.c b/gcc/testsuite/gcc.dg/strlenopt-4gf.c index 033661a..16eb5b0 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-4gf.c +++ b/gcc/testsuite/gcc.dg/strlenopt-4gf.c @@ -1,5 +1,5 @@ /* This test needs runtime that provides stpcpy and __*_chk functions. */ -/* { dg-do run { target *-*-linux* *-*-gnu* } } */ +/* { dg-do run { target *-*-linux* *-*-gnu* *-*-uclinux* } } */ /* { dg-options "-O2 -fdump-tree-strlen" } */ #define USE_GNU diff --git a/gcc/testsuite/gcc.dg/strncmp-2.c b/gcc/testsuite/gcc.dg/strncmp-2.c index f5555ba..6818b30 100644 --- a/gcc/testsuite/gcc.dg/strncmp-2.c +++ b/gcc/testsuite/gcc.dg/strncmp-2.c @@ -1,5 +1,5 @@ /* Test strncmp builtin expansion for compilation and proper execution. */ -/* { dg-do run { target *-*-linux* *-*-gnu* } } */ +/* { dg-do run { target *-*-linux* *-*-gnu* *-*-uclinux* } } */ /* { dg-options "-O2" } */ /* { dg-require-effective-target ptr32plus } */ diff --git a/gcc/testsuite/gcc.dg/struct-ret-3.c b/gcc/testsuite/gcc.dg/struct-ret-3.c index 4083bb4..4c0a0e6 100644 --- a/gcc/testsuite/gcc.dg/struct-ret-3.c +++ b/gcc/testsuite/gcc.dg/struct-ret-3.c @@ -1,7 +1,7 @@ /* PR middle-end/31309 */ /* Origin: Peeter Joot */ -/* { dg-do run { target *-*-linux* *-*-gnu* } } */ +/* { dg-do run { target *-*-linux* *-*-gnu* *-*-uclinux* } } */ /* { dg-add-options stack_size } */ #include diff --git a/gcc/testsuite/gcc.dg/torture/pr69760.c b/gcc/testsuite/gcc.dg/torture/pr69760.c index 8f24608..53733c7 100644 --- a/gcc/testsuite/gcc.dg/torture/pr69760.c +++ b/gcc/testsuite/gcc.dg/torture/pr69760.c @@ -1,5 +1,5 @@ /* PR tree-optimization/69760 */ -/* { dg-do run { target { { *-*-linux* *-*-gnu* } && mmap } } } */ +/* { dg-do run { target { { *-*-linux* *-*-gnu* *-*-uclinux* } && mmap } } } */ /* { dg-options "-O2" } */ #include diff --git a/gcc/testsuite/gcc.target/arm/div64-unwinding.c b/gcc/testsuite/gcc.target/arm/div64-unwinding.c index 7f112ee..0944281 100644 --- a/gcc/testsuite/gcc.target/arm/div64-unwinding.c +++ b/gcc/testsuite/gcc.target/arm/div64-unwinding.c @@ -1,6 +1,6 @@ /* Performing a 64-bit division should not pull in the unwinder. */ -/* { dg-do run { target { ! *-*-linux* } } } */ +/* { dg-do run { target { { ! *-*-linux* } && { ! *-*-uclinux* } } } } */ /* { dg-options "-O0" } */ #include diff --git a/gcc/testsuite/gcc.target/arm/pr66912.c b/gcc/testsuite/gcc.target/arm/pr66912.c index 27e4c45..7e6294c 100644 --- a/gcc/testsuite/gcc.target/arm/pr66912.c +++ b/gcc/testsuite/gcc.target/arm/pr66912.c @@ -1,4 +1,4 @@ -/* { dg-do compile { target *-*-linux* } } */ +/* { dg-do compile { target *-*-linux* arm*-*-uclinuxfdpiceabi } } */ /* { dg-options "-O2 -fpic" } */ __attribute__((visibility("protected"))) diff --git a/gcc/testsuite/gcc.target/arm/stack-checking.c b/gcc/testsuite/gcc.target/arm/stack-checking.c index 4b53bed..9d1d2b0 100644 --- a/gcc/testsuite/gcc.target/arm/stack-checking.c +++ b/gcc/testsuite/gcc.target/arm/stack-checking.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { *-*-linux* } } } */ +/* { dg-do run { target { *-*-linux* *-*-uclinux* } } } */ /* { dg-require-stack-check "" } */ /* { dg-options "-fstack-check" } */ diff --git a/gcc/testsuite/gcc.target/arm/synchronize.c b/gcc/testsuite/gcc.target/arm/synchronize.c index 7ef10e2..912f407 100644 --- a/gcc/testsuite/gcc.target/arm/synchronize.c +++ b/gcc/testsuite/gcc.target/arm/synchronize.c @@ -1,4 +1,4 @@ -/* { dg-final { scan-assembler "__sync_synchronize|dmb|mcr" { target arm*-*-linux-* } } } */ +/* { dg-final { scan-assembler "__sync_synchronize|dmb|mcr" { target arm*-*-linux-* arm*-*-uclinux* } } } */ void *foo (void) { diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 3db1902..51677cc 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -1206,6 +1206,7 @@ proc check_effective_target_pie { } { || [istarget *-*-dragonfly*] || [istarget *-*-freebsd*] || [istarget *-*-linux*] + || [istarget arm*-*-uclinuxfdpiceabi] || [istarget *-*-gnu*] || [istarget *-*-amdhsa]} { return 1; @@ -6857,6 +6858,7 @@ proc check_effective_target_sync_long_long_runtime { } { } "" }]) || [istarget aarch64*-*-*] + || [istarget arm*-*-uclinuxfdpiceabi] || ([istarget arm*-*-linux-*] && [check_runtime sync_longlong_runtime { #include @@ -6916,6 +6918,7 @@ proc check_effective_target_sync_int_long { } { || [istarget aarch64*-*-*] || [istarget alpha*-*-*] || [istarget arm*-*-linux-*] + || [istarget arm*-*-uclinuxfdpiceabi] || ([istarget arm*-*-*] && [check_effective_target_arm_acq_rel]) || [istarget bfin*-*linux*] @@ -6939,6 +6942,7 @@ proc check_effective_target_sync_char_short { } { || [istarget i?86-*-*] || [istarget x86_64-*-*] || [istarget alpha*-*-*] || [istarget arm*-*-linux-*] + || [istarget arm*-*-uclinuxfdpiceabi] || ([istarget arm*-*-*] && [check_effective_target_arm_acq_rel]) || [istarget hppa*-*linux*] -- cgit v1.1 From d41049119d659d066a7d7479fab5af84aef471be Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Tue, 10 Sep 2019 10:06:52 +0200 Subject: [ARM/FDPIC v6 18/24] [ARM][testsuite] FDPIC: Enable tests on pie_enabled targets Some tests have the "nonpic" guard, but pass on arm*-*-uclinuxfdpiceabi because it is in PIE mode by default. Rather than adding this target to all these tests, add the "pie_enabled" effective target. 2019-09-10 Christophe Lyon gcc/testsuite/ * g++.dg/cpp0x/noexcept03.C: Add pie_enabled. * g++.dg/ipa/devirt-c-7.C: Likewise. * g++.dg/ipa/ivinline-1.C: Likewise. * g++.dg/ipa/ivinline-2.C: Likewise. * g++.dg/ipa/ivinline-3.C: Likewise. * g++.dg/ipa/ivinline-4.C: Likewise. * g++.dg/ipa/ivinline-5.C: Likewise. * g++.dg/ipa/ivinline-7.C: Likewise. * g++.dg/ipa/ivinline-8.C: Likewise. * g++.dg/ipa/ivinline-9.C: Likewise. * g++.dg/tls/pr79288.C: Likewise. * gcc.dg/addr_equal-1.c: Likewise. * gcc.dg/const-1.c: Likewise. * gcc.dg/ipa/pure-const-1.c: Likewise. * gcc.dg/noreturn-8.c: Likewise. * gcc.dg/pr33826.c: Likewise. * gcc.dg/torture/ipa-pta-1.c: Likewise. * gcc.dg/tree-ssa/alias-2.c: Likewise. * gcc.dg/tree-ssa/ipa-split-5.c: Likewise. * gcc.dg/tree-ssa/loadpre6.c: Likewise. * gcc.dg/uninit-19.c: Likewise. From-SVN: r275580 --- gcc/testsuite/ChangeLog | 24 ++++++++++++++++++++++++ gcc/testsuite/g++.dg/cpp0x/noexcept03.C | 2 +- gcc/testsuite/g++.dg/ipa/devirt-c-7.C | 3 +-- gcc/testsuite/g++.dg/ipa/ivinline-1.C | 2 +- gcc/testsuite/g++.dg/ipa/ivinline-2.C | 2 +- gcc/testsuite/g++.dg/ipa/ivinline-3.C | 2 +- gcc/testsuite/g++.dg/ipa/ivinline-4.C | 2 +- gcc/testsuite/g++.dg/ipa/ivinline-5.C | 2 +- gcc/testsuite/g++.dg/ipa/ivinline-7.C | 2 +- gcc/testsuite/g++.dg/ipa/ivinline-8.C | 2 +- gcc/testsuite/g++.dg/ipa/ivinline-9.C | 2 +- gcc/testsuite/g++.dg/tls/pr79288.C | 2 +- gcc/testsuite/gcc.dg/addr_equal-1.c | 3 +-- gcc/testsuite/gcc.dg/const-1.c | 2 +- gcc/testsuite/gcc.dg/ipa/pure-const-1.c | 2 +- gcc/testsuite/gcc.dg/noreturn-8.c | 2 +- gcc/testsuite/gcc.dg/pr33826.c | 3 +-- gcc/testsuite/gcc.dg/torture/ipa-pta-1.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/alias-2.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/ipa-split-5.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/loadpre6.c | 2 +- 21 files changed, 44 insertions(+), 23 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8d23b97..e2e2b69 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,29 @@ 2019-09-10 Christophe Lyon + * g++.dg/cpp0x/noexcept03.C: Add pie_enabled. + * g++.dg/ipa/devirt-c-7.C: Likewise. + * g++.dg/ipa/ivinline-1.C: Likewise. + * g++.dg/ipa/ivinline-2.C: Likewise. + * g++.dg/ipa/ivinline-3.C: Likewise. + * g++.dg/ipa/ivinline-4.C: Likewise. + * g++.dg/ipa/ivinline-5.C: Likewise. + * g++.dg/ipa/ivinline-7.C: Likewise. + * g++.dg/ipa/ivinline-8.C: Likewise. + * g++.dg/ipa/ivinline-9.C: Likewise. + * g++.dg/tls/pr79288.C: Likewise. + * gcc.dg/addr_equal-1.c: Likewise. + * gcc.dg/const-1.c: Likewise. + * gcc.dg/ipa/pure-const-1.c: Likewise. + * gcc.dg/noreturn-8.c: Likewise. + * gcc.dg/pr33826.c: Likewise. + * gcc.dg/torture/ipa-pta-1.c: Likewise. + * gcc.dg/tree-ssa/alias-2.c: Likewise. + * gcc.dg/tree-ssa/ipa-split-5.c: Likewise. + * gcc.dg/tree-ssa/loadpre6.c: Likewise. + * gcc.dg/uninit-19.c: Likewise. + +2019-09-10 Christophe Lyon + * g++.dg/abi/forced.C: Add *-*-uclinux*. * g++.dg/abi/guard2.C: Likewise. * g++.dg/ext/cleanup-10.C: Likewise. diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept03.C b/gcc/testsuite/g++.dg/cpp0x/noexcept03.C index 2d37867..906a44d 100644 --- a/gcc/testsuite/g++.dg/cpp0x/noexcept03.C +++ b/gcc/testsuite/g++.dg/cpp0x/noexcept03.C @@ -1,6 +1,6 @@ // Runtime test for noexcept-specification. // { dg-options "-Wnoexcept" } -// { dg-do run { target nonpic } } +// { dg-do run { target { nonpic || pie_enabled } } } // { dg-require-effective-target c++11 } #include diff --git a/gcc/testsuite/g++.dg/ipa/devirt-c-7.C b/gcc/testsuite/g++.dg/ipa/devirt-c-7.C index 2e76cbe..efb65c2 100644 --- a/gcc/testsuite/g++.dg/ipa/devirt-c-7.C +++ b/gcc/testsuite/g++.dg/ipa/devirt-c-7.C @@ -1,7 +1,6 @@ /* Verify that ipa-cp will not get confused by placement new constructing an object within another one when looking for dynamic type change . */ -/* { dg-do run } */ -/* { dg-require-effective-target nonpic } */ +/* { dg-do run { target { nonpic || pie_enabled } } } */ /* { dg-options "-O3 -Wno-attributes" } */ extern "C" void abort (void); diff --git a/gcc/testsuite/g++.dg/ipa/ivinline-1.C b/gcc/testsuite/g++.dg/ipa/ivinline-1.C index 9b10d20..2d988bc 100644 --- a/gcc/testsuite/g++.dg/ipa/ivinline-1.C +++ b/gcc/testsuite/g++.dg/ipa/ivinline-1.C @@ -1,6 +1,6 @@ /* Verify that simple virtual calls are inlined even without early inlining. */ -/* { dg-do run { target nonpic } } */ +/* { dg-do run { target { nonpic || pie_enabled } } } */ /* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp" } */ extern "C" void abort (void); diff --git a/gcc/testsuite/g++.dg/ipa/ivinline-2.C b/gcc/testsuite/g++.dg/ipa/ivinline-2.C index 21cd46f..d978638 100644 --- a/gcc/testsuite/g++.dg/ipa/ivinline-2.C +++ b/gcc/testsuite/g++.dg/ipa/ivinline-2.C @@ -1,6 +1,6 @@ /* Verify that simple virtual calls using this pointer are inlined even without early inlining.. */ -/* { dg-do run { target nonpic } } */ +/* { dg-do run { target { nonpic || pie_enabled } } } */ /* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp" } */ extern "C" void abort (void); diff --git a/gcc/testsuite/g++.dg/ipa/ivinline-3.C b/gcc/testsuite/g++.dg/ipa/ivinline-3.C index 1e24644..f756a16 100644 --- a/gcc/testsuite/g++.dg/ipa/ivinline-3.C +++ b/gcc/testsuite/g++.dg/ipa/ivinline-3.C @@ -1,6 +1,6 @@ /* Verify that simple virtual calls on an object refrence are inlined even without early inlining. */ -/* { dg-do run { target nonpic } } */ +/* { dg-do run { target { nonpic || pie_enabled } } } */ /* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp" } */ extern "C" void abort (void); diff --git a/gcc/testsuite/g++.dg/ipa/ivinline-4.C b/gcc/testsuite/g++.dg/ipa/ivinline-4.C index cf0d980..5fbd3ef 100644 --- a/gcc/testsuite/g++.dg/ipa/ivinline-4.C +++ b/gcc/testsuite/g++.dg/ipa/ivinline-4.C @@ -1,7 +1,7 @@ /* Verify that simple virtual calls are inlined even without early inlining, even when a typecast to an ancestor is involved along the way. */ -/* { dg-do run { target nonpic } } */ +/* { dg-do run { target { nonpic || pie_enabled } } } */ /* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp" } */ extern "C" void abort (void); diff --git a/gcc/testsuite/g++.dg/ipa/ivinline-5.C b/gcc/testsuite/g++.dg/ipa/ivinline-5.C index f15ebf2..6c19907 100644 --- a/gcc/testsuite/g++.dg/ipa/ivinline-5.C +++ b/gcc/testsuite/g++.dg/ipa/ivinline-5.C @@ -1,6 +1,6 @@ /* Verify that virtual call inlining does not pick a wrong method when there is a user defined ancestor in an object. */ -/* { dg-do run { target nonpic } } */ +/* { dg-do run { target { nonpic || pie_enabled } } } */ /* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp" } */ extern "C" void abort (void); diff --git a/gcc/testsuite/g++.dg/ipa/ivinline-7.C b/gcc/testsuite/g++.dg/ipa/ivinline-7.C index a7b41e7..fd6aba6 100644 --- a/gcc/testsuite/g++.dg/ipa/ivinline-7.C +++ b/gcc/testsuite/g++.dg/ipa/ivinline-7.C @@ -1,7 +1,7 @@ /* Verify that simple virtual calls are inlined even without early inlining, even when a typecast to an ancestor is involved along the way and that ancestor is not the first one with virtual functions. */ -/* { dg-do run { target nonpic } } */ +/* { dg-do run { target { nonpic || pie_enabled } } } */ /* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp" } */ extern "C" void abort (void); diff --git a/gcc/testsuite/g++.dg/ipa/ivinline-8.C b/gcc/testsuite/g++.dg/ipa/ivinline-8.C index 5c3299f..bc81abf 100644 --- a/gcc/testsuite/g++.dg/ipa/ivinline-8.C +++ b/gcc/testsuite/g++.dg/ipa/ivinline-8.C @@ -1,6 +1,6 @@ /* Verify that virtual calls are inlined (ithout early inlining) even when their caller is itself indirectly inlined. */ -/* { dg-do run { target nonpic } } */ +/* { dg-do run { target { nonpic || pie_enabled } } } */ /* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp" } */ extern "C" void abort (void); diff --git a/gcc/testsuite/g++.dg/ipa/ivinline-9.C b/gcc/testsuite/g++.dg/ipa/ivinline-9.C index 41b2381..0917f15 100644 --- a/gcc/testsuite/g++.dg/ipa/ivinline-9.C +++ b/gcc/testsuite/g++.dg/ipa/ivinline-9.C @@ -2,7 +2,7 @@ inlining, even when a typecast to an ancestor is involved along the way and that ancestor itself has an ancestor wich is not the primary base class. */ -/* { dg-do run { target nonpic } } */ +/* { dg-do run { target { nonpic || pie_enabled } } } */ /* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-cp" } */ extern "C" void abort (void); diff --git a/gcc/testsuite/g++.dg/tls/pr79288.C b/gcc/testsuite/g++.dg/tls/pr79288.C index 9f488df..da6751f 100644 --- a/gcc/testsuite/g++.dg/tls/pr79288.C +++ b/gcc/testsuite/g++.dg/tls/pr79288.C @@ -1,5 +1,5 @@ // PR c++/79288 -// { dg-do compile { target nonpic } } +// { dg-do compile { target { nonpic || pie_enabled } } } // { dg-require-effective-target tls } // { dg-options "-O2" } // { dg-final { scan-assembler-not "@tpoff" { target i?86-*-* x86_64-*-* } } } diff --git a/gcc/testsuite/gcc.dg/addr_equal-1.c b/gcc/testsuite/gcc.dg/addr_equal-1.c index 18b0dc9..35fa010 100644 --- a/gcc/testsuite/gcc.dg/addr_equal-1.c +++ b/gcc/testsuite/gcc.dg/addr_equal-1.c @@ -1,5 +1,4 @@ -/* { dg-do run } */ -/* { dg-require-effective-target nonpic } */ +/* { dg-do run { target { nonpic || pie_enabled } } } */ /* { dg-require-weak "" } */ /* { dg-require-alias "" } */ /* { dg-options "-O2 -fdelete-null-pointer-checks" } */ diff --git a/gcc/testsuite/gcc.dg/const-1.c b/gcc/testsuite/gcc.dg/const-1.c index 2e95bd8..5c2d49d 100644 --- a/gcc/testsuite/gcc.dg/const-1.c +++ b/gcc/testsuite/gcc.dg/const-1.c @@ -1,4 +1,4 @@ -/* { dg-do compile { target nonpic } } */ +/* { dg-do compile { target { nonpic || pie_enabled } } } */ /* { dg-options "-O2 -Wsuggest-attribute=const -fno-finite-loops" } */ extern int extern_const(int a) __attribute__ ((const)); diff --git a/gcc/testsuite/gcc.dg/ipa/pure-const-1.c b/gcc/testsuite/gcc.dg/ipa/pure-const-1.c index 06b415e..dd58457 100644 --- a/gcc/testsuite/gcc.dg/ipa/pure-const-1.c +++ b/gcc/testsuite/gcc.dg/ipa/pure-const-1.c @@ -1,4 +1,4 @@ -/* { dg-do compile { target nonpic } } */ +/* { dg-do compile { target { nonpic || pie_enabled } } } */ /* { dg-options "-O3 -fdump-tree-local-pure-const1 -fdump-ipa-pure-const -fdump-tree-optimized -fno-early-inlining -fgnu89-inline" } */ void abort (void); int error_code; diff --git a/gcc/testsuite/gcc.dg/noreturn-8.c b/gcc/testsuite/gcc.dg/noreturn-8.c index 294800b..ce41cab 100644 --- a/gcc/testsuite/gcc.dg/noreturn-8.c +++ b/gcc/testsuite/gcc.dg/noreturn-8.c @@ -1,4 +1,4 @@ -/* { dg-do run { target nonpic } } */ +/* { dg-do run { target { nonpic || pie_enabled } } } */ /* { dg-options "-O2" } */ void exit (int); void noreturn_autodetection_failed (); diff --git a/gcc/testsuite/gcc.dg/pr33826.c b/gcc/testsuite/gcc.dg/pr33826.c index df83915..d222774 100644 --- a/gcc/testsuite/gcc.dg/pr33826.c +++ b/gcc/testsuite/gcc.dg/pr33826.c @@ -1,8 +1,7 @@ /* Regression test for PR middle-end/33826 */ /* Verify that recursive functions cannot be pure or const. */ -/* { dg-do compile } */ -/* { dg-require-effective-target nonpic } */ +/* { dg-do compile { target { nonpic || pie_enabled } } } */ /* { dg-options "-O1 -fdump-tree-local-pure-const1 -fdump-ipa-pure-const" } */ int recurse1 (int); diff --git a/gcc/testsuite/gcc.dg/torture/ipa-pta-1.c b/gcc/testsuite/gcc.dg/torture/ipa-pta-1.c index 1bf4997..30156a3 100644 --- a/gcc/testsuite/gcc.dg/torture/ipa-pta-1.c +++ b/gcc/testsuite/gcc.dg/torture/ipa-pta-1.c @@ -1,4 +1,4 @@ -/* { dg-do compile { target { nonpic } } } */ +/* { dg-do compile { target { nonpic || pie_enabled } } } */ /* { dg-options "-fipa-pta -fdump-ipa-pta2 -fno-ipa-icf" } */ /* { dg-skip-if "" { *-*-* } { "-O0" "-fno-fat-lto-objects" } { "" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/alias-2.c b/gcc/testsuite/gcc.dg/tree-ssa/alias-2.c index e10a25d..f9d2dd4 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/alias-2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/alias-2.c @@ -1,4 +1,4 @@ -/* { dg-do compile { target { nonpic } } } */ +/* { dg-do compile { target { nonpic || pie_enabled } } } */ /* { dg-options "-O2 -fdump-tree-optimized" } */ static int a; int f; diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ipa-split-5.c b/gcc/testsuite/gcc.dg/tree-ssa/ipa-split-5.c index 2d713d6..3b5a94f 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ipa-split-5.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ipa-split-5.c @@ -1,4 +1,4 @@ -/* { dg-do compile { target nonpic } } */ +/* { dg-do compile { target { nonpic || pie_enabled } } } */ /* { dg-options "-O3 -fdump-tree-fnsplit -fdump-tree-optimized --param=builtin-expect-probability=100" } */ struct a {int a,b;}; diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loadpre6.c b/gcc/testsuite/gcc.dg/tree-ssa/loadpre6.c index 028becd..b4e9296 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/loadpre6.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/loadpre6.c @@ -1,4 +1,4 @@ -/* { dg-do compile { target nonpic } } */ +/* { dg-do compile { target { nonpic || pie_enabled } } } */ /* { dg-options "-O2 -fdump-tree-pre-stats -fdump-tree-fre1" } */ #include -- cgit v1.1 From 1ce7625c439d111b412c069e7918babf4e776310 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Tue, 10 Sep 2019 10:08:11 +0200 Subject: [ARM/FDPIC v6 19/24] [ARM][testsuite] FDPIC: Adjust pr43698.c to avoid clash with uclibc. uclibc defines bswap_32, so use a different name in this test. 2019-09-10 Christophe Lyon gcc/testsuite/ * gcc.target/arm/pr43698.c (bswap_32): Rename as my_bswap_32. From-SVN: r275581 --- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.target/arm/pr43698.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e2e2b69..6b62d88 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2019-09-10 Christophe Lyon + * gcc.target/arm/pr43698.c (bswap_32): Rename as my_bswap_32. + +2019-09-10 Christophe Lyon + * g++.dg/cpp0x/noexcept03.C: Add pie_enabled. * g++.dg/ipa/devirt-c-7.C: Likewise. * g++.dg/ipa/ivinline-1.C: Likewise. diff --git a/gcc/testsuite/gcc.target/arm/pr43698.c b/gcc/testsuite/gcc.target/arm/pr43698.c index 1fc497c..3b5dad0 100644 --- a/gcc/testsuite/gcc.target/arm/pr43698.c +++ b/gcc/testsuite/gcc.target/arm/pr43698.c @@ -6,7 +6,7 @@ char do_reverse_endian = 0; -# define bswap_32(x) \ +# define my_bswap_32(x) \ ((((x) & 0xff000000) >> 24) | \ (((x) & 0x00ff0000) >> 8) | \ (((x) & 0x0000ff00) << 8) | \ @@ -16,7 +16,7 @@ char do_reverse_endian = 0; (__extension__ ({ \ uint64_t __res; \ if (!do_reverse_endian) { __res = (X); \ - } else if (sizeof(X) == 4) { __res = bswap_32((X)); \ + } else if (sizeof(X) == 4) { __res = my_bswap_32((X)); \ } \ __res; \ })) -- cgit v1.1 From fec08d85b0f38c46ef72606fb04ed05bc4821ffa Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Tue, 10 Sep 2019 10:09:27 +0200 Subject: [ARM/FDPIC v6 21/24] [ARM] FDPIC: Handle stack-protector combined patterns The recent stack_protect_combined_set_insn and stack_protect_combined_test_insn force recomputing of GOT base, but need to take into account that in FDPIC mode, the PIC register is fixed by the ABI (r9). 2019-09-10 Christophe Lyon gcc/ * config/arm/arm.md (stack_protect_combined_set_insn): Handle FDPIC mode. (stack_protect_combined_test_insn): Likewise. From-SVN: r275582 --- gcc/ChangeLog | 6 ++++++ gcc/config/arm/arm.md | 18 ++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index afe73b5..3bf2a0b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,10 @@ 2019-09-10 Christophe Lyon + + * config/arm/arm.md (stack_protect_combined_set_insn): Handle + FDPIC mode. + (stack_protect_combined_test_insn): Likewise. + +2019-09-10 Christophe Lyon Mickaël Guêné * config/arm/arm.c (arm_load_tp): Add FDPIC support. diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 918271d..6513c2d 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -8270,8 +8270,15 @@ { if (flag_pic) { + rtx pic_reg; + + if (TARGET_FDPIC) + pic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM); + else + pic_reg = operands[3]; + /* Forces recomputing of GOT base now. */ - legitimize_pic_address (operands[1], SImode, operands[2], operands[3], + legitimize_pic_address (operands[1], SImode, operands[2], pic_reg, true /*compute_now*/); } else @@ -8346,8 +8353,15 @@ if (flag_pic) { + rtx pic_reg; + + if (TARGET_FDPIC) + pic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM); + else + pic_reg = operands[4]; + /* Forces recomputing of GOT base now. */ - legitimize_pic_address (operands[1], SImode, operands[3], operands[4], + legitimize_pic_address (operands[1], SImode, operands[3], pic_reg, true /*compute_now*/); } else -- cgit v1.1 From 18ab88559067266d602b43b4d594a21eddae0f8a Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Tue, 10 Sep 2019 10:10:41 +0200 Subject: [ARM/FDPIC v6 22/24] [ARM][testsuite] FDPIC: Skip tests that require -static support Since FDPIC does not support -static, skip the related tests. 2019-09-10 Christophe Lyon gcc/testsuite/ * lib/target-supports.exp (check_effective_target_static): Disable for ARM FDPIC target. From-SVN: r275583 --- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/lib/target-supports.exp | 3 +++ 2 files changed, 8 insertions(+) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6b62d88..9db40e4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2019-09-10 Christophe Lyon + * lib/target-supports.exp (check_effective_target_static): Disable + for ARM FDPIC target. + +2019-09-10 Christophe Lyon + * gcc.target/arm/pr43698.c (bswap_32): Rename as my_bswap_32. 2019-09-10 Christophe Lyon diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 51677cc..4f7d6cb 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -1087,6 +1087,9 @@ proc check_effective_target_pe_aligned_commons {} { # Return 1 if the target supports -static proc check_effective_target_static {} { + if { [istarget arm*-*-uclinuxfdpiceabi] } { + return 0; + } return [check_no_compiler_messages static executable { int main (void) { return 0; } } "-static"] -- cgit v1.1 From b08bcba5dc1775618e67f6486240188260084122 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Tue, 10 Sep 2019 08:12:28 +0000 Subject: decl.c (has_designator_problem): Use cp_expr_loc_or_input_loc in error_at. /cp 2019-09-10 Paolo Carlini * decl.c (has_designator_problem): Use cp_expr_loc_or_input_loc in error_at. (build_enumerator): Likewise. (cp_finish_decl): Use DECL_SOURCE_LOCATION. (grokdeclarator): Use id_loc in two error_at; change errror message about constinit together constexpr to use two ranges. /testsuite 2019-09-10 Paolo Carlini * g++.dg/cpp0x/enum29.C: Test location(s) too. * g++.dg/cpp0x/lambda/lambda-ice10.C: Likewise. * g++.dg/cpp2a/constinit3.C: Likewise. * g++.dg/ext/desig4.C: Likewise. * g++.dg/ext/label10.C: Likewise. * g++.old-deja/g++.other/dtor3.C: Likewise. From-SVN: r275585 --- gcc/cp/ChangeLog | 9 ++++++++ gcc/cp/decl.c | 28 ++++++++++++++---------- gcc/testsuite/ChangeLog | 9 ++++++++ gcc/testsuite/g++.dg/cpp0x/enum29.C | 2 +- gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice10.C | 2 +- gcc/testsuite/g++.dg/cpp2a/constinit3.C | 6 ++--- gcc/testsuite/g++.dg/ext/desig4.C | 8 +++---- gcc/testsuite/g++.dg/ext/label10.C | 2 +- gcc/testsuite/g++.old-deja/g++.other/dtor3.C | 8 +++---- 9 files changed, 49 insertions(+), 25 deletions(-) (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2b98a06..2c48829 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2019-09-10 Paolo Carlini + + * decl.c (has_designator_problem): Use cp_expr_loc_or_input_loc + in error_at. + (build_enumerator): Likewise. + (cp_finish_decl): Use DECL_SOURCE_LOCATION. + (grokdeclarator): Use id_loc in two error_at; change errror + message about constinit together constexpr to use two ranges. + 2019-09-09 Marek Polacek PR c++/84374 - diagnose invalid uses of decltype(auto). diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index dfcd7b1..8bb398b 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -6114,8 +6114,9 @@ has_designator_problem (reshape_iter *d, tsubst_flags_t complain) if (d->cur->index) { if (complain & tf_error) - error ("C99 designator %qE outside aggregate initializer", - d->cur->index); + error_at (cp_expr_loc_or_input_loc (d->cur->index), + "C99 designator %qE outside aggregate initializer", + d->cur->index); else return true; } @@ -7288,8 +7289,9 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, if ((flags & LOOKUP_CONSTINIT) && !(dk == dk_thread || dk == dk_static)) { - error ("% can only be applied to a variable with static " - "or thread storage duration"); + error_at (DECL_SOURCE_LOCATION (decl), + "% can only be applied to a variable with " + "static or thread storage duration"); return; } @@ -10628,8 +10630,9 @@ grokdeclarator (const cp_declarator *declarator, && !uniquely_derived_from_p (ctype, current_class_type)) { - error ("invalid use of qualified-name %<%T::%D%>", - qualifying_scope, decl); + error_at (id_declarator->id_loc, + "invalid use of qualified-name %<%T::%D%>", + qualifying_scope, decl); return error_mark_node; } } @@ -10816,8 +10819,9 @@ grokdeclarator (const cp_declarator *declarator, keywords shall appear in a decl-specifier-seq." */ if (constinit_p && constexpr_p) { - error_at (min_location (declspecs->locations[ds_constinit], - declspecs->locations[ds_constexpr]), + gcc_rich_location richloc (declspecs->locations[ds_constinit]); + richloc.add_range (declspecs->locations[ds_constexpr]); + error_at (&richloc, "can use at most one of the % and % " "specifiers"); return error_mark_node; @@ -11831,7 +11835,8 @@ grokdeclarator (const cp_declarator *declarator, && inner_declarator->u.id.sfk == sfk_destructor && arg_types != void_list_node) { - error ("destructors may not have parameters"); + error_at (declarator->id_loc, + "destructors may not have parameters"); arg_types = void_list_node; parms = NULL_TREE; } @@ -15171,8 +15176,9 @@ build_enumerator (tree name, tree value, tree enumtype, tree attributes, if (! INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (value))) { - error ("enumerator value for %qD must have integral or " - "unscoped enumeration type", name); + error_at (cp_expr_loc_or_input_loc (value), + "enumerator value for %qD must have integral or " + "unscoped enumeration type", name); value = NULL_TREE; } else diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9db40e4..31b54f8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2019-09-10 Paolo Carlini + + * g++.dg/cpp0x/enum29.C: Test location(s) too. + * g++.dg/cpp0x/lambda/lambda-ice10.C: Likewise. + * g++.dg/cpp2a/constinit3.C: Likewise. + * g++.dg/ext/desig4.C: Likewise. + * g++.dg/ext/label10.C: Likewise. + * g++.old-deja/g++.other/dtor3.C: Likewise. + 2019-09-10 Christophe Lyon * lib/target-supports.exp (check_effective_target_static): Disable diff --git a/gcc/testsuite/g++.dg/cpp0x/enum29.C b/gcc/testsuite/g++.dg/cpp0x/enum29.C index 63ecf7e..b7048f1 100644 --- a/gcc/testsuite/g++.dg/cpp0x/enum29.C +++ b/gcc/testsuite/g++.dg/cpp0x/enum29.C @@ -38,7 +38,7 @@ enum E0 { e0 = X0() }; enum E1 { e1 = X1() }; enum E2 { e2 = X2() }; enum E3 { e3 = X3() }; -enum E4 { e4 = X4() }; // { dg-error "integral" } +enum E4 { e4 = X4() }; // { dg-error "16:enumerator value for .e4. must have integral" } enum E5 { e5 = X5() }; // { dg-error "ambiguous" } enum F0 : int { f0 = X0() }; diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice10.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice10.C index 1ea59c2..235bfeb 100644 --- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice10.C +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice10.C @@ -4,5 +4,5 @@ template struct A { static const int i; - template const int A::i = []{ return 0; }(); // { dg-error "invalid use" } + template const int A::i = []{ return 0; }(); // { dg-error "29:invalid use" } }; diff --git a/gcc/testsuite/g++.dg/cpp2a/constinit3.C b/gcc/testsuite/g++.dg/cpp2a/constinit3.C index 316937e..1db16fe 100644 --- a/gcc/testsuite/g++.dg/cpp2a/constinit3.C +++ b/gcc/testsuite/g++.dg/cpp2a/constinit3.C @@ -31,8 +31,8 @@ int fn1 () { // Not static storage - constinit int a1 = 42; // { dg-error ".constinit. can only be applied to a variable with static or thread storage" } - constinit int a2 = 42; // { dg-error ".constinit. can only be applied to a variable with static or thread storage" } + constinit int a1 = 42; // { dg-error "17:.constinit. can only be applied to a variable with static or thread storage" } + constinit int a2 = 42; // { dg-error "17:.constinit. can only be applied to a variable with static or thread storage" } extern constinit int e1; return 0; @@ -46,7 +46,7 @@ fn3 () void fn2 (int i, constinit int p) // { dg-error "a parameter cannot be declared .constinit." } { - constinit auto l = [i](){ return i; }; // { dg-error ".constinit. can only be applied to a variable with static or thread storage" } + constinit auto l = [i](){ return i; }; // { dg-error "18:.constinit. can only be applied to a variable with static or thread storage" } } struct B { int d; }; diff --git a/gcc/testsuite/g++.dg/ext/desig4.C b/gcc/testsuite/g++.dg/ext/desig4.C index 62c3c58..902bd1f 100644 --- a/gcc/testsuite/g++.dg/ext/desig4.C +++ b/gcc/testsuite/g++.dg/ext/desig4.C @@ -1,18 +1,18 @@ // PR c++/51458 // { dg-options "" } -char g[] = { [7] = "abcd" }; // { dg-error "designator" } +char g[] = { [7] = "abcd" }; // { dg-error "15:designator .7." } int a = { .foo = 6 }; // { dg-error "designator" } -int b = { [0] = 1 }; // { dg-error "designator" } +int b = { [0] = 1 }; // { dg-error "12:designator .0." } _Complex float c = { .foo = 0, 1 }; // { dg-error "designator" } // { dg-error "either all initializer clauses should be designated or none of them should be" "" { target c++2a } .-1 } // { dg-error "cannot convert" "" { target *-*-* } .-2 } -_Complex float d = { [0] = 0, 1 }; // { dg-error "designator" } +_Complex float d = { [0] = 0, 1 }; // { dg-error "23:designator .0." } // { dg-error "either all initializer clauses should be designated or none of them should be" "" { target c++2a } .-1 } // { dg-error "cannot convert" "" { target *-*-* } .-2 } _Complex float e = { 0, .foo = 1 }; // { dg-error "designator" } // { dg-error "either all initializer clauses should be designated or none of them should be" "" { target c++2a } .-1 } // { dg-error "cannot convert" "" { target *-*-* } .-2 } -_Complex float f = { 0, [0] = 1 }; // { dg-error "designator" } +_Complex float f = { 0, [0] = 1 }; // { dg-error "26:designator .0." } // { dg-error "either all initializer clauses should be designated or none of them should be" "" { target c++2a } .-1 } // { dg-error "cannot convert" "" { target *-*-* } .-2 } diff --git a/gcc/testsuite/g++.dg/ext/label10.C b/gcc/testsuite/g++.dg/ext/label10.C index 62d235d..4ba5ae7 100644 --- a/gcc/testsuite/g++.dg/ext/label10.C +++ b/gcc/testsuite/g++.dg/ext/label10.C @@ -12,6 +12,6 @@ A<0> a; void foo () { __label__ P; - enum { O = && P }; // { dg-error "cannot appear in|integral" } + enum { O = && P }; // { dg-error "14:enumerator value for .O. must have integral|cannot appear in" } P:; } diff --git a/gcc/testsuite/g++.old-deja/g++.other/dtor3.C b/gcc/testsuite/g++.old-deja/g++.other/dtor3.C index f5a00ed..22eca46 100644 --- a/gcc/testsuite/g++.old-deja/g++.other/dtor3.C +++ b/gcc/testsuite/g++.old-deja/g++.other/dtor3.C @@ -2,27 +2,27 @@ struct S1 { - ~S1(int); // { dg-error "" } destructors may not have parameters + ~S1(int); // { dg-error "3:destructors may not have parameters" } }; template struct S2 { - ~S2(int); // { dg-error "" } destructors may not have parameters + ~S2(int); // { dg-error "3:destructors may not have parameters" } }; struct S3 { - ~S3(double) {} // { dg-error "" } destructors may not have parameters + ~S3(double) {} // { dg-error "3:destructors may not have parameters" } }; template struct S4 { - ~S4(double) {} // { dg-error "" } destructors may not have parameters + ~S4(double) {} // { dg-error "3:destructors may not have parameters" } }; -- cgit v1.1 From 873140e65d4332557301db341eb40ed285e34c6d Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 10 Sep 2019 10:15:46 +0200 Subject: re PR middle-end/91680 (Integer promotion quirk prevents efficient power of 2 division) PR middle-end/91680 * match.pd ((A / (1 << B)) -> (A >> B)): Allow widening cast from the shift type to type. * gcc.dg/tree-ssa/pr91680.c: New test. * g++.dg/torture/pr91680.C: New test. From-SVN: r275587 --- gcc/ChangeLog | 24 +++++++++++++-------- gcc/match.pd | 24 +++++++++++++++++---- gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/g++.dg/torture/pr91680.C | 35 +++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/pr91680.c | 37 +++++++++++++++++++++++++++++++++ 5 files changed, 113 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/g++.dg/torture/pr91680.C create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr91680.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3bf2a0b..6139e3c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-09-10 Jakub Jelinek + + PR middle-end/91680 + * match.pd ((A / (1 << B)) -> (A >> B)): Allow widening cast from + the shift type to type. + 2019-09-10 Christophe Lyon * config/arm/arm.md (stack_protect_combined_set_insn): Handle @@ -5,7 +11,7 @@ (stack_protect_combined_test_insn): Likewise. 2019-09-10 Christophe Lyon - Mickaël Guêné + Mickaël Guêné * config/arm/arm.c (arm_load_tp): Add FDPIC support. * config/arm/arm.md (FDPIC_REGNUM): New constant. @@ -13,7 +19,7 @@ (load_tp_soft): Disable in FDPIC mode. 2019-09-10 Christophe Lyon - Mickaël Guêné + Mickaël Guêné * config/arm/arm.c (tls_reloc): Add TLS_GD32_FDPIC, TLS_LDM32_FDPIC and TLS_IE32_FDPIC. @@ -22,7 +28,7 @@ (arm_emit_tls_decoration): Likewise. 2019-09-10 Christophe Lyon - Mickaël Guêné + Mickaël Guêné * config/arm/arm.c (arm_asm_trampoline_template): Add FDPIC support. @@ -31,7 +37,7 @@ * config/arm/arm.h (TRAMPOLINE_SIZE): Likewise. 2019-09-10 Christophe Lyon - Mickaël Guêné + Mickaël Guêné * config/arm/arm.c (arm_fdpic_local_funcdesc_p): New function. (legitimize_pic_address): Enforce binding rules on function @@ -39,20 +45,20 @@ (arm_assemble_integer): Likewise. 2019-09-10 Christophe Lyon - Mickaël Guêné + Mickaël Guêné * config/arm/arm.h (PIC_REGISTER_MAY_NEED_SAVING): New helper. * config/arm/arm.c (arm_compute_save_reg0_reg12_mask): Handle FDPIC. 2019-09-10 Christophe Lyon - Mickaël Guêné + Mickaël Guêné * ginclude/unwind-arm-common.h (unwinder_cache): Add reserved5 field. 2019-09-10 Christophe Lyon - Mickaël Guêné + Mickaël Guêné * config/arm/arm-c.c (__FDPIC__): Define new pre-processor macro in FDPIC mode. @@ -80,7 +86,7 @@ * config/arm/unspecs.md (UNSPEC_PIC_RESTORE): New. 2019-09-10 Christophe Lyon - Mickaël Guêné + Mickaël Guêné * config.gcc: Handle arm*-*-uclinuxfdpiceabi. * config/arm/bpabi.h (TARGET_FDPIC_ASM_SPEC): New. @@ -95,7 +101,7 @@ * config.gcc: Handle *-*-uclinuxfdpiceabi. 2019-09-10 Christophe Lyon - Mickaël Guêné + Mickaël Guêné * config/arm/arm.opt: Add -mfdpic option. * doc/invoke.texi: Add documentation for -mfdpic. diff --git a/gcc/match.pd b/gcc/match.pd index 5b2d95d..309a094 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -305,13 +305,29 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* (A / (1 << B)) -> (A >> B). Only for unsigned A. For signed A, this would not preserve rounding toward zero. - For example: (-1 / ( 1 << B)) != -1 >> B. */ -(simplify - (trunc_div @0 (lshift integer_onep@1 @2)) + For example: (-1 / ( 1 << B)) != -1 >> B. + Also also widening conversions, like: + (A / (unsigned long long) (1U << B)) -> (A >> B) + or + (A / (unsigned long long) (1 << B)) -> (A >> B). + If the left shift is signed, it can be done only if the upper bits + of A starting from shift's type sign bit are zero, as + (unsigned long long) (1 << 31) is -2147483648ULL, not 2147483648ULL, + so it is valid only if A >> 31 is zero. */ +(simplify + (trunc_div @0 (convert? (lshift integer_onep@1 @2))) (if ((TYPE_UNSIGNED (type) || tree_expr_nonnegative_p (@0)) && (!VECTOR_TYPE_P (type) || target_supports_op_p (type, RSHIFT_EXPR, optab_vector) - || target_supports_op_p (type, RSHIFT_EXPR, optab_scalar))) + || target_supports_op_p (type, RSHIFT_EXPR, optab_scalar)) + && (useless_type_conversion_p (type, TREE_TYPE (@1)) + || (element_precision (type) >= element_precision (TREE_TYPE (@1)) + && (TYPE_UNSIGNED (TREE_TYPE (@1)) + || (element_precision (type) + == element_precision (TREE_TYPE (@1))) + || (get_nonzero_bits (@0) + & wi::mask (element_precision (TREE_TYPE (@1)) - 1, true, + element_precision (type))) == 0)))) (rshift @0 @2))) /* Preserve explicit divisions by 0: the C++ front-end wants to detect diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 31b54f8..6f487a8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2019-09-10 Jakub Jelinek + + PR middle-end/91680 + * gcc.dg/tree-ssa/pr91680.c: New test. + * g++.dg/torture/pr91680.C: New test. + 2019-09-10 Paolo Carlini * g++.dg/cpp0x/enum29.C: Test location(s) too. diff --git a/gcc/testsuite/g++.dg/torture/pr91680.C b/gcc/testsuite/g++.dg/torture/pr91680.C new file mode 100644 index 0000000..afed400 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr91680.C @@ -0,0 +1,35 @@ +/* PR middle-end/91680 */ +/* { dg-do run { target { ilp32 || lp64 } } } */ + +extern "C" void abort (); + +#include "../../gcc.dg/tree-ssa/pr91680.c" + +int +main () +{ + unsigned char i; + for (i = 0; i < __SIZEOF_INT__ * __CHAR_BIT__; i++) + { + volatile unsigned long long q = 1 << i; + if (foo (i) != 256 / q) + abort (); + q = 1U << i; + if (bar (i) != 256 / q) + abort (); + q = 1 << i; + if (baz (i, (1U << i) - 1) != ((1U << i) - 1) / q) + abort (); + if (baz (i, 1U << i) != (1U << i) / q) + abort (); + if (baz (i, -1) != -1 / q) + abort (); + q = 1U << i; + if (qux (i, (1U << i) - 1) != ((1U << i) - 1) / q) + abort (); + if (qux (i, 1U << i) != (1U << i) / q) + abort (); + if (qux (i, -1) != -1 / q) + abort (); + } +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr91680.c b/gcc/testsuite/gcc.dg/tree-ssa/pr91680.c new file mode 100644 index 0000000..6d1912b --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr91680.c @@ -0,0 +1,37 @@ +/* PR middle-end/91680 */ +/* { dg-do compile { target { ilp32 || lp64 } } } */ +/* { dg-options "-O2 -fdump-tree-forwprop1" } */ +/* { dg-final { scan-tree-dump-times " / " 1 "forwprop1" } } */ +/* { dg-final { scan-tree-dump-times " >> " 3 "forwprop1" } } */ + +__attribute__((noipa)) unsigned long long +foo (unsigned char x) +{ + unsigned long long q = 1 << x; + return 256 / q; +} + +__attribute__((noipa)) unsigned long long +bar (unsigned char x) +{ + unsigned long long q = 1U << x; + return 256 / q; +} + +__attribute__((noipa)) unsigned long long +baz (unsigned char x, unsigned long long y) +{ + /* This can't be optimized, at least not in C++ and maybe not + in C89, because for x 31 q is -2147483648ULL, not + 2147483648ULL, and e.g. 2147483648ULL >> 31 is 1, while + 2147483648ULL / -2147483648ULL is 0. */ + unsigned long long q = 1 << x; + return y / q; +} + +__attribute__((noipa)) unsigned long long +qux (unsigned char x, unsigned long long y) +{ + unsigned long long q = 1U << x; + return y / q; +} -- cgit v1.1 From 903a9d25e9a7d86ff9d258afc203cd83a893a8bf Mon Sep 17 00:00:00 2001 From: Arnaud Charlet Date: Tue, 10 Sep 2019 10:17:14 +0000 Subject: * doc/install.texi: Fix syntax for html generation. From-SVN: r275589 --- gcc/ChangeLog | 4 ++++ gcc/doc/install.texi | 7 ++++++- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6139e3c..1c373c7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2019-09-10 Arnaud Charlet + + * doc/install.texi: Fix syntax for html generation. + 2019-09-10 Jakub Jelinek PR middle-end/91680 diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi index 6f4dd7b..dd36a1e 100644 --- a/gcc/doc/install.texi +++ b/gcc/doc/install.texi @@ -2727,7 +2727,12 @@ and network filesystems. @section Building the Ada compiler -See @ref{GNAT-prerequisite}. +@ifnothtml +@ref{GNAT-prerequisite}. +@end ifnothtml +@ifhtml +@uref{GNAT-prerequisite}. +@end ifhtml @section Building with profile feedback -- cgit v1.1 From ef8febf85853e289951278ab5cb7ba6f4e3d2cd1 Mon Sep 17 00:00:00 2001 From: David Edelsohn Date: Tue, 10 Sep 2019 14:59:37 +0000 Subject: default_format_1.f90: Remove XFAIL AIX. * gfortran.dg/default_format_1.f90: Remove XFAIL AIX. * gfortran.dg/default_format_denormal_1.f90: Same. From-SVN: r275591 --- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gfortran.dg/default_format_1.f90 | 2 +- gcc/testsuite/gfortran.dg/default_format_denormal_1.f90 | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6f487a8..c8779bb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-10 David Edelsohn + + * gfortran.dg/default_format_1.f90: Remove XFAIL AIX. + * gfortran.dg/default_format_denormal_1.f90: Same. + 2019-09-10 Jakub Jelinek PR middle-end/91680 diff --git a/gcc/testsuite/gfortran.dg/default_format_1.f90 b/gcc/testsuite/gfortran.dg/default_format_1.f90 index cafda89..05e9454 100644 --- a/gcc/testsuite/gfortran.dg/default_format_1.f90 +++ b/gcc/testsuite/gfortran.dg/default_format_1.f90 @@ -1,4 +1,4 @@ -! { dg-do run { xfail powerpc-ibm-aix* } } +! { dg-do run } ! Test XFAILed on Darwin because the system's printf() lacks ! proper support for denormals. ! diff --git a/gcc/testsuite/gfortran.dg/default_format_denormal_1.f90 b/gcc/testsuite/gfortran.dg/default_format_denormal_1.f90 index 6ae79a3..fb7c364 100644 --- a/gcc/testsuite/gfortran.dg/default_format_denormal_1.f90 +++ b/gcc/testsuite/gfortran.dg/default_format_denormal_1.f90 @@ -1,4 +1,4 @@ -! { dg-do run { xfail *-*-darwin[89]* *-*-cygwin* powerpc-ibm-aix* } } +! { dg-do run { xfail *-*-darwin[89]* *-*-cygwin* } } ! Test XFAILed on these platforms because the system's printf() lacks ! proper support for denormals. ! -- cgit v1.1 From 68a57628f482c75003abfc77b5c2a3be029668fa Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Tue, 10 Sep 2019 18:15:16 +0200 Subject: Rename Deprecated to WarnRemoved in *.opt files. 2019-09-10 Martin Liska * common.opt: Use newly added WarnRemoved. * config/aarch64/aarch64.opt: Likewise. * config/arm/arm.opt: Likewise. * config/i386/i386.opt: Likewise. * config/ia64/ia64.opt: Likewise. * config/rs6000/rs6000.opt: Likewise. * doc/options.texi: Document WarnRemoved properly. * dwarf2out.c (gen_producer_string): Handle renamed OPT_SPECIAL_warn_removed. * lto-opts.c (lto_write_options): Likewise. * lto-wrapper.c (merge_and_complain): Likewise. * opts-common.c (decode_cmdline_option): Likewise. (prune_options): Likewise. (read_cmdline_option): Likewise. (control_warning_option): Likewise. * opts.c (print_filtered_help): Likewise. * optc-gen.awk: Parse for WarnRemoved and make usage of Deprecated an error. * opth-gen.awk: Generate new OPT_SPECIAL_warn_removed. 2019-09-10 Martin Liska * c.opt: Use newly added WarnRemoved. From-SVN: r275592 --- gcc/ChangeLog | 22 ++++++++++ gcc/c-family/ChangeLog | 4 ++ gcc/c-family/c.opt | 92 +++++++++++++++++++++--------------------- gcc/common.opt | 8 ++-- gcc/config/aarch64/aarch64.opt | 2 +- gcc/config/arm/arm.opt | 2 +- gcc/config/i386/i386.opt | 9 ++--- gcc/config/ia64/ia64.opt | 4 +- gcc/config/rs6000/rs6000.opt | 6 +-- gcc/doc/options.texi | 6 +-- gcc/dwarf2out.c | 2 +- gcc/lto-opts.c | 2 +- gcc/lto-wrapper.c | 2 +- gcc/optc-gen.awk | 10 +++-- gcc/opth-gen.awk | 2 +- gcc/opts-common.c | 10 ++--- gcc/opts.c | 2 +- 17 files changed, 105 insertions(+), 80 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1c373c7..1bd7fa2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,25 @@ +2019-09-10 Martin Liska + + * common.opt: Use newly added WarnRemoved. + * config/aarch64/aarch64.opt: Likewise. + * config/arm/arm.opt: Likewise. + * config/i386/i386.opt: Likewise. + * config/ia64/ia64.opt: Likewise. + * config/rs6000/rs6000.opt: Likewise. + * doc/options.texi: Document WarnRemoved properly. + * dwarf2out.c (gen_producer_string): Handle renamed + OPT_SPECIAL_warn_removed. + * lto-opts.c (lto_write_options): Likewise. + * lto-wrapper.c (merge_and_complain): Likewise. + * opts-common.c (decode_cmdline_option): Likewise. + (prune_options): Likewise. + (read_cmdline_option): Likewise. + (control_warning_option): Likewise. + * opts.c (print_filtered_help): Likewise. + * optc-gen.awk: Parse for WarnRemoved and make usage + of Deprecated an error. + * opth-gen.awk: Generate new OPT_SPECIAL_warn_removed. + 2019-09-10 Arnaud Charlet * doc/install.texi: Fix syntax for html generation. diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 7e838fb2..2b700c2 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,7 @@ +2019-09-10 Martin Liska + + * c.opt: Use newly added WarnRemoved. + 2019-09-09 Martin Liska * c.opt: Update comment of removed diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index c580447..88bbe2e 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -428,7 +428,7 @@ C ObjC C++ ObjC++ Var(warn_char_subscripts) Warning LangEnabledBy(C ObjC C++ Obj Warn about subscripts whose type is \"char\". Wchkp -C ObjC C++ ObjC++ Warning Deprecated +C ObjC C++ ObjC++ Warning WarnRemoved Removed in GCC 9. This switch has no effect. Wclobbered @@ -864,7 +864,7 @@ C ObjC Var(warn_missing_prototypes) Warning Warn about global functions without prototypes. Wmudflap -C ObjC C++ ObjC++ Deprecated +C ObjC C++ ObjC++ WarnRemoved Wmultichar C ObjC C++ ObjC++ CPP(warn_multichar) CppReason(CPP_W_MULTICHAR) Var(cpp_warn_multichar) Init(0) Warning @@ -1302,14 +1302,14 @@ C++ ObjC++ Joined RejectNegative Var(aligned_new_threshold) UInteger Init(-1) -faligned-new= Use C++17 over-aligned type allocation for alignments greater than N. fall-virtual -C++ ObjC++ Deprecated +C++ ObjC++ WarnRemoved fallow-parameterless-variadic-functions C ObjC Var(flag_allow_parameterless_variadic_functions) Allow variadic functions without named parameter. falt-external-templates -C++ ObjC++ Deprecated +C++ ObjC++ WarnRemoved No longer supported. fasm @@ -1337,86 +1337,86 @@ Enable the char8_t fundamental type and use it as the type for UTF-8 string and character literals. fcheck-pointer-bounds -C ObjC C++ ObjC++ LTO Deprecated +C ObjC C++ ObjC++ LTO WarnRemoved Removed in GCC 9. This switch has no effect. fchkp-check-incomplete-type -C ObjC C++ ObjC++ LTO Deprecated +C ObjC C++ ObjC++ LTO WarnRemoved Removed in GCC 9. This switch has no effect. fchkp-zero-input-bounds-for-main -C ObjC C++ ObjC++ LTO Deprecated +C ObjC C++ ObjC++ LTO WarnRemoved Removed in GCC 9. This switch has no effect. fchkp-first-field-has-own-bounds -C ObjC C++ ObjC++ LTO Deprecated RejectNegative +C ObjC C++ ObjC++ LTO WarnRemoved RejectNegative Removed in GCC 9. This switch has no effect. fchkp-narrow-bounds -C ObjC C++ ObjC++ LTO Deprecated +C ObjC C++ ObjC++ LTO WarnRemoved Removed in GCC 9. This switch has no effect. fchkp-narrow-to-innermost-array -C ObjC C++ ObjC++ LTO Deprecated RejectNegative +C ObjC C++ ObjC++ LTO WarnRemoved RejectNegative Removed in GCC 9. This switch has no effect. fchkp-flexible-struct-trailing-arrays -C ObjC C++ ObjC++ LTO Deprecated +C ObjC C++ ObjC++ LTO WarnRemoved Removed in GCC 9. This switch has no effect. fchkp-optimize -C ObjC C++ ObjC++ LTO Deprecated +C ObjC C++ ObjC++ LTO WarnRemoved fchkp-use-fast-string-functions -C ObjC C++ ObjC++ LTO Deprecated +C ObjC C++ ObjC++ LTO WarnRemoved Removed in GCC 9. This switch has no effect. fchkp-use-nochk-string-functions -C ObjC C++ ObjC++ LTO Deprecated +C ObjC C++ ObjC++ LTO WarnRemoved Removed in GCC 9. This switch has no effect. fchkp-use-static-bounds -C ObjC C++ ObjC++ LTO Deprecated +C ObjC C++ ObjC++ LTO WarnRemoved Removed in GCC 9. This switch has no effect. fchkp-use-static-const-bounds -C ObjC C++ ObjC++ LTO Deprecated +C ObjC C++ ObjC++ LTO WarnRemoved Removed in GCC 9. This switch has no effect. fchkp-treat-zero-dynamic-size-as-infinite -C ObjC C++ ObjC++ LTO Deprecated +C ObjC C++ ObjC++ LTO WarnRemoved Removed in GCC 9. This switch has no effect. fchkp-check-read -C ObjC C++ ObjC++ LTO Deprecated +C ObjC C++ ObjC++ LTO WarnRemoved Removed in GCC 9. This switch has no effect. fchkp-check-write -C ObjC C++ ObjC++ LTO Deprecated +C ObjC C++ ObjC++ LTO WarnRemoved Removed in GCC 9. This switch has no effect. fchkp-store-bounds -C ObjC C++ ObjC++ LTO Deprecated +C ObjC C++ ObjC++ LTO WarnRemoved Removed in GCC 9. This switch has no effect. fchkp-instrument-calls -C ObjC C++ ObjC++ LTO Deprecated +C ObjC C++ ObjC++ LTO WarnRemoved Removed in GCC 9. This switch has no effect. fchkp-instrument-marked-only -C ObjC C++ ObjC++ LTO Deprecated +C ObjC C++ ObjC++ LTO WarnRemoved Removed in GCC 9. This switch has no effect. fchkp-use-wrappers -C ObjC C++ ObjC++ LTO Deprecated +C ObjC C++ ObjC++ LTO WarnRemoved Removed in GCC 9. This switch has no effect. static-libmpx -Driver Deprecated +Driver WarnRemoved Removed in GCC 9. This switch has no effect. static-libmpxwrappers -Driver Deprecated +Driver WarnRemoved Removed in GCC 9. This switch has no effect. fcilkplus @@ -1507,7 +1507,7 @@ C++ ObjC++ Var(flag_enforce_eh_specs) Init(1) Generate code to check exception specifications. fenum-int-equiv -C++ ObjC++ Deprecated +C++ ObjC++ WarnRemoved fexec-charset= C ObjC C++ ObjC++ Joined RejectNegative @@ -1526,10 +1526,10 @@ C++ ObjC++ Var(flag_extern_tls_init) Init(-1) Support dynamic initialization of thread-local variables in a different translation unit. fexternal-templates -C++ ObjC++ Deprecated +C++ ObjC++ WarnRemoved ffor-scope -C++ ObjC++ Deprecated +C++ ObjC++ WarnRemoved ffreestanding C ObjC C++ ObjC++ @@ -1548,20 +1548,20 @@ C ObjC Var(flag_gnu89_inline) Init(-1) Use traditional GNU semantics for inline functions. fguiding-decls -C++ ObjC++ Deprecated +C++ ObjC++ WarnRemoved fhandle-exceptions C++ ObjC++ Optimization Alias(fexceptions) Warn({%<-fhandle-exceptions%> has been renamed %<-fexceptions%> (and is now on by default)}) fhonor-std -C++ ObjC++ Deprecated +C++ ObjC++ WarnRemoved fhosted C ObjC Assume normal C execution environment. fhuge-objects -C++ ObjC++ Deprecated +C++ ObjC++ WarnRemoved No longer supported. fimplement-inlines @@ -1581,14 +1581,14 @@ C++ ObjC++ Var(flag_new_inheriting_ctors) Init(1) Implement C++17 inheriting constructor semantics. ffriend-injection -C++ ObjC++ Deprecated +C++ ObjC++ WarnRemoved fkeep-inline-dllexport C C++ ObjC ObjC++ Var(flag_keep_inline_dllexport) Init(1) Report Condition(TARGET_DLLIMPORT_DECL_ATTRIBUTES) Don't emit dllexported inline functions unless needed. flabels-ok -C++ ObjC++ Deprecated +C++ ObjC++ WarnRemoved flax-vector-conversions C ObjC C++ ObjC++ Var(flag_lax_vector_conversions) @@ -1603,19 +1603,19 @@ C ObjC C++ ObjC++ Var(flag_ms_extensions) Don't warn about uses of Microsoft extensions. fmudflap -C ObjC C++ ObjC++ Deprecated +C ObjC C++ ObjC++ WarnRemoved fmudflapth -C ObjC C++ ObjC++ Deprecated +C ObjC C++ ObjC++ WarnRemoved fmudflapir -C ObjC C++ ObjC++ Deprecated +C ObjC C++ ObjC++ WarnRemoved fname-mangling-version- -C++ ObjC++ Joined Deprecated +C++ ObjC++ Joined WarnRemoved fnew-abi -C++ ObjC++ Deprecated +C++ ObjC++ WarnRemoved fnew-ttp-matching C++ ObjC++ Var(flag_new_ttp) @@ -1656,7 +1656,7 @@ fnonansi-builtins C++ ObjC++ Var(flag_no_nonansi_builtin, 0) fnonnull-objects -C++ ObjC++ Deprecated +C++ ObjC++ WarnRemoved fnothrow-opt C++ ObjC++ Optimization Var(flag_nothrow_opt) @@ -1763,7 +1763,7 @@ ObjC ObjC++ LTO Var(flag_replace_objc_classes) Used in Fix-and-Continue mode to indicate that object files may be swapped in at runtime. frepo -C++ ObjC++ Deprecated +C++ ObjC++ WarnRemoved Removed in GCC 10. This switch has no effect. frtti @@ -1791,7 +1791,7 @@ C++ ObjC++ Var(flag_sized_deallocation) Init(-1) Enable C++14 sized deallocation support. fsquangle -C++ ObjC++ Deprecated +C++ ObjC++ WarnRemoved fsso-struct= C ObjC Joined RejectNegative Enum(sso_struct) Var(default_sso) Init(SSO_NATIVE) @@ -1818,7 +1818,7 @@ C++ ObjC++ Optimization Var(flag_strict_enums) Assume that values of enumeration type are always within the minimum range of that type. fstrict-prototype -C++ ObjC++ Deprecated +C++ ObjC++ WarnRemoved fstrong-eval-order C++ ObjC++ Common Alias(fstrong-eval-order=, all, none) @@ -1858,7 +1858,7 @@ C++ ObjC++ Joined RejectNegative UInteger -ftemplate-depth= Specify maximum template instantiation depth. fthis-is-variable -C++ ObjC++ Deprecated +C++ ObjC++ WarnRemoved fthreadsafe-statics C++ ObjC++ Optimization Var(flag_threadsafe_statics) Init(1) @@ -1889,11 +1889,11 @@ C++ ObjC++ Var(flag_visibility_ms_compat) Changes visibility to match Microsoft Visual Studio by default. fvtable-gc -C++ ObjC++ Deprecated +C++ ObjC++ WarnRemoved No longer supported. fvtable-thunks -C++ ObjC++ Deprecated +C++ ObjC++ WarnRemoved No longer supported. fweak @@ -1909,7 +1909,7 @@ C ObjC C++ ObjC++ Var(flag_working_directory) Init(-1) Generate a #line directive pointing at the current working directory. fxref -C++ ObjC++ Deprecated +C++ ObjC++ WarnRemoved No longer supported. fzero-link diff --git a/gcc/common.opt b/gcc/common.opt index 0d165f5..1b9e0f3 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -2992,19 +2992,19 @@ Common Driver Var(dwarf2out_as_locview_support) Init(2) Assume assembler support for view in (DWARF2+) .loc directives. gcoff -Common Driver Deprecated +Common Driver WarnRemoved Does nothing. Preserved for backward compatibility. gcoff1 -Common Driver Deprecated +Common Driver WarnRemoved Does nothing. Preserved for backward compatibility. gcoff2 -Common Driver Deprecated +Common Driver WarnRemoved Does nothing. Preserved for backward compatibility. gcoff3 -Common Driver Deprecated +Common Driver WarnRemoved Does nothing. Preserved for backward compatibility. gcolumn-info diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt index 2c8b22c..55d4660 100644 --- a/gcc/config/aarch64/aarch64.opt +++ b/gcc/config/aarch64/aarch64.opt @@ -157,7 +157,7 @@ Target RejectNegative Joined Var(aarch64_branch_protection_string) Save Use branch-protection features. msign-return-address= -Target Deprecated RejectNegative Joined Enum(aarch64_ra_sign_scope_t) Var(aarch64_ra_sign_scope) Init(AARCH64_FUNCTION_NONE) Save +Target WarnRemoved RejectNegative Joined Enum(aarch64_ra_sign_scope_t) Var(aarch64_ra_sign_scope) Init(AARCH64_FUNCTION_NONE) Save Select return address signing scope. Enum diff --git a/gcc/config/arm/arm.opt b/gcc/config/arm/arm.opt index 545ec49..452f0cf 100644 --- a/gcc/config/arm/arm.opt +++ b/gcc/config/arm/arm.opt @@ -276,7 +276,7 @@ Target Report Var(unaligned_access) Init(2) Save Enable unaligned word and halfword accesses to packed data. mneon-for-64bits -Target Deprecated +Target WarnRemoved This option is deprecated and has no effect. mslow-flash-data diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index 5d47212..0483bb5 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -377,7 +377,6 @@ Inline memset/memcpy string operations, but perform inline version only for smal mintel-syntax Target Undocumented Alias(masm=, intel, att) Warn(%<-mintel-syntax%> and %<-mno-intel-syntax%> are deprecated; use %<-masm=intel%> and %<-masm=att%> instead) -;; Deprecated mms-bitfields Target Report Mask(MS_BITFIELD_LAYOUT) Save @@ -850,8 +849,7 @@ Target Report Mask(ISA_CLWB) Var(ix86_isa_flags) Save Support CLWB instruction. mpcommit -Target Deprecated -;; Deprecated +Target WarnRemoved mfxsr Target Report Mask(ISA_FXSR) Var(ix86_isa_flags) Save @@ -967,7 +965,7 @@ Target Report Mask(ISA_RTM) Var(ix86_isa_flags) Save Support RTM built-in functions and code generation. mmpx -Target Deprecated +Target WarnRemoved Removed in GCC 9. This switch has no effect. mmwaitx @@ -1015,8 +1013,7 @@ Target RejectNegative Joined Integer Var(ix86_stack_protector_guard_symbol_str) Use the given symbol for addressing the stack-protector guard. mmitigate-rop -Target Deprecated -;; Deprecated +Target WarnRemoved mgeneral-regs-only Target Report RejectNegative Mask(GENERAL_REGS_ONLY) Var(ix86_target_flags) Save diff --git a/gcc/config/ia64/ia64.opt b/gcc/config/ia64/ia64.opt index 9d2bbe1..07da8a2 100644 --- a/gcc/config/ia64/ia64.opt +++ b/gcc/config/ia64/ia64.opt @@ -164,10 +164,10 @@ Target Report Var(mflag_sched_spec_control_ldc) Init(0) Use simple data speculation check for control speculation. msched-prefer-non-data-spec-insns -Target Deprecated +Target WarnRemoved msched-prefer-non-control-spec-insns -Target Deprecated +Target WarnRemoved msched-count-spec-in-critical-path Target Report Var(mflag_sched_count_spec_in_critical_path) Init(0) diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt index 1b69507..1f37a92 100644 --- a/gcc/config/rs6000/rs6000.opt +++ b/gcc/config/rs6000/rs6000.opt @@ -149,7 +149,7 @@ mno-mfpgpr Target RejectNegative Undocumented Ignore mmfpgpr -Target RejectNegative Undocumented Deprecated +Target RejectNegative Undocumented WarnRemoved maltivec Target Report Mask(ALTIVEC) Var(rs6000_isa_flags) @@ -180,7 +180,7 @@ mno-string Target RejectNegative Undocumented Ignore mstring -Target RejectNegative Undocumented Deprecated +Target RejectNegative Undocumented WarnRemoved msoft-float Target Report RejectNegative Mask(SOFT_FLOAT) Var(rs6000_isa_flags) @@ -479,7 +479,7 @@ Target Report Mask(CRYPTO) Var(rs6000_isa_flags) Use ISA 2.07 Category:Vector.AES and Category:Vector.SHA2 instructions. mdirect-move -Target Undocumented Mask(DIRECT_MOVE) Var(rs6000_isa_flags) Deprecated +Target Undocumented Mask(DIRECT_MOVE) Var(rs6000_isa_flags) WarnRemoved mhtm Target Report Mask(HTM) Var(rs6000_isa_flags) diff --git a/gcc/doc/options.texi b/gcc/doc/options.texi index 1c83d24..b59f4d3 100644 --- a/gcc/doc/options.texi +++ b/gcc/doc/options.texi @@ -314,9 +314,9 @@ The state of this option should be stored in variable @var{var} (actually a macro for @code{global_options.x_@var{var}}). The way that the state is stored depends on the type of option: -@item Deprecated -The option is deprecated and every usage of such option will -result in a warning. +@item WarnRemoved +The option is removed and every usage of such option will +result in a warning. We use it option backward compatibility. @item Var(@var{var}, @var{set}) The option controls an integer variable @var{var} and is active when diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index aa7fd7e..279c6b7 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -24432,7 +24432,7 @@ gen_producer_string (void) case OPT_U: case OPT_SPECIAL_unknown: case OPT_SPECIAL_ignore: - case OPT_SPECIAL_deprecated: + case OPT_SPECIAL_warn_removed: case OPT_SPECIAL_program_name: case OPT_SPECIAL_input_file: case OPT_grecord_gcc_switches: diff --git a/gcc/lto-opts.c b/gcc/lto-opts.c index 5e59e93..494d9c2 100644 --- a/gcc/lto-opts.c +++ b/gcc/lto-opts.c @@ -122,7 +122,7 @@ lto_write_options (void) case OPT_dumpbase: case OPT_SPECIAL_unknown: case OPT_SPECIAL_ignore: - case OPT_SPECIAL_deprecated: + case OPT_SPECIAL_warn_removed: case OPT_SPECIAL_program_name: case OPT_SPECIAL_input_file: case OPT_dumpdir: diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c index 75ed289..5423adb 100644 --- a/gcc/lto-wrapper.c +++ b/gcc/lto-wrapper.c @@ -247,7 +247,7 @@ merge_and_complain (struct cl_decoded_option **decoded_options, { case OPT_SPECIAL_unknown: case OPT_SPECIAL_ignore: - case OPT_SPECIAL_deprecated: + case OPT_SPECIAL_warn_removed: case OPT_SPECIAL_program_name: case OPT_SPECIAL_input_file: break; diff --git a/gcc/optc-gen.awk b/gcc/optc-gen.awk index 85f68a6..1519592 100644 --- a/gcc/optc-gen.awk +++ b/gcc/optc-gen.awk @@ -332,12 +332,14 @@ for (i = 0; i < n_opts; i++) { if (flag_set_p("Report", flags[i])) print "#error Ignored option with Report" } - else if (flag_set_p("Deprecated", flags[i])) { - alias_data = "NULL, NULL, OPT_SPECIAL_deprecated" + else if (flag_set_p("Deprecated", flags[i])) + print "#error Deprecated was replaced with WarnRemoved" + else if (flag_set_p("WarnRemoved", flags[i])) { + alias_data = "NULL, NULL, OPT_SPECIAL_warn_removed" if (warn_message != "NULL") - print "#error Deprecated option with Warn" + print "#error WarnRemoved option with Warn" if (flag_set_p("Report", flags[i])) - print "#error Deprecated option with Report" + print "#error WarnRemoved option with Report" } else alias_data = "NULL, NULL, N_OPTS" diff --git a/gcc/opth-gen.awk b/gcc/opth-gen.awk index 297456f..e19626a 100644 --- a/gcc/opth-gen.awk +++ b/gcc/opth-gen.awk @@ -494,7 +494,7 @@ for (i = 0; i < n_opts; i++) { print " N_OPTS," print " OPT_SPECIAL_unknown," print " OPT_SPECIAL_ignore," -print " OPT_SPECIAL_deprecated," +print " OPT_SPECIAL_warn_removed," print " OPT_SPECIAL_program_name," print " OPT_SPECIAL_input_file" print "};" diff --git a/gcc/opts-common.c b/gcc/opts-common.c index 200951b..b4ec1bd 100644 --- a/gcc/opts-common.c +++ b/gcc/opts-common.c @@ -667,7 +667,7 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask, size_t new_opt_index = option->alias_target; if (new_opt_index == OPT_SPECIAL_ignore - || new_opt_index == OPT_SPECIAL_deprecated) + || new_opt_index == OPT_SPECIAL_warn_removed) { gcc_assert (option->alias_arg == NULL); gcc_assert (option->neg_alias_arg == NULL); @@ -840,7 +840,7 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask, decoded->canonical_option[i] = NULL; } if (opt_index != OPT_SPECIAL_unknown && opt_index != OPT_SPECIAL_ignore - && opt_index != OPT_SPECIAL_deprecated) + && opt_index != OPT_SPECIAL_warn_removed) { generate_canonical_option (opt_index, arg, value, decoded); if (separate_args > 1) @@ -1018,7 +1018,7 @@ prune_options (struct cl_decoded_option **decoded_options, { case OPT_SPECIAL_unknown: case OPT_SPECIAL_ignore: - case OPT_SPECIAL_deprecated: + case OPT_SPECIAL_warn_removed: case OPT_SPECIAL_program_name: case OPT_SPECIAL_input_file: goto keep; @@ -1348,7 +1348,7 @@ read_cmdline_option (struct gcc_options *opts, if (decoded->opt_index == OPT_SPECIAL_ignore) return; - if (decoded->opt_index == OPT_SPECIAL_deprecated) + if (decoded->opt_index == OPT_SPECIAL_warn_removed) { /* Warn only about positive ignored options. */ if (decoded->value) @@ -1653,7 +1653,7 @@ control_warning_option (unsigned int opt_index, int kind, const char *arg, arg = cl_options[opt_index].alias_arg; opt_index = cl_options[opt_index].alias_target; } - if (opt_index == OPT_SPECIAL_ignore || opt_index == OPT_SPECIAL_deprecated) + if (opt_index == OPT_SPECIAL_ignore || opt_index == OPT_SPECIAL_warn_removed) return; if (dc) diagnostic_classify_diagnostic (dc, opt_index, (diagnostic_t) kind, loc); diff --git a/gcc/opts.c b/gcc/opts.c index 07f701c..efd75aa 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -1541,7 +1541,7 @@ print_filtered_help (unsigned int include_flags, if (print_state) { if (option->alias_target < N_OPTS - && option->alias_target != OPT_SPECIAL_deprecated + && option->alias_target != OPT_SPECIAL_warn_removed && option->alias_target != OPT_SPECIAL_ignore && option->alias_target != OPT_SPECIAL_input_file && option->alias_target != OPT_SPECIAL_program_name -- cgit v1.1 From e8b0314a583b028ad2d6508b455e33f5787bffe1 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 10 Sep 2019 16:19:23 +0000 Subject: Make get_call_rtx_from take a const rtx_insn * Only one caller (in dwarf2out.c) was preventing get_call_rtx_from from taking an rtx_insn *. Since that caller just passes a PATTERN, it's a trivial change to make. 2019-09-10 Richard Sandiford gcc/ * rtl.h (get_call_rtx_from): Take a const rtx_insn * instead of an rtx. * rtlanal.c (get_call_rtx_from): Likewise. * dwarf2out.c (dwarf2out_var_location): Pass the insn rather than the pattern to get_call_rtx_from. * config/i386/i386-expand.h (ix86_notrack_prefixed_insn_p): Take an rtx_insn * instead of an rtx. * config/i386/i386-expand.c (ix86_notrack_prefixed_insn_p): Likewise. From-SVN: r275593 --- gcc/ChangeLog | 10 ++++++++++ gcc/config/i386/i386-expand.c | 2 +- gcc/config/i386/i386-expand.h | 2 +- gcc/dwarf2out.c | 2 +- gcc/rtl.h | 2 +- gcc/rtlanal.c | 5 ++--- 6 files changed, 16 insertions(+), 7 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1bd7fa2..0ec847c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2019-09-10 Richard Sandiford + + * rtl.h (get_call_rtx_from): Take a const rtx_insn * instead of an rtx. + * rtlanal.c (get_call_rtx_from): Likewise. + * dwarf2out.c (dwarf2out_var_location): Pass the insn rather + than the pattern to get_call_rtx_from. + * config/i386/i386-expand.h (ix86_notrack_prefixed_insn_p): Take + an rtx_insn * instead of an rtx. + * config/i386/i386-expand.c (ix86_notrack_prefixed_insn_p): Likewise. + 2019-09-10 Martin Liska * common.opt: Use newly added WarnRemoved. diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c index 862cd81..22c2823 100644 --- a/gcc/config/i386/i386-expand.c +++ b/gcc/config/i386/i386-expand.c @@ -19969,7 +19969,7 @@ ix86_expand_sse2_mulvxdi3 (rtx op0, rtx op1, rtx op2) should be encoded with notrack prefix. */ bool -ix86_notrack_prefixed_insn_p (rtx insn) +ix86_notrack_prefixed_insn_p (rtx_insn *insn) { if (!insn || !((flag_cf_protection & CF_BRANCH))) return false; diff --git a/gcc/config/i386/i386-expand.h b/gcc/config/i386/i386-expand.h index 9271bb8..70b6b28 100644 --- a/gcc/config/i386/i386-expand.h +++ b/gcc/config/i386/i386-expand.h @@ -50,7 +50,7 @@ rtx ix86_expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode, int ignore); bool ix86_vectorize_vec_perm_const (machine_mode vmode, rtx target, rtx op0, rtx op1, const vec_perm_indices &sel); -bool ix86_notrack_prefixed_insn_p (rtx insn); +bool ix86_notrack_prefixed_insn_p (rtx_insn *); machine_mode ix86_split_reduction (machine_mode mode); void ix86_expand_divmod_libfunc (rtx libfunc, machine_mode mode, rtx op0, rtx op1, rtx *quot_p, rtx *rem_p); diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 279c6b7..c359c2d 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -27505,7 +27505,7 @@ create_label: ca_loc->tail_call_p = SIBLING_CALL_P (prev); /* Look for a SYMBOL_REF in the "prev" instruction. */ - rtx x = get_call_rtx_from (PATTERN (prev)); + rtx x = get_call_rtx_from (prev); if (x) { /* Try to get the call symbol, if any. */ diff --git a/gcc/rtl.h b/gcc/rtl.h index 911b563..c054861 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -3419,7 +3419,7 @@ extern bool nonzero_address_p (const_rtx); extern int rtx_unstable_p (const_rtx); extern bool rtx_varies_p (const_rtx, bool); extern bool rtx_addr_varies_p (const_rtx, bool); -extern rtx get_call_rtx_from (rtx); +extern rtx get_call_rtx_from (const rtx_insn *); extern HOST_WIDE_INT get_integer_term (const_rtx); extern rtx get_related_value (const_rtx); extern bool offset_within_block_p (const_rtx, HOST_WIDE_INT); diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 3dcdc84..dfc6fe2 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -811,10 +811,9 @@ rtx_addr_varies_p (const_rtx x, bool for_alias) /* Return the CALL in X if there is one. */ rtx -get_call_rtx_from (rtx x) +get_call_rtx_from (const rtx_insn *insn) { - if (INSN_P (x)) - x = PATTERN (x); + rtx x = PATTERN (insn); if (GET_CODE (x) == PARALLEL) x = XVECEXP (x, 0, 0); if (GET_CODE (x) == SET) -- cgit v1.1 From 031e8857886b91da290ffb03d9027424566e5da3 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 10 Sep 2019 18:56:21 +0000 Subject: Move c6x REGNO_REG_CLASS out of line I have a series of patches that hides call_used_regs from target- independent code, a knock-on effect of which is that (public) target macros can't use call_used_regs either. This patch fixes the only case in which that was a problem. 2019-09-10 Richard Sandiford gcc/ * config/c6x/c6x-protos.h (c6x_set_return_address): Declare. * config/c6x/c6x.h (REGNO_REG_CLASS): Move implementation to * config/c6x/c6x.c (c6x_regno_reg_class): ...this new function. From-SVN: r275597 --- gcc/ChangeLog | 6 ++++++ gcc/config/c6x/c6x-protos.h | 2 ++ gcc/config/c6x/c6x.c | 22 ++++++++++++++++++++++ gcc/config/c6x/c6x.h | 7 +------ 4 files changed, 31 insertions(+), 6 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0ec847c..56f99f0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2019-09-10 Richard Sandiford + * config/c6x/c6x-protos.h (c6x_set_return_address): Declare. + * config/c6x/c6x.h (REGNO_REG_CLASS): Move implementation to + * config/c6x/c6x.c (c6x_regno_reg_class): ...this new function. + +2019-09-10 Richard Sandiford + * rtl.h (get_call_rtx_from): Take a const rtx_insn * instead of an rtx. * rtlanal.c (get_call_rtx_from): Likewise. * dwarf2out.c (dwarf2out_var_location): Pass the insn rather diff --git a/gcc/config/c6x/c6x-protos.h b/gcc/config/c6x/c6x-protos.h index 8c04c31..b2043cb 100644 --- a/gcc/config/c6x/c6x-protos.h +++ b/gcc/config/c6x/c6x-protos.h @@ -53,6 +53,8 @@ extern void c6x_expand_epilogue (bool); extern rtx c6x_return_addr_rtx (int); extern void c6x_set_return_address (rtx, rtx); + +enum reg_class c6x_regno_reg_class (int); #endif extern void c6x_override_options (void); diff --git a/gcc/config/c6x/c6x.c b/gcc/config/c6x/c6x.c index f6a4518..852373b 100644 --- a/gcc/config/c6x/c6x.c +++ b/gcc/config/c6x/c6x.c @@ -6677,6 +6677,28 @@ c6x_modes_tieable_p (machine_mode mode1, machine_mode mode2) && GET_MODE_SIZE (mode2) <= UNITS_PER_WORD)); } +/* Implement REGNO_REG_CLASS. */ + +enum reg_class +c6x_regno_reg_class (int reg) +{ + if (reg >= REG_A1 && reg <= REG_A2) + return PREDICATE_A_REGS; + + if (reg == REG_A0 && TARGET_INSNS_64) + return PREDICATE_A_REGS; + + if (reg >= REG_B0 && reg <= REG_B2) + return PREDICATE_B_REGS; + + if (A_REGNO_P (reg)) + return NONPREDICATE_A_REGS; + + if (call_used_regs[reg]) + return CALL_USED_B_REGS; + + return B_REGS; +} /* Target Structure. */ diff --git a/gcc/config/c6x/c6x.h b/gcc/config/c6x/c6x.h index c605b73..e93a544 100644 --- a/gcc/config/c6x/c6x.h +++ b/gcc/config/c6x/c6x.h @@ -259,12 +259,7 @@ enum reg_class #define CROSS_OPERANDS(X0,X1) \ (A_REG_P (X0) == A_REG_P (X1) ? CROSS_N : CROSS_Y) -#define REGNO_REG_CLASS(reg) \ - ((reg) >= REG_A1 && (reg) <= REG_A2 ? PREDICATE_A_REGS \ - : (reg) == REG_A0 && TARGET_INSNS_64 ? PREDICATE_A_REGS \ - : (reg) >= REG_B0 && (reg) <= REG_B2 ? PREDICATE_B_REGS \ - : A_REGNO_P (reg) ? NONPREDICATE_A_REGS \ - : call_used_regs[reg] ? CALL_USED_B_REGS : B_REGS) +#define REGNO_REG_CLASS(reg) c6x_regno_reg_class (reg) #define BASE_REG_CLASS ALL_REGS #define INDEX_REG_CLASS ALL_REGS -- cgit v1.1 From df1f0eef67939274e9ddd3df426e8dfc5184086b Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 10 Sep 2019 18:56:26 +0000 Subject: Remove call_fixed_reg_set On targets that use reload, call_fixed_reg_set is structurally: fixed_reg_set -- reginfo.c | (call_used_reg_set & ~have_save_mode) -- first loop in init_caller_save | ~have_save_insn -- final loop in init_caller_save (where "have_save_mode" and "have_save_insn" are just my names). But the final loop in init_caller_save does: for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) for (j = 1; j <= MOVE_MAX_WORDS; j++) if (reg_save_code (i,regno_save_mode[i][j]) == -1) This last condition ought to be true whenever: regno_save_mode[i][j] == VOIDmode since either targetm.hard_regno_mode_ok (i, VOIDmode) should be false or the VOIDmode save & restore shouldn't match any move insn. And after the first loop, regno_save_mode[i][j] == VOIDmode whenever !call_used_regs[i]. So the above is actually: fixed_reg_set | (call_used_reg_set & ~have_save_mode) | (~call_used_reg_set | ~have_save_insn) which simplifies to: fixed_reg_set -- reginfo.c | ~have_save_mode -- first loop in init_caller_save | ~have_save_insn -- final loop in init_caller_save | ~call_used_reg_set -- final loop in init_caller_save So: ~call_fixed_reg_set == (~fixed_reg_set & have_save_mode & have_save_insn & call_used_reg_set) [A] All users have the form: (call_used_reg_set or some subset) & ~(call_fixed_reg_set | ...) i.e.: (call_used_reg_set or some subset) & ~call_fixed_reg_set & ~(...) We can therefore drop the "& call_used_reg_set" from [A], leaving: ~fixed_reg_set & have_save_mode & have_save_insn This patch combines have_save_mode & have_save_insn into a single condition "a save is possible", represented as savable_regs. We can then substitute: ~call_fixed_reg_set --> ~fixed_reg_set & savable_regs (registers we can actually save around calls) The patch also sets regno_save_mode[i][j] for all registers, in case non-default ABIs require a save when the default ABI doesn't. This ensures that savable_regs (like fixed_reg_set but unlike call_fixed_reg_set) isn't affected by the ABI. This only becomes significant with later patches and at this point is just a simplification. Since init_caller_save is only called for reload targets, the default assumption for LRA is that all registers are savable, just like the default assumption before the patch was that (~)call_fixed_reg_set == (~)fixed_reg_set. 2019-09-10 Richard Sandiford gcc/ * hard-reg-set.h (target_hard_regs::x_call_fixed_reg_set): Delete. (target_hard_regs::x_savable_regs): New field. (call_fixed_reg_set): Delete. (savable_regs): New macro, * reginfo.c (globalize_reg): Don't set call_fixed_reg_set. (init_reg_sets_1): Likewise. Initialize savable_regs. * caller-save.c (init_caller_save): Invoke HARD_REGNO_CALLER_SAVE_MODE for all registers. Set savable_regs instead of call_fixed_reg_set. (setup_save_areas, save_call_clobbered_regs): Replace uses of ~call_fixed_reg_set with ~fixed_reg_set & savable_regs. * config/sh/sh.c (output_stack_adjust): Likewise. From-SVN: r275598 --- gcc/ChangeLog | 14 ++++++++++++++ gcc/caller-save.c | 36 +++++++++++++----------------------- gcc/config/sh/sh.c | 4 +++- gcc/hard-reg-set.h | 18 +++++++++++------- gcc/reginfo.c | 5 +---- 5 files changed, 42 insertions(+), 35 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 56f99f0..aee3190 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,19 @@ 2019-09-10 Richard Sandiford + * hard-reg-set.h (target_hard_regs::x_call_fixed_reg_set): Delete. + (target_hard_regs::x_savable_regs): New field. + (call_fixed_reg_set): Delete. + (savable_regs): New macro, + * reginfo.c (globalize_reg): Don't set call_fixed_reg_set. + (init_reg_sets_1): Likewise. Initialize savable_regs. + * caller-save.c (init_caller_save): Invoke HARD_REGNO_CALLER_SAVE_MODE + for all registers. Set savable_regs instead of call_fixed_reg_set. + (setup_save_areas, save_call_clobbered_regs): Replace uses of + ~call_fixed_reg_set with ~fixed_reg_set & savable_regs. + * config/sh/sh.c (output_stack_adjust): Likewise. + +2019-09-10 Richard Sandiford + * config/c6x/c6x-protos.h (c6x_set_return_address): Declare. * config/c6x/c6x.h (REGNO_REG_CLASS): Move implementation to * config/c6x/c6x.c (c6x_regno_reg_class): ...this new function. diff --git a/gcc/caller-save.c b/gcc/caller-save.c index 8c88af9..05fbc44 100644 --- a/gcc/caller-save.c +++ b/gcc/caller-save.c @@ -198,23 +198,12 @@ init_caller_save (void) we can't have the register live over calls. */ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - { - if (call_used_regs[i] - && !TEST_HARD_REG_BIT (call_fixed_reg_set, i)) - { - for (j = 1; j <= MOVE_MAX_WORDS; j++) - { - regno_save_mode[i][j] = HARD_REGNO_CALLER_SAVE_MODE (i, j, - VOIDmode); - if (regno_save_mode[i][j] == VOIDmode && j == 1) - { - SET_HARD_REG_BIT (call_fixed_reg_set, i); - } - } - } - else - regno_save_mode[i][1] = VOIDmode; - } + for (j = 1; j <= MOVE_MAX_WORDS; j++) + { + regno_save_mode[i][j] = HARD_REGNO_CALLER_SAVE_MODE (i, j, VOIDmode); + if (regno_save_mode[i][j] == VOIDmode && j == 1) + CLEAR_HARD_REG_BIT (savable_regs, i); + } /* The following code tries to approximate the conditions under which we can easily save and restore a register without scratch registers or @@ -276,7 +265,7 @@ init_caller_save (void) regno_save_mode[i][j] = VOIDmode; if (j == 1) { - SET_HARD_REG_BIT (call_fixed_reg_set, i); + CLEAR_HARD_REG_BIT (savable_regs, i); if (call_used_regs[i]) SET_HARD_REG_BIT (no_caller_save_reg_set, i); } @@ -455,8 +444,8 @@ setup_save_areas (void) if (SIBLING_CALL_P (insn) && crtl->return_rtx) mark_set_regs (crtl->return_rtx, NULL_RTX, &this_insn_sets); - used_regs &= ~(call_fixed_reg_set | this_insn_sets); - hard_regs_to_save &= used_regs; + used_regs &= ~(fixed_reg_set | this_insn_sets); + hard_regs_to_save &= used_regs & savable_regs; for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) if (TEST_HARD_REG_BIT (hard_regs_to_save, regno)) { @@ -539,8 +528,8 @@ setup_save_areas (void) if (SIBLING_CALL_P (insn) && crtl->return_rtx) mark_set_regs (crtl->return_rtx, NULL_RTX, &this_insn_sets); - used_regs &= ~(call_fixed_reg_set | this_insn_sets); - hard_regs_to_save &= used_regs; + used_regs &= ~(fixed_reg_set | this_insn_sets); + hard_regs_to_save &= used_regs & savable_regs; for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) if (TEST_HARD_REG_BIT (hard_regs_to_save, regno)) { @@ -850,9 +839,10 @@ save_call_clobbered_regs (void) note_stores (insn, mark_set_regs, &this_insn_sets); /* Compute which hard regs must be saved before this call. */ - hard_regs_to_save &= ~(call_fixed_reg_set + hard_regs_to_save &= ~(fixed_reg_set | this_insn_sets | hard_regs_saved); + hard_regs_to_save &= savable_regs; get_call_reg_set_usage (insn, &call_def_reg_set, call_used_reg_set); hard_regs_to_save &= call_def_reg_set; diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index b2fb56c..7f88180 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -6707,7 +6707,9 @@ output_stack_adjust (int size, rtx reg, int epilogue_p, temp = -1; if (temp < 0 && ! current_function_interrupt && epilogue_p >= 0) { - HARD_REG_SET temps = call_used_reg_set & ~call_fixed_reg_set; + HARD_REG_SET temps = (call_used_reg_set + & ~fixed_reg_set + & savable_regs); if (epilogue_p > 0) { int nreg = 0; diff --git a/gcc/hard-reg-set.h b/gcc/hard-reg-set.h index 274956e..4c8da3a 100644 --- a/gcc/hard-reg-set.h +++ b/gcc/hard-reg-set.h @@ -400,11 +400,15 @@ struct target_hard_regs { /* The same info as a HARD_REG_SET. */ HARD_REG_SET x_call_used_reg_set; - /* Contains registers that are fixed use -- i.e. in fixed_reg_set -- or - a function value return register or TARGET_STRUCT_VALUE_RTX or - STATIC_CHAIN_REGNUM. These are the registers that cannot hold quantities - across calls even if we are willing to save and restore them. */ - HARD_REG_SET x_call_fixed_reg_set; + /* For targets that use reload rather than LRA, this is the set + of registers that we are able to save and restore around calls + (i.e. those for which we know a suitable mode and set of + load/store instructions exist). For LRA targets it contains + all registers. + + This is legacy information and should be removed if all targets + switch to LRA. */ + HARD_REG_SET x_savable_regs; /* Contains registers that are fixed use -- i.e. in fixed_reg_set -- but only if they are not merely part of that set because they are global @@ -482,8 +486,8 @@ extern struct target_hard_regs *this_target_hard_regs; (this_target_hard_regs->x_call_really_used_regs) #define call_used_reg_set \ (this_target_hard_regs->x_call_used_reg_set) -#define call_fixed_reg_set \ - (this_target_hard_regs->x_call_fixed_reg_set) +#define savable_regs \ + (this_target_hard_regs->x_savable_regs) #define regs_invalidated_by_call \ (this_target_hard_regs->x_regs_invalidated_by_call) #define no_caller_save_reg_set \ diff --git a/gcc/reginfo.c b/gcc/reginfo.c index 48a3f66..b72a567 100644 --- a/gcc/reginfo.c +++ b/gcc/reginfo.c @@ -351,7 +351,6 @@ init_reg_sets_1 (void) CLEAR_HARD_REG_SET (fixed_reg_set); CLEAR_HARD_REG_SET (call_used_reg_set); - CLEAR_HARD_REG_SET (call_fixed_reg_set); CLEAR_HARD_REG_SET (regs_invalidated_by_call); operand_reg_set &= accessible_reg_set; @@ -417,7 +416,7 @@ init_reg_sets_1 (void) SET_HARD_REG_BIT (regs_invalidated_by_call, i); } - call_fixed_reg_set = fixed_reg_set; + SET_HARD_REG_SET (savable_regs); fixed_nonglobal_reg_set = fixed_reg_set; /* Preserve global registers if called more than once. */ @@ -428,7 +427,6 @@ init_reg_sets_1 (void) fixed_regs[i] = call_used_regs[i] = 1; SET_HARD_REG_BIT (fixed_reg_set, i); SET_HARD_REG_BIT (call_used_reg_set, i); - SET_HARD_REG_BIT (call_fixed_reg_set, i); } } @@ -782,7 +780,6 @@ globalize_reg (tree decl, int i) SET_HARD_REG_BIT (fixed_reg_set, i); SET_HARD_REG_BIT (call_used_reg_set, i); - SET_HARD_REG_BIT (call_fixed_reg_set, i); reinit_regs (); } -- cgit v1.1 From 026116ce2a4dedad81518b0ca89dd8243b545778 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 10 Sep 2019 18:56:31 +0000 Subject: Remove no_caller_save_reg_set Reusing the reasoning from the call_fixed_reg_set patch: for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) for (j = 1; j <= MOVE_MAX_WORDS; j++) if (reg_save_code (i,regno_save_mode[i][j]) == -1) should be true whenever regno_save_mode[i][j] == VOIDmode, which it is for: ~call_used_reg_set | ~have_save_mode So this condition amounts to: ~call_used_reg_set | ~have_save_mode | ~have_save_insn == ~call_used_reg_set | ~savable_regs no_caller_save_reg_set is then set if call_used_regs[i], so no_caller_save_reg_set is: call_used_reg_set & (~call_used_reg_set | ~savable_regs) == call_used_reg_set & ~savable_regs This patch expands its single user accordingly. Note that ~savable_regs is always empty on LRA targets. 2019-09-10 Richard Sandiford gcc/ * hard-reg-set.h (target_hard_regs::x_no_caller_save_reg_set): Delete. (no_caller_save_reg_set): Delete. * caller-save.c (init_caller_save): Don't initialize it. * ira-conflicts.c (ira_build_conflicts): Calculate no_caller_save_reg_set locally from call_used_reg_set and savable_regs. From-SVN: r275599 --- gcc/ChangeLog | 8 ++++++++ gcc/caller-save.c | 7 +------ gcc/hard-reg-set.h | 6 ------ gcc/ira-conflicts.c | 2 ++ 4 files changed, 11 insertions(+), 12 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index aee3190..7c6d9ea 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 2019-09-10 Richard Sandiford + * hard-reg-set.h (target_hard_regs::x_no_caller_save_reg_set): Delete. + (no_caller_save_reg_set): Delete. + * caller-save.c (init_caller_save): Don't initialize it. + * ira-conflicts.c (ira_build_conflicts): Calculate + no_caller_save_reg_set locally from call_used_reg_set and savable_regs. + +2019-09-10 Richard Sandiford + * hard-reg-set.h (target_hard_regs::x_call_fixed_reg_set): Delete. (target_hard_regs::x_savable_regs): New field. (call_fixed_reg_set): Delete. diff --git a/gcc/caller-save.c b/gcc/caller-save.c index 05fbc44..58ea14f 100644 --- a/gcc/caller-save.c +++ b/gcc/caller-save.c @@ -192,7 +192,6 @@ init_caller_save (void) caller_save_initialized_p = true; - CLEAR_HARD_REG_SET (no_caller_save_reg_set); /* First find all the registers that we need to deal with and all the modes that they can have. If we can't find a mode to use, we can't have the register live over calls. */ @@ -264,11 +263,7 @@ init_caller_save (void) { regno_save_mode[i][j] = VOIDmode; if (j == 1) - { - CLEAR_HARD_REG_BIT (savable_regs, i); - if (call_used_regs[i]) - SET_HARD_REG_BIT (no_caller_save_reg_set, i); - } + CLEAR_HARD_REG_BIT (savable_regs, i); } } diff --git a/gcc/hard-reg-set.h b/gcc/hard-reg-set.h index 4c8da3a..945e499 100644 --- a/gcc/hard-reg-set.h +++ b/gcc/hard-reg-set.h @@ -424,10 +424,6 @@ struct target_hard_regs { with the local stack frame are safe, but scant others. */ HARD_REG_SET x_regs_invalidated_by_call; - /* Call used hard registers which cannot be saved because there is no - insn for this. */ - HARD_REG_SET x_no_caller_save_reg_set; - /* Table of register numbers in the order in which to try to use them. */ int x_reg_alloc_order[FIRST_PSEUDO_REGISTER]; @@ -490,8 +486,6 @@ extern struct target_hard_regs *this_target_hard_regs; (this_target_hard_regs->x_savable_regs) #define regs_invalidated_by_call \ (this_target_hard_regs->x_regs_invalidated_by_call) -#define no_caller_save_reg_set \ - (this_target_hard_regs->x_no_caller_save_reg_set) #define reg_alloc_order \ (this_target_hard_regs->x_reg_alloc_order) #define inv_reg_alloc_order \ diff --git a/gcc/ira-conflicts.c b/gcc/ira-conflicts.c index ac8014a..430c6a6 100644 --- a/gcc/ira-conflicts.c +++ b/gcc/ira-conflicts.c @@ -765,6 +765,8 @@ ira_build_conflicts (void) } else if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0) { + HARD_REG_SET no_caller_save_reg_set + = (call_used_reg_set & ~savable_regs); OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= no_caller_save_reg_set; OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= temp_hard_reg_set; OBJECT_CONFLICT_HARD_REGS (obj) |= no_caller_save_reg_set; -- cgit v1.1 From a5647ae846f6765f12a359acba6a71fc12254fa8 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 10 Sep 2019 18:56:37 +0000 Subject: Replace call_used_reg_set with call_used_or_fixed_regs CALL_USED_REGISTERS and call_used_regs infamously contain all fixed registers (hence the need for CALL_REALLY_USED_REGISTERS etc.). We try to recover from this to some extent with: /* Contains 1 for registers that are set or clobbered by calls. */ /* ??? Ideally, this would be just call_used_regs plus global_regs, but for someone's bright idea to have call_used_regs strictly include fixed_regs. Which leaves us guessing as to the set of fixed_regs that are actually preserved. We know for sure that those associated with the local stack frame are safe, but scant others. */ HARD_REG_SET x_regs_invalidated_by_call; Since global registers are added to fixed_reg_set and call_used_reg_set too, it's always the case that: call_used_reg_set == regs_invalidated_by_call | fixed_reg_set This patch replaces all uses of call_used_reg_set with a new macro call_used_or_fixed_regs to make this clearer. This is part of a series that allows call_used_regs to be what is now call_really_used_regs. It's a purely mechanical replacement; later patches clean up obvious oddities like "call_used_or_fixed_regs & ~fixed_regs". 2019-09-10 Richard Sandiford gcc/ * hard-reg-set.h (target_hard_regs::x_call_used_reg_set): Delete. (call_used_reg_set): Delete. (call_used_or_fixed_regs): New macro. * reginfo.c (init_reg_sets_1, globalize_reg): Remove initialization of call_used_reg_set. * caller-save.c (setup_save_areas): Use call_used_or_fixed_regs instead of call_used_regs. (save_call_clobbered_regs): Likewise. * cfgcleanup.c (old_insns_match_p): Likewise. * config/c6x/c6x.c (c6x_call_saved_register_used): Likewise. * config/epiphany/epiphany.c (epiphany_conditional_register_usage): Likewise. * config/frv/frv.c (frv_ifcvt_modify_tests): Likewise. * config/sh/sh.c (output_stack_adjust): Likewise. * final.c (collect_fn_hard_reg_usage): Likewise. * ira-build.c (ira_build): Likewise. * ira-color.c (calculate_saved_nregs): Likewise. (allocno_reload_assign, calculate_spill_cost): Likewise. * ira-conflicts.c (ira_build_conflicts): Likewise. * ira-costs.c (ira_tune_allocno_costs): Likewise. * ira-lives.c (process_bb_node_lives): Likewise. * ira.c (setup_reg_renumber): Likewise. * lra-assigns.c (find_hard_regno_for_1, lra_assign): Likewise. * lra-constraints.c (need_for_call_save_p): Likewise. (need_for_split_p, inherit_in_ebb): Likewise. * lra-lives.c (process_bb_lives): Likewise. * lra-remat.c (call_used_input_regno_present_p): Likewise. * postreload.c (reload_combine): Likewise. * regrename.c (find_rename_reg): Likewise. * reload1.c (reload_as_needed): Likewise. * rtlanal.c (find_all_hard_reg_sets): Likewise. * sel-sched.c (mark_unavailable_hard_regs): Likewise. * shrink-wrap.c (requires_stack_frame_p): Likewise. From-SVN: r275600 --- gcc/ChangeLog | 36 ++++++++++++++++++++++++++++++++++++ gcc/caller-save.c | 9 +++++---- gcc/cfgcleanup.c | 4 ++-- gcc/config/c6x/c6x.c | 2 +- gcc/config/epiphany/epiphany.c | 2 +- gcc/config/frv/frv.c | 2 +- gcc/config/sh/sh.c | 2 +- gcc/final.c | 4 ++-- gcc/hard-reg-set.h | 7 ++----- gcc/ira-build.c | 2 +- gcc/ira-color.c | 8 ++++---- gcc/ira-conflicts.c | 10 +++++----- gcc/ira-costs.c | 2 +- gcc/ira-lives.c | 2 +- gcc/ira.c | 2 +- gcc/lra-assigns.c | 4 ++-- gcc/lra-constraints.c | 6 +++--- gcc/lra-lives.c | 4 ++-- gcc/lra-remat.c | 6 +++--- gcc/postreload.c | 2 +- gcc/reginfo.c | 6 ------ gcc/regrename.c | 2 +- gcc/reload1.c | 2 +- gcc/rtlanal.c | 2 +- gcc/sel-sched.c | 4 ++-- gcc/shrink-wrap.c | 2 +- 26 files changed, 81 insertions(+), 53 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7c6d9ea..403e8dd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,41 @@ 2019-09-10 Richard Sandiford + * hard-reg-set.h (target_hard_regs::x_call_used_reg_set): Delete. + (call_used_reg_set): Delete. + (call_used_or_fixed_regs): New macro. + * reginfo.c (init_reg_sets_1, globalize_reg): Remove initialization + of call_used_reg_set. + * caller-save.c (setup_save_areas): Use call_used_or_fixed_regs + instead of call_used_regs. + (save_call_clobbered_regs): Likewise. + * cfgcleanup.c (old_insns_match_p): Likewise. + * config/c6x/c6x.c (c6x_call_saved_register_used): Likewise. + * config/epiphany/epiphany.c (epiphany_conditional_register_usage): + Likewise. + * config/frv/frv.c (frv_ifcvt_modify_tests): Likewise. + * config/sh/sh.c (output_stack_adjust): Likewise. + * final.c (collect_fn_hard_reg_usage): Likewise. + * ira-build.c (ira_build): Likewise. + * ira-color.c (calculate_saved_nregs): Likewise. + (allocno_reload_assign, calculate_spill_cost): Likewise. + * ira-conflicts.c (ira_build_conflicts): Likewise. + * ira-costs.c (ira_tune_allocno_costs): Likewise. + * ira-lives.c (process_bb_node_lives): Likewise. + * ira.c (setup_reg_renumber): Likewise. + * lra-assigns.c (find_hard_regno_for_1, lra_assign): Likewise. + * lra-constraints.c (need_for_call_save_p): Likewise. + (need_for_split_p, inherit_in_ebb): Likewise. + * lra-lives.c (process_bb_lives): Likewise. + * lra-remat.c (call_used_input_regno_present_p): Likewise. + * postreload.c (reload_combine): Likewise. + * regrename.c (find_rename_reg): Likewise. + * reload1.c (reload_as_needed): Likewise. + * rtlanal.c (find_all_hard_reg_sets): Likewise. + * sel-sched.c (mark_unavailable_hard_regs): Likewise. + * shrink-wrap.c (requires_stack_frame_p): Likewise. + +2019-09-10 Richard Sandiford + * hard-reg-set.h (target_hard_regs::x_no_caller_save_reg_set): Delete. (no_caller_save_reg_set): Delete. * caller-save.c (init_caller_save): Don't initialize it. diff --git a/gcc/caller-save.c b/gcc/caller-save.c index 58ea14f..b63e568 100644 --- a/gcc/caller-save.c +++ b/gcc/caller-save.c @@ -426,7 +426,7 @@ setup_save_areas (void) freq = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn)); REG_SET_TO_HARD_REG_SET (hard_regs_to_save, &chain->live_throughout); - get_call_reg_set_usage (insn, &used_regs, call_used_reg_set); + get_call_reg_set_usage (insn, &used_regs, call_used_or_fixed_regs); /* Record all registers set in this call insn. These don't need to be saved. N.B. the call insn might set a subreg @@ -509,7 +509,7 @@ setup_save_areas (void) REG_SET_TO_HARD_REG_SET (hard_regs_to_save, &chain->live_throughout); - get_call_reg_set_usage (insn, &used_regs, call_used_reg_set); + get_call_reg_set_usage (insn, &used_regs, call_used_or_fixed_regs); /* Record all registers set in this call insn. These don't need to be saved. N.B. the call insn might set a subreg @@ -839,7 +839,7 @@ save_call_clobbered_regs (void) | hard_regs_saved); hard_regs_to_save &= savable_regs; get_call_reg_set_usage (insn, &call_def_reg_set, - call_used_reg_set); + call_used_or_fixed_regs); hard_regs_to_save &= call_def_reg_set; for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) @@ -855,7 +855,8 @@ save_call_clobbered_regs (void) if (cheap && HARD_REGISTER_P (cheap) - && TEST_HARD_REG_BIT (call_used_reg_set, REGNO (cheap))) + && TEST_HARD_REG_BIT (call_used_or_fixed_regs, + REGNO (cheap))) { rtx dest, newpat; rtx pat = PATTERN (insn); diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c index baa3809..17fa1de 100644 --- a/gcc/cfgcleanup.c +++ b/gcc/cfgcleanup.c @@ -1228,8 +1228,8 @@ old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx_insn *i1, rtx_insn *i2) HARD_REG_SET i1_used, i2_used; - get_call_reg_set_usage (i1, &i1_used, call_used_reg_set); - get_call_reg_set_usage (i2, &i2_used, call_used_reg_set); + get_call_reg_set_usage (i1, &i1_used, call_used_or_fixed_regs); + get_call_reg_set_usage (i2, &i2_used, call_used_or_fixed_regs); if (i1_used != i2_used) return dir_none; diff --git a/gcc/config/c6x/c6x.c b/gcc/config/c6x/c6x.c index 852373b..f7f0dbc 100644 --- a/gcc/config/c6x/c6x.c +++ b/gcc/config/c6x/c6x.c @@ -1094,7 +1094,7 @@ c6x_call_saved_register_used (tree call_expr) INIT_CUMULATIVE_ARGS (cum_v, NULL, NULL, 0, 0); cum = pack_cumulative_args (&cum_v); - call_saved_regset = ~call_used_reg_set; + call_saved_regset = ~call_used_or_fixed_regs; for (i = 0; i < call_expr_nargs (call_expr); i++) { parameter = CALL_EXPR_ARG (call_expr, i); diff --git a/gcc/config/epiphany/epiphany.c b/gcc/config/epiphany/epiphany.c index 41cd89e..d8b1cee 100644 --- a/gcc/config/epiphany/epiphany.c +++ b/gcc/config/epiphany/epiphany.c @@ -2242,7 +2242,7 @@ epiphany_conditional_register_usage (void) CLEAR_HARD_REG_SET (reg_class_contents[SHORT_INSN_REGS]); reg_class_contents[SIBCALL_REGS] = reg_class_contents[GENERAL_REGS]; /* It would be simpler and quicker if we could just use - &~, alas, call_used_reg_set is yet uninitialized; + &~, alas, call_used_or_fixed_regs is yet uninitialized; it is set up later by our caller. */ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (!call_used_regs[i]) diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c index 8a1f399..90c062b 100644 --- a/gcc/config/frv/frv.c +++ b/gcc/config/frv/frv.c @@ -5201,7 +5201,7 @@ frv_ifcvt_modify_tests (ce_if_block *ce_info, rtx *p_true, rtx *p_false) not fixed. However, allow the ICC/ICR temporary registers to be allocated if we did not need to use them in reloading other registers. */ memset (&tmp_reg->regs, 0, sizeof (tmp_reg->regs)); - tmp_reg->regs = call_used_reg_set &~ fixed_reg_set; + tmp_reg->regs = call_used_or_fixed_regs &~ fixed_reg_set; SET_HARD_REG_BIT (tmp_reg->regs, ICC_TEMP); SET_HARD_REG_BIT (tmp_reg->regs, ICR_TEMP); diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 7f88180..fd23fb0 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -6707,7 +6707,7 @@ output_stack_adjust (int size, rtx reg, int epilogue_p, temp = -1; if (temp < 0 && ! current_function_interrupt && epilogue_p >= 0) { - HARD_REG_SET temps = (call_used_reg_set + HARD_REG_SET temps = (call_used_or_fixed_regs & ~fixed_reg_set & savable_regs); if (epilogue_p > 0) diff --git a/gcc/final.c b/gcc/final.c index 6d91aa0..ae8ff22 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -5007,7 +5007,7 @@ collect_fn_hard_reg_usage (void) && !self_recursive_call_p (insn)) { if (!get_call_reg_set_usage (insn, &insn_used_regs, - call_used_reg_set)) + call_used_or_fixed_regs)) return; function_used_regs |= insn_used_regs; @@ -5030,7 +5030,7 @@ collect_fn_hard_reg_usage (void) /* The information we have gathered is only interesting if it exposes a register from the call_used_regs that is not used in this function. */ - if (hard_reg_set_subset_p (call_used_reg_set, function_used_regs)) + if (hard_reg_set_subset_p (call_used_or_fixed_regs, function_used_regs)) return; node = cgraph_node::rtl_info (current_function_decl); diff --git a/gcc/hard-reg-set.h b/gcc/hard-reg-set.h index 945e499..33ac640 100644 --- a/gcc/hard-reg-set.h +++ b/gcc/hard-reg-set.h @@ -397,9 +397,6 @@ struct target_hard_regs { char x_call_really_used_regs[FIRST_PSEUDO_REGISTER]; - /* The same info as a HARD_REG_SET. */ - HARD_REG_SET x_call_used_reg_set; - /* For targets that use reload rather than LRA, this is the set of registers that we are able to save and restore around calls (i.e. those for which we know a suitable mode and set of @@ -480,12 +477,12 @@ extern struct target_hard_regs *this_target_hard_regs; (this_target_hard_regs->x_call_used_regs) #define call_really_used_regs \ (this_target_hard_regs->x_call_really_used_regs) -#define call_used_reg_set \ - (this_target_hard_regs->x_call_used_reg_set) #define savable_regs \ (this_target_hard_regs->x_savable_regs) #define regs_invalidated_by_call \ (this_target_hard_regs->x_regs_invalidated_by_call) +#define call_used_or_fixed_regs \ + (regs_invalidated_by_call | fixed_reg_set) #define reg_alloc_order \ (this_target_hard_regs->x_reg_alloc_order) #define inv_reg_alloc_order \ diff --git a/gcc/ira-build.c b/gcc/ira-build.c index 834bea7..b5e6933 100644 --- a/gcc/ira-build.c +++ b/gcc/ira-build.c @@ -3462,7 +3462,7 @@ ira_build (void) allocno crossing calls. */ FOR_EACH_ALLOCNO (a, ai) if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0) - ior_hard_reg_conflicts (a, call_used_reg_set); + ior_hard_reg_conflicts (a, call_used_or_fixed_regs); } if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL) print_copies (ira_dump_file); diff --git a/gcc/ira-color.c b/gcc/ira-color.c index eee9e0b..505d5c8 100644 --- a/gcc/ira-color.c +++ b/gcc/ira-color.c @@ -1650,7 +1650,7 @@ calculate_saved_nregs (int hard_regno, machine_mode mode) ira_assert (hard_regno >= 0); for (i = hard_regno_nregs (hard_regno, mode) - 1; i >= 0; i--) if (!allocated_hardreg_p[hard_regno + i] - && !TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + i) + && !TEST_HARD_REG_BIT (call_used_or_fixed_regs, hard_regno + i) && !LOCAL_REGNO (hard_regno + i)) nregs++; return nregs; @@ -4379,7 +4379,7 @@ allocno_reload_assign (ira_allocno_t a, HARD_REG_SET forbidden_regs) saved[i] = OBJECT_TOTAL_CONFLICT_HARD_REGS (obj); OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= forbidden_regs; if (! flag_caller_saves && ALLOCNO_CALLS_CROSSED_NUM (a) != 0) - OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= call_used_reg_set; + OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= call_used_or_fixed_regs; } ALLOCNO_ASSIGNED_P (a) = false; aclass = ALLOCNO_CLASS (a); @@ -4400,7 +4400,7 @@ allocno_reload_assign (ira_allocno_t a, HARD_REG_SET forbidden_regs) [aclass][hard_regno]])); if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0 && ira_hard_reg_set_intersection_p (hard_regno, ALLOCNO_MODE (a), - call_used_reg_set)) + call_used_or_fixed_regs)) { ira_assert (flag_caller_saves); caller_save_needed = 1; @@ -4715,7 +4715,7 @@ calculate_spill_cost (int *regnos, rtx in, rtx out, rtx_insn *insn, cost += ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a); nregs = hard_regno_nregs (hard_regno, ALLOCNO_MODE (a)); for (j = 0; j < nregs; j++) - if (! TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + j)) + if (! TEST_HARD_REG_BIT (call_used_or_fixed_regs, hard_regno + j)) break; if (j == nregs) count++; diff --git a/gcc/ira-conflicts.c b/gcc/ira-conflicts.c index 430c6a6..afbc2ec 100644 --- a/gcc/ira-conflicts.c +++ b/gcc/ira-conflicts.c @@ -740,7 +740,7 @@ ira_build_conflicts (void) else temp_hard_reg_set = (reg_class_contents[base] & ~ira_no_alloc_regs - & call_used_reg_set); + & call_used_or_fixed_regs); FOR_EACH_ALLOCNO (a, ai) { int i, n = ALLOCNO_NUM_OBJECTS (a); @@ -760,13 +760,13 @@ ira_build_conflicts (void) && REG_USERVAR_P (allocno_reg) && ! reg_is_parm_p (allocno_reg))) { - OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= call_used_reg_set; - OBJECT_CONFLICT_HARD_REGS (obj) |= call_used_reg_set; + OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= call_used_or_fixed_regs; + OBJECT_CONFLICT_HARD_REGS (obj) |= call_used_or_fixed_regs; } else if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0) { HARD_REG_SET no_caller_save_reg_set - = (call_used_reg_set & ~savable_regs); + = (call_used_or_fixed_regs & ~savable_regs); OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= no_caller_save_reg_set; OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= temp_hard_reg_set; OBJECT_CONFLICT_HARD_REGS (obj) |= no_caller_save_reg_set; @@ -805,7 +805,7 @@ ira_build_conflicts (void) /* Allocnos bigger than the saved part of call saved regs must conflict with them. */ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) - if (!TEST_HARD_REG_BIT (call_used_reg_set, regno) + if (!TEST_HARD_REG_BIT (call_used_or_fixed_regs, regno) && targetm.hard_regno_call_part_clobbered (NULL, regno, obj_mode)) { diff --git a/gcc/ira-costs.c b/gcc/ira-costs.c index 5d672ac..aefec08 100644 --- a/gcc/ira-costs.c +++ b/gcc/ira-costs.c @@ -2380,7 +2380,7 @@ ira_tune_allocno_costs (void) if (ira_hard_reg_set_intersection_p (regno, mode, *crossed_calls_clobber_regs) && (ira_hard_reg_set_intersection_p (regno, mode, - call_used_reg_set) + call_used_or_fixed_regs) || targetm.hard_regno_call_part_clobbered (NULL, regno, mode))) cost += (ALLOCNO_CALL_FREQ (a) diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c index 6f4012f..eb7eb0f 100644 --- a/gcc/ira-lives.c +++ b/gcc/ira-lives.c @@ -1257,7 +1257,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) HARD_REG_SET this_call_used_reg_set; get_call_reg_set_usage (insn, &this_call_used_reg_set, - call_used_reg_set); + call_used_or_fixed_regs); /* Don't allocate allocnos that cross setjmps or any call, if this function receives a nonlocal diff --git a/gcc/ira.c b/gcc/ira.c index 029d690..b44647f 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -2370,7 +2370,7 @@ setup_reg_renumber (void) } if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0 && ira_hard_reg_set_intersection_p (hard_regno, ALLOCNO_MODE (a), - call_used_reg_set)) + call_used_or_fixed_regs)) { ira_assert (!optimize || flag_caller_saves || (ALLOCNO_CALLS_CROSSED_NUM (a) diff --git a/gcc/lra-assigns.c b/gcc/lra-assigns.c index 0a34ea9..014fb496 100644 --- a/gcc/lra-assigns.c +++ b/gcc/lra-assigns.c @@ -654,7 +654,7 @@ find_hard_regno_for_1 (int regno, int *cost, int try_only_hard_regno, for (j = 0; j < hard_regno_nregs (hard_regno, PSEUDO_REGNO_MODE (regno)); j++) - if (! TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + j) + if (! TEST_HARD_REG_BIT (call_used_or_fixed_regs, hard_regno + j) && ! df_regs_ever_live_p (hard_regno + j)) /* It needs save restore. */ hard_regno_costs[hard_regno] @@ -1641,7 +1641,7 @@ lra_assign (bool &fails_p) for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++) if (lra_reg_info[i].nrefs != 0 && reg_renumber[i] >= 0 && lra_reg_info[i].call_insn - && overlaps_hard_reg_set_p (call_used_reg_set, + && overlaps_hard_reg_set_p (call_used_or_fixed_regs, PSEUDO_REGNO_MODE (i), reg_renumber[i])) gcc_unreachable (); /* Setup insns to process on the next constraint pass. */ diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index 16d96c5..a60bc6c 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -5439,7 +5439,7 @@ need_for_call_save_p (int regno) ((flag_ipa_ra && ! hard_reg_set_empty_p (lra_reg_info[regno].actual_call_used_reg_set)) ? lra_reg_info[regno].actual_call_used_reg_set - : call_used_reg_set, + : call_used_or_fixed_regs, PSEUDO_REGNO_MODE (regno), reg_renumber[regno]) || (targetm.hard_regno_call_part_clobbered (lra_reg_info[regno].call_insn, @@ -5483,7 +5483,7 @@ need_for_split_p (HARD_REG_SET potential_reload_hard_regs, int regno) true) the assign pass assumes that all pseudos living through calls are assigned to call saved hard regs. */ && (regno >= FIRST_PSEUDO_REGISTER - || ! TEST_HARD_REG_BIT (call_used_reg_set, regno) + || ! TEST_HARD_REG_BIT (call_used_or_fixed_regs, regno) || usage_insns[regno].calls_num == calls_num) /* We need at least 2 reloads to make pseudo splitting profitable. We should provide hard regno splitting in @@ -6458,7 +6458,7 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail) /* If there are pending saves/restores, the optimization is not worth. */ && usage_insns[regno].calls_num == calls_num - 1 - && TEST_HARD_REG_BIT (call_used_reg_set, hard_regno)) + && TEST_HARD_REG_BIT (call_used_or_fixed_regs, hard_regno)) { /* Restore the pseudo from the call result as REG_RETURNED note says that the pseudo value is diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c index 0bdba39..e509cc3 100644 --- a/gcc/lra-lives.c +++ b/gcc/lra-lives.c @@ -928,12 +928,12 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) { call_insn = curr_insn; if (! flag_ipa_ra && ! targetm.return_call_with_max_clobbers) - last_call_used_reg_set = call_used_reg_set; + last_call_used_reg_set = call_used_or_fixed_regs; else { HARD_REG_SET this_call_used_reg_set; get_call_reg_set_usage (curr_insn, &this_call_used_reg_set, - call_used_reg_set); + call_used_or_fixed_regs); bool flush = (! hard_reg_set_empty_p (last_call_used_reg_set) && (last_call_used_reg_set diff --git a/gcc/lra-remat.c b/gcc/lra-remat.c index ef2a552..18c0a6a 100644 --- a/gcc/lra-remat.c +++ b/gcc/lra-remat.c @@ -69,9 +69,9 @@ along with GCC; see the file COPYING3. If not see /* Number of candidates for rematerialization. */ static unsigned int cands_num; -/* The following is used for representation of call_used_reg_set in +/* The following is used for representation of call_used_or_fixed_regs in form array whose elements are hard register numbers with nonzero bit - in CALL_USED_REG_SET. */ + in CALL_USED_OR_FIXED_REGS. */ static int call_used_regs_arr_len; static int call_used_regs_arr[FIRST_PSEUDO_REGISTER]; @@ -710,7 +710,7 @@ call_used_input_regno_present_p (rtx_insn *insn) reg != NULL; reg = reg->next) if (reg->type == OP_IN && reg->regno < FIRST_PSEUDO_REGISTER - && TEST_HARD_REG_BIT (call_used_reg_set, reg->regno)) + && TEST_HARD_REG_BIT (call_used_or_fixed_regs, reg->regno)) return true; return false; } diff --git a/gcc/postreload.c b/gcc/postreload.c index 3f2dac3..af64def 100644 --- a/gcc/postreload.c +++ b/gcc/postreload.c @@ -1332,7 +1332,7 @@ reload_combine (void) rtx link; HARD_REG_SET used_regs; - get_call_reg_set_usage (insn, &used_regs, call_used_reg_set); + get_call_reg_set_usage (insn, &used_regs, call_used_or_fixed_regs); for (r = 0; r < FIRST_PSEUDO_REGISTER; r++) if (TEST_HARD_REG_BIT (used_regs, r)) diff --git a/gcc/reginfo.c b/gcc/reginfo.c index b72a567..026a7bf 100644 --- a/gcc/reginfo.c +++ b/gcc/reginfo.c @@ -350,7 +350,6 @@ init_reg_sets_1 (void) /* Initialize "constant" tables. */ CLEAR_HARD_REG_SET (fixed_reg_set); - CLEAR_HARD_REG_SET (call_used_reg_set); CLEAR_HARD_REG_SET (regs_invalidated_by_call); operand_reg_set &= accessible_reg_set; @@ -384,9 +383,6 @@ init_reg_sets_1 (void) if (fixed_regs[i]) SET_HARD_REG_BIT (fixed_reg_set, i); - if (call_used_regs[i]) - SET_HARD_REG_BIT (call_used_reg_set, i); - /* There are a couple of fixed registers that we know are safe to exclude from being clobbered by calls: @@ -426,7 +422,6 @@ init_reg_sets_1 (void) { fixed_regs[i] = call_used_regs[i] = 1; SET_HARD_REG_BIT (fixed_reg_set, i); - SET_HARD_REG_BIT (call_used_reg_set, i); } } @@ -779,7 +774,6 @@ globalize_reg (tree decl, int i) #endif SET_HARD_REG_BIT (fixed_reg_set, i); - SET_HARD_REG_BIT (call_used_reg_set, i); reinit_regs (); } diff --git a/gcc/regrename.c b/gcc/regrename.c index d83e1e9..47d8224 100644 --- a/gcc/regrename.c +++ b/gcc/regrename.c @@ -367,7 +367,7 @@ find_rename_reg (du_head_p this_head, enum reg_class super_class, If the chain needs a call-saved register, mark the call-used registers as unavailable. */ if (this_head->need_caller_save_reg) - *unavailable |= call_used_reg_set; + *unavailable |= call_used_or_fixed_regs; /* Mark registers that overlap this chain's lifetime as unavailable. */ merge_overlapping_regs (unavailable, this_head); diff --git a/gcc/reload1.c b/gcc/reload1.c index 3c23e6e..8234e1e 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -4784,7 +4784,7 @@ reload_as_needed (int live_known) be partially clobbered by the call. */ else if (CALL_P (insn)) { - reg_reloaded_valid &= ~(call_used_reg_set + reg_reloaded_valid &= ~(call_used_or_fixed_regs | reg_reloaded_call_part_clobbered); /* If this is a call to a setjmp-type function, we must not diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index dfc6fe2..1fbbeda 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -1477,7 +1477,7 @@ find_all_hard_reg_sets (const rtx_insn *insn, HARD_REG_SET *pset, bool implicit) CLEAR_HARD_REG_SET (*pset); note_stores (insn, record_hard_reg_sets, pset); if (CALL_P (insn) && implicit) - *pset |= call_used_reg_set; + *pset |= call_used_or_fixed_regs; for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) if (REG_NOTE_KIND (link) == REG_INC) record_hard_reg_sets (XEXP (link, 0), NULL, pset); diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c index 9447b92..e515b1b 100644 --- a/gcc/sel-sched.c +++ b/gcc/sel-sched.c @@ -1224,10 +1224,10 @@ mark_unavailable_hard_regs (def_t def, struct reg_rename *reg_rename_p, reg_rename_p->unavailable_hard_regs |= sel_hrd.stack_regs; #endif - /* If there's a call on this path, make regs from call_used_reg_set + /* If there's a call on this path, make regs from call_used_or_fixed_regs unavailable. */ if (def->crosses_call) - reg_rename_p->unavailable_hard_regs |= call_used_reg_set; + reg_rename_p->unavailable_hard_regs |= call_used_or_fixed_regs; /* Stop here before reload: we need FRAME_REGS, STACK_REGS, and crosses_call, but not register classes. */ diff --git a/gcc/shrink-wrap.c b/gcc/shrink-wrap.c index f1af1cb..0186966 100644 --- a/gcc/shrink-wrap.c +++ b/gcc/shrink-wrap.c @@ -76,7 +76,7 @@ requires_stack_frame_p (rtx_insn *insn, HARD_REG_SET prologue_used, } if (hard_reg_set_intersect_p (hardregs, prologue_used)) return true; - hardregs &= ~call_used_reg_set; + hardregs &= ~call_used_or_fixed_regs; for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) if (TEST_HARD_REG_BIT (hardregs, regno) && df_regs_ever_live_p (regno)) -- cgit v1.1 From ff18ad15259c8978f85344934b146ff7b9ee07e1 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 10 Sep 2019 18:56:43 +0000 Subject: Make more use of regs_invalidated_by_call This cleans up a couple of places in which the previous patch had: call_used_or_fixed_regs & ~fixed_reg_set In that context, regs_invalidated_by_call is IMO more obvious. 2019-09-10 Richard Sandiford gcc/ * config/frv/frv.c (frv_ifcvt_modify_tests): Use regs_invalidated_by_call & ~fixed_reg_set instead of call_used_or_fixed_regs & ~fixed_reg_set. * config/sh/sh.c (output_stack_adjust): Likewise. From-SVN: r275601 --- gcc/ChangeLog | 7 +++++++ gcc/config/frv/frv.c | 2 +- gcc/config/sh/sh.c | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 403e8dd..33f34c3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,12 @@ 2019-09-10 Richard Sandiford + * config/frv/frv.c (frv_ifcvt_modify_tests): Use + regs_invalidated_by_call & ~fixed_reg_set instead of + call_used_or_fixed_regs & ~fixed_reg_set. + * config/sh/sh.c (output_stack_adjust): Likewise. + +2019-09-10 Richard Sandiford + * hard-reg-set.h (target_hard_regs::x_call_used_reg_set): Delete. (call_used_reg_set): Delete. (call_used_or_fixed_regs): New macro. diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c index 90c062b..936c532 100644 --- a/gcc/config/frv/frv.c +++ b/gcc/config/frv/frv.c @@ -5201,7 +5201,7 @@ frv_ifcvt_modify_tests (ce_if_block *ce_info, rtx *p_true, rtx *p_false) not fixed. However, allow the ICC/ICR temporary registers to be allocated if we did not need to use them in reloading other registers. */ memset (&tmp_reg->regs, 0, sizeof (tmp_reg->regs)); - tmp_reg->regs = call_used_or_fixed_regs &~ fixed_reg_set; + tmp_reg->regs = regs_invalidated_by_call & ~fixed_reg_set; SET_HARD_REG_BIT (tmp_reg->regs, ICC_TEMP); SET_HARD_REG_BIT (tmp_reg->regs, ICR_TEMP); diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index fd23fb0..ab3a78f 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -6707,7 +6707,7 @@ output_stack_adjust (int size, rtx reg, int epilogue_p, temp = -1; if (temp < 0 && ! current_function_interrupt && epilogue_p >= 0) { - HARD_REG_SET temps = (call_used_or_fixed_regs + HARD_REG_SET temps = (regs_invalidated_by_call & ~fixed_reg_set & savable_regs); if (epilogue_p > 0) -- cgit v1.1 From a365fa0636886aeda83e57b84d837cfba13597fe Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 10 Sep 2019 18:56:51 +0000 Subject: Add call_used_or_fixed_reg_p Similarly to the call_used_or_fixed_regs patch, this one replaces tests of call_used_regs[i] with call_used_or_fixed_reg_p (i). The only remaining direct uses of call_used_regs are in reginfo.c and in the conditional register usage hooks. Again, this is purely mechanical. A later patch will clear up the oddities in config/ code. 2019-09-10 Richard Sandiford gcc/ * hard-reg-set.h (call_used_or_fixed_reg_p): New macro. * cfgloopanal.c (init_set_costs): Use call_used_or_fixed_reg_p instead of testing call_used_regs directly. * config/aarch64/aarch64.c (aarch64_layout_frame): Likewise. (aarch64_components_for_bb): Likewise. * config/alpha/alpha.c (alpha_compute_frame_layout): Likewise. * config/arc/arc.c (arc_must_save_register): Likewise. (arc_epilogue_uses): Likewise. * config/arm/arm.c (arm_option_override, use_return_insn): Likewise. (legitimize_pic_address, callee_saved_reg_p): Likewise. (arm_compute_save_reg0_reg12_mask): Likewise. (arm_compute_save_core_reg_mask): Likewise. (arm_get_vfp_saved_size, arm_compute_frame_layout): Likewise. (arm_save_coproc_regs, thumb1_extra_regs_pushed): Likewise. (cmse_nonsecure_entry_clear_before_return): Likewise. (thumb1_expand_epilogue, arm_expand_epilogue_apcs_frame): Likewise. (arm_expand_epilogue): Likewise. * config/avr/avr.c (avr_regs_to_save, sequent_regs_live): Likewise. (avr_function_arg_advance, avr_find_unused_d_reg): Likewise. (_reg_unused_after): Likewise. * config/bfin/bfin.c (must_save_p, expand_prologue_reg_save): Likewise. (expand_epilogue_reg_restore, n_regs_saved_by_prologue): Likewise. (add_to_reg, hwloop_optimize): Likewise. * config/bpf/bpf.c (bpf_compute_frame_layout, bpf_expand_prologue) (bpf_expand_epilogue): Likewise. * config/c6x/c6x.c (c6x_save_reg, c6x_regno_reg_class): Likewise. * config/cr16/cr16.c (cr16_compute_save_regs): Likewise. * config/cris/cris.c (cris_reg_saved_in_regsave_area): Likewise. * config/epiphany/epiphany.c (epiphany_init_reg_tables): Likewise. (epiphany_compute_function_type, MUST_SAVE_REGISTER): Likewise. (epiphany_output_mi_thunk, epiphany_start_function): Likewise. * config/fr30/fr30.c (fr30_num_arg_regs): Likewise. * config/frv/frv.c (frv_stack_info): Likewise. * config/ft32/ft32.c (ft32_compute_frame): Likewise. (ft32_expand_prologue, ft32_expand_epilogue): Likewise. * config/gcn/gcn.c (gcn_compute_frame_offsets): Likewise. (move_callee_saved_registers): Likewise. * config/h8300/h8300.c (byte_reg): Likewise. * config/i386/i386-options.c (ix86_set_current_function): Likewise. * config/i386/i386.c (ix86_save_reg, ix86_expand_prologue): Likewise. (ix86_expand_epilogue, x86_order_regs_for_local_alloc): Likewise. * config/i386/predicates.md (sibcall_memory_operand): Likewise. * config/ia64/ia64.c (emit_safe_across_calls, find_gr_spill): Likewise. (next_scratch_gr_reg, ia64_compute_frame_size): Likewise. * config/iq2000/iq2000.h (MUST_SAVE_REGISTER): Likewise. * config/lm32/lm32.c (lm32_compute_frame_size): Likewise. * config/m32c/m32c.c (need_to_save): Likewise. * config/m68k/m68k.c (m68k_save_reg): Likewise. * config/mcore/mcore.c (calc_live_regs): Likewise. * config/microblaze/microblaze.c (microblaze_must_save_register): Likewise. * config/mmix/mmix.c (mmix_local_regno): Likewise. (mmix_initial_elimination_offset, mmix_reorg): Likewise. (mmix_use_simple_return, mmix_expand_prologue): Likewise. (mmix_expand_epilogue): Likewise. * config/moxie/moxie.c (moxie_compute_frame): Likewise. (moxie_expand_prologue, moxie_expand_epilogue): Likewise. * config/msp430/msp430.c (msp430_preserve_reg_p): Likewise. * config/nds32/nds32.h (nds32_16bit_address_type): Likewise. (NDS32_REQUIRED_CALLEE_SAVED_P): Likewise. * config/nios2/nios2.c (prologue_saved_reg_p): Likewise. * config/or1k/or1k.c (callee_saved_regno_p): Likewise. * config/pa/pa.c (pa_expand_prologue, pa_expand_epilogue): Likewise. * config/pdp11/pdp11.c (pdp11_saved_regno): Likewise. * config/pru/pru.c (prologue_saved_reg_p): Likewise. * config/riscv/riscv.c (riscv_save_reg_p): Likewise. (riscv_epilogue_uses, riscv_hard_regno_mode_ok): Likewise. * config/rl78/rl78.c (need_to_save): Likewise. * config/rs6000/rs6000-logue.c (save_reg_p): Likewise. (rs6000_stack_info, generate_set_vrsave): Likewise. (rs6000_emit_prologue, rs6000_emit_epilogue): Likewise. * config/rs6000/rs6000.c (rs6000_debug_reg_print): Likewise. * config/rx/rx.c (rx_get_stack_layout): Likewise. * config/s390/s390.c (s390_call_saved_register_used): Likewise. * config/sh/sh.c (calc_live_regs, sh_output_mi_thunk): Likewise. * config/sparc/sparc.c (save_global_or_fp_reg_p): Likewise. (save_local_or_in_reg_p): Likewise. * config/stormy16/stormy16.c (REG_NEEDS_SAVE): Likewise. (xstormy16_epilogue_uses): Likewise. * config/tilegx/tilegx.c (need_to_save_reg): Likewise. * config/tilepro/tilepro.c (need_to_save_reg): Likewise. * config/v850/v850.c (compute_register_save_size): Likewise. * config/vax/vax.c (vax_expand_prologue): Likewise. * config/visium/visium.c (visium_save_reg_p): Likewise. * config/xtensa/xtensa.c (xtensa_call_save_reg): Likewise. * cselib.c (cselib_process_insn): Likewise. * df-scan.c (df_get_entry_block_def_set): Likewise. * function.c (aggregate_value_p): Likewise. * haifa-sched.c (alloc_global_sched_pressure_data): Likewise. * ira-lives.c (process_bb_node_lives): Likewise. * ira.c (do_reload): Likewise. * lra-lives.c (process_bb_lives): Likewise. * lra-remat.c (lra_remat): Likewise. * lra.c (lra): Likewise. * postreload.c (reload_combine_recognize_pattern): Likewise. (reload_cse_move2add): Likewise. * recog.c (peep2_find_free_register): Likewise. * regrename.c (check_new_reg_p): Likewise. * reload.c (find_equiv_reg): Likewise. * reload1.c (reload, find_reg): Likewise. * sel-sched.c (init_hard_regs_data): Likewise. From-SVN: r275602 --- gcc/ChangeLog | 104 +++++++++++++++++++++++++++++++++++++ gcc/cfgloopanal.c | 2 +- gcc/config/aarch64/aarch64.c | 6 +-- gcc/config/alpha/alpha.c | 4 +- gcc/config/arc/arc.c | 4 +- gcc/config/arm/arm.c | 48 +++++++++-------- gcc/config/avr/avr.c | 12 ++--- gcc/config/bfin/bfin.c | 18 +++---- gcc/config/bpf/bpf.c | 6 +-- gcc/config/c6x/c6x.c | 4 +- gcc/config/cr16/cr16.c | 5 +- gcc/config/cris/cris.c | 4 +- gcc/config/epiphany/epiphany.c | 12 ++--- gcc/config/fr30/fr30.c | 2 +- gcc/config/frv/frv.c | 3 +- gcc/config/ft32/ft32.c | 8 +-- gcc/config/gcn/gcn.c | 6 +-- gcc/config/h8300/h8300.c | 5 +- gcc/config/i386/i386-options.c | 2 +- gcc/config/i386/i386.c | 14 ++--- gcc/config/i386/predicates.md | 2 +- gcc/config/ia64/ia64.c | 20 +++---- gcc/config/iq2000/iq2000.h | 2 +- gcc/config/lm32/lm32.c | 2 +- gcc/config/m32c/m32c.c | 2 +- gcc/config/m68k/m68k.c | 4 +- gcc/config/mcore/mcore.c | 2 +- gcc/config/microblaze/microblaze.c | 2 +- gcc/config/mmix/mmix.c | 17 +++--- gcc/config/moxie/moxie.c | 8 +-- gcc/config/msp430/msp430.c | 2 +- gcc/config/nds32/nds32.h | 2 +- gcc/config/nios2/nios2.c | 2 +- gcc/config/or1k/or1k.c | 2 +- gcc/config/pa/pa.c | 8 +-- gcc/config/pdp11/pdp11.c | 2 +- gcc/config/pru/pru.c | 2 +- gcc/config/riscv/riscv.c | 11 ++-- gcc/config/rl78/rl78.c | 4 +- gcc/config/rs6000/rs6000-logue.c | 17 +++--- gcc/config/rs6000/rs6000.c | 2 +- gcc/config/rx/rx.c | 4 +- gcc/config/s390/s390.c | 4 +- gcc/config/sh/sh.c | 9 ++-- gcc/config/sparc/sparc.c | 4 +- gcc/config/stormy16/stormy16.c | 6 +-- gcc/config/tilegx/tilegx.c | 2 +- gcc/config/tilepro/tilepro.c | 2 +- gcc/config/v850/v850.c | 4 +- gcc/config/vax/vax.c | 2 +- gcc/config/visium/visium.c | 4 +- gcc/config/xtensa/xtensa.c | 2 +- gcc/cselib.c | 2 +- gcc/df-scan.c | 2 +- gcc/function.c | 2 +- gcc/haifa-sched.c | 2 +- gcc/hard-reg-set.h | 9 ++++ gcc/ira-lives.c | 2 +- gcc/ira.c | 4 +- gcc/lra-lives.c | 2 +- gcc/lra-remat.c | 2 +- gcc/lra.c | 2 +- gcc/postreload.c | 4 +- gcc/recog.c | 3 +- gcc/regrename.c | 2 +- gcc/reload.c | 4 +- gcc/reload1.c | 8 +-- gcc/sel-sched.c | 2 +- 68 files changed, 306 insertions(+), 173 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 33f34c3..099652b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,109 @@ 2019-09-10 Richard Sandiford + * hard-reg-set.h (call_used_or_fixed_reg_p): New macro. + * cfgloopanal.c (init_set_costs): Use call_used_or_fixed_reg_p + instead of testing call_used_regs directly. + * config/aarch64/aarch64.c (aarch64_layout_frame): Likewise. + (aarch64_components_for_bb): Likewise. + * config/alpha/alpha.c (alpha_compute_frame_layout): Likewise. + * config/arc/arc.c (arc_must_save_register): Likewise. + (arc_epilogue_uses): Likewise. + * config/arm/arm.c (arm_option_override, use_return_insn): Likewise. + (legitimize_pic_address, callee_saved_reg_p): Likewise. + (arm_compute_save_reg0_reg12_mask): Likewise. + (arm_compute_save_core_reg_mask): Likewise. + (arm_get_vfp_saved_size, arm_compute_frame_layout): Likewise. + (arm_save_coproc_regs, thumb1_extra_regs_pushed): Likewise. + (cmse_nonsecure_entry_clear_before_return): Likewise. + (thumb1_expand_epilogue, arm_expand_epilogue_apcs_frame): Likewise. + (arm_expand_epilogue): Likewise. + * config/avr/avr.c (avr_regs_to_save, sequent_regs_live): Likewise. + (avr_function_arg_advance, avr_find_unused_d_reg): Likewise. + (_reg_unused_after): Likewise. + * config/bfin/bfin.c (must_save_p, expand_prologue_reg_save): Likewise. + (expand_epilogue_reg_restore, n_regs_saved_by_prologue): Likewise. + (add_to_reg, hwloop_optimize): Likewise. + * config/bpf/bpf.c (bpf_compute_frame_layout, bpf_expand_prologue) + (bpf_expand_epilogue): Likewise. + * config/c6x/c6x.c (c6x_save_reg, c6x_regno_reg_class): Likewise. + * config/cr16/cr16.c (cr16_compute_save_regs): Likewise. + * config/cris/cris.c (cris_reg_saved_in_regsave_area): Likewise. + * config/epiphany/epiphany.c (epiphany_init_reg_tables): Likewise. + (epiphany_compute_function_type, MUST_SAVE_REGISTER): Likewise. + (epiphany_output_mi_thunk, epiphany_start_function): Likewise. + * config/fr30/fr30.c (fr30_num_arg_regs): Likewise. + * config/frv/frv.c (frv_stack_info): Likewise. + * config/ft32/ft32.c (ft32_compute_frame): Likewise. + (ft32_expand_prologue, ft32_expand_epilogue): Likewise. + * config/gcn/gcn.c (gcn_compute_frame_offsets): Likewise. + (move_callee_saved_registers): Likewise. + * config/h8300/h8300.c (byte_reg): Likewise. + * config/i386/i386-options.c (ix86_set_current_function): Likewise. + * config/i386/i386.c (ix86_save_reg, ix86_expand_prologue): Likewise. + (ix86_expand_epilogue, x86_order_regs_for_local_alloc): Likewise. + * config/i386/predicates.md (sibcall_memory_operand): Likewise. + * config/ia64/ia64.c (emit_safe_across_calls, find_gr_spill): Likewise. + (next_scratch_gr_reg, ia64_compute_frame_size): Likewise. + * config/iq2000/iq2000.h (MUST_SAVE_REGISTER): Likewise. + * config/lm32/lm32.c (lm32_compute_frame_size): Likewise. + * config/m32c/m32c.c (need_to_save): Likewise. + * config/m68k/m68k.c (m68k_save_reg): Likewise. + * config/mcore/mcore.c (calc_live_regs): Likewise. + * config/microblaze/microblaze.c (microblaze_must_save_register): + Likewise. + * config/mmix/mmix.c (mmix_local_regno): Likewise. + (mmix_initial_elimination_offset, mmix_reorg): Likewise. + (mmix_use_simple_return, mmix_expand_prologue): Likewise. + (mmix_expand_epilogue): Likewise. + * config/moxie/moxie.c (moxie_compute_frame): Likewise. + (moxie_expand_prologue, moxie_expand_epilogue): Likewise. + * config/msp430/msp430.c (msp430_preserve_reg_p): Likewise. + * config/nds32/nds32.h (nds32_16bit_address_type): Likewise. + (NDS32_REQUIRED_CALLEE_SAVED_P): Likewise. + * config/nios2/nios2.c (prologue_saved_reg_p): Likewise. + * config/or1k/or1k.c (callee_saved_regno_p): Likewise. + * config/pa/pa.c (pa_expand_prologue, pa_expand_epilogue): Likewise. + * config/pdp11/pdp11.c (pdp11_saved_regno): Likewise. + * config/pru/pru.c (prologue_saved_reg_p): Likewise. + * config/riscv/riscv.c (riscv_save_reg_p): Likewise. + (riscv_epilogue_uses, riscv_hard_regno_mode_ok): Likewise. + * config/rl78/rl78.c (need_to_save): Likewise. + * config/rs6000/rs6000-logue.c (save_reg_p): Likewise. + (rs6000_stack_info, generate_set_vrsave): Likewise. + (rs6000_emit_prologue, rs6000_emit_epilogue): Likewise. + * config/rs6000/rs6000.c (rs6000_debug_reg_print): Likewise. + * config/rx/rx.c (rx_get_stack_layout): Likewise. + * config/s390/s390.c (s390_call_saved_register_used): Likewise. + * config/sh/sh.c (calc_live_regs, sh_output_mi_thunk): Likewise. + * config/sparc/sparc.c (save_global_or_fp_reg_p): Likewise. + (save_local_or_in_reg_p): Likewise. + * config/stormy16/stormy16.c (REG_NEEDS_SAVE): Likewise. + (xstormy16_epilogue_uses): Likewise. + * config/tilegx/tilegx.c (need_to_save_reg): Likewise. + * config/tilepro/tilepro.c (need_to_save_reg): Likewise. + * config/v850/v850.c (compute_register_save_size): Likewise. + * config/vax/vax.c (vax_expand_prologue): Likewise. + * config/visium/visium.c (visium_save_reg_p): Likewise. + * config/xtensa/xtensa.c (xtensa_call_save_reg): Likewise. + * cselib.c (cselib_process_insn): Likewise. + * df-scan.c (df_get_entry_block_def_set): Likewise. + * function.c (aggregate_value_p): Likewise. + * haifa-sched.c (alloc_global_sched_pressure_data): Likewise. + * ira-lives.c (process_bb_node_lives): Likewise. + * ira.c (do_reload): Likewise. + * lra-lives.c (process_bb_lives): Likewise. + * lra-remat.c (lra_remat): Likewise. + * lra.c (lra): Likewise. + * postreload.c (reload_combine_recognize_pattern): Likewise. + (reload_cse_move2add): Likewise. + * recog.c (peep2_find_free_register): Likewise. + * regrename.c (check_new_reg_p): Likewise. + * reload.c (find_equiv_reg): Likewise. + * reload1.c (reload, find_reg): Likewise. + * sel-sched.c (init_hard_regs_data): Likewise. + +2019-09-10 Richard Sandiford + * config/frv/frv.c (frv_ifcvt_modify_tests): Use regs_invalidated_by_call & ~fixed_reg_set instead of call_used_or_fixed_regs & ~fixed_reg_set. diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c index 10037f0..0ebecc3 100644 --- a/gcc/cfgloopanal.c +++ b/gcc/cfgloopanal.c @@ -353,7 +353,7 @@ init_set_costs (void) && !fixed_regs[i]) { target_avail_regs++; - if (call_used_regs[i]) + if (call_used_or_fixed_reg_p (i)) target_clobbered_regs++; } diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 01b138d..ed04060 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -5336,12 +5336,12 @@ aarch64_layout_frame (void) for (regno = R0_REGNUM; regno <= R30_REGNUM; regno++) if (df_regs_ever_live_p (regno) && (regno == R30_REGNUM - || !call_used_regs[regno])) + || !call_used_or_fixed_reg_p (regno))) cfun->machine->frame.reg_offset[regno] = SLOT_REQUIRED; for (regno = V0_REGNUM; regno <= V31_REGNUM; regno++) if (df_regs_ever_live_p (regno) - && (!call_used_regs[regno] + && (!call_used_or_fixed_reg_p (regno) || (simd_function && FP_SIMD_SAVED_REGNUM_P (regno)))) { cfun->machine->frame.reg_offset[regno] = SLOT_REQUIRED; @@ -5938,7 +5938,7 @@ aarch64_components_for_bb (basic_block bb) /* GPRs are used in a bb if they are in the IN, GEN, or KILL sets. */ for (unsigned regno = 0; regno <= LAST_SAVED_REGNUM; regno++) - if ((!call_used_regs[regno] + if ((!call_used_or_fixed_reg_p (regno) || (simd_function && FP_SIMD_SAVED_REGNUM_P (regno))) && (bitmap_bit_p (in, regno) || bitmap_bit_p (gen, regno) diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index fd6b5a8..5c07b95 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -7225,7 +7225,7 @@ alpha_compute_frame_layout (void) /* One for every register we have to save. */ for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (! fixed_regs[i] && ! call_used_regs[i] + if (! fixed_regs[i] && ! call_used_or_fixed_reg_p (i) && df_regs_ever_live_p (i) && i != REG_RA) sa_mask |= HOST_WIDE_INT_1U << i; @@ -7285,7 +7285,7 @@ alpha_compute_frame_layout (void) vms_save_fp_regno = -1; if (vms_base_regno == HARD_FRAME_POINTER_REGNUM) for (unsigned i = 0; i < 32; i++) - if (! fixed_regs[i] && call_used_regs[i] + if (! fixed_regs[i] && call_used_or_fixed_reg_p (i) && ! df_regs_ever_live_p (i)) { vms_save_fp_regno = i; diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c index d603406..0b5d3fd 100644 --- a/gcc/config/arc/arc.c +++ b/gcc/config/arc/arc.c @@ -2735,7 +2735,7 @@ arc_must_save_register (int regno, struct function *func, bool special_p) break; } - if (((df_regs_ever_live_p (regno) && !call_used_regs[regno]) + if (((df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno)) /* In an interrupt save everything. */ || (ARC_INTERRUPT_P (fn_type) && (df_regs_ever_live_p (RETURN_ADDR_REGNUM) @@ -10331,7 +10331,7 @@ arc_epilogue_uses (int regno) if (epilogue_completed && ARC_INTERRUPT_P (fn_type)) { /* An interrupt function restores more registers. */ - if (df_regs_ever_live_p (regno) || call_used_regs[regno]) + if (df_regs_ever_live_p (regno) || call_used_or_fixed_reg_p (regno)) return true; } diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index c452771..db7de5e 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -3475,7 +3475,7 @@ arm_option_override (void) warning (0, "%<-mpic-register=%> is useless without %<-fpic%>"); /* Prevent the user from choosing an obviously stupid PIC register. */ - else if (pic_register < 0 || call_used_regs[pic_register] + else if (pic_register < 0 || call_used_or_fixed_reg_p (pic_register) || pic_register == HARD_FRAME_POINTER_REGNUM || pic_register == STACK_POINTER_REGNUM || pic_register >= PC_REGNUM @@ -4155,7 +4155,7 @@ use_return_insn (int iscond, rtx sibling) { /* Validate that r3 is a call-clobbered register (always true in the default abi) ... */ - if (!call_used_regs[3]) + if (!call_used_or_fixed_reg_p (3)) return 0; /* ... that it isn't being used for a return value ... */ @@ -4211,12 +4211,12 @@ use_return_insn (int iscond, rtx sibling) since this also requires an insn. */ if (TARGET_HARD_FLOAT) for (regno = FIRST_VFP_REGNUM; regno <= LAST_VFP_REGNUM; regno++) - if (df_regs_ever_live_p (regno) && !call_used_regs[regno]) + if (df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno)) return 0; if (TARGET_REALLY_IWMMXT) for (regno = FIRST_IWMMXT_REGNUM; regno <= LAST_IWMMXT_REGNUM; regno++) - if (df_regs_ever_live_p (regno) && ! call_used_regs[regno]) + if (df_regs_ever_live_p (regno) && ! call_used_or_fixed_reg_p (regno)) return 0; return 1; @@ -7735,7 +7735,7 @@ legitimize_pic_address (rtx orig, machine_mode mode, rtx reg, rtx pic_reg, registers are marked as caller saved when optimizing for size on Thumb-1 targets despite being callee saved in order to avoid using them. */ #define callee_saved_reg_p(reg) \ - (!call_used_regs[reg] \ + (!call_used_or_fixed_reg_p (reg) \ || (TARGET_THUMB1 && optimize_size \ && reg >= FIRST_HI_REGNUM && reg <= LAST_HI_REGNUM)) @@ -19721,7 +19721,7 @@ arm_compute_save_reg0_reg12_mask (void) for (reg = 0; reg <= max_reg; reg++) if (df_regs_ever_live_p (reg) - || (! crtl->is_leaf && call_used_regs[reg])) + || (! crtl->is_leaf && call_used_or_fixed_reg_p (reg))) save_reg_mask |= (1 << reg); /* Also save the pic base register if necessary. */ @@ -19900,7 +19900,7 @@ arm_compute_save_core_reg_mask (void) && (save_reg_mask & THUMB2_WORK_REGS) == 0) { reg = thumb_find_work_register (1 << 4); - if (!call_used_regs[reg]) + if (!call_used_or_fixed_reg_p (reg)) save_reg_mask |= (1 << reg); } @@ -20008,8 +20008,10 @@ arm_get_vfp_saved_size (void) regno < LAST_VFP_REGNUM; regno += 2) { - if ((!df_regs_ever_live_p (regno) || call_used_regs[regno]) - && (!df_regs_ever_live_p (regno + 1) || call_used_regs[regno + 1])) + if ((!df_regs_ever_live_p (regno) + || call_used_or_fixed_reg_p (regno)) + && (!df_regs_ever_live_p (regno + 1) + || call_used_or_fixed_reg_p (regno + 1))) { if (count > 0) { @@ -21530,7 +21532,8 @@ arm_compute_frame_layout (void) for (regno = FIRST_IWMMXT_REGNUM; regno <= LAST_IWMMXT_REGNUM; regno++) - if (df_regs_ever_live_p (regno) && ! call_used_regs[regno]) + if (df_regs_ever_live_p (regno) + && !call_used_or_fixed_reg_p (regno)) saved += 8; } @@ -21747,7 +21750,7 @@ arm_save_coproc_regs(void) rtx insn; for (reg = LAST_IWMMXT_REGNUM; reg >= FIRST_IWMMXT_REGNUM; reg--) - if (df_regs_ever_live_p (reg) && ! call_used_regs[reg]) + if (df_regs_ever_live_p (reg) && !call_used_or_fixed_reg_p (reg)) { insn = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx); insn = gen_rtx_MEM (V2SImode, insn); @@ -21762,8 +21765,9 @@ arm_save_coproc_regs(void) for (reg = FIRST_VFP_REGNUM; reg < LAST_VFP_REGNUM; reg += 2) { - if ((!df_regs_ever_live_p (reg) || call_used_regs[reg]) - && (!df_regs_ever_live_p (reg + 1) || call_used_regs[reg + 1])) + if ((!df_regs_ever_live_p (reg) || call_used_or_fixed_reg_p (reg)) + && (!df_regs_ever_live_p (reg + 1) + || call_used_or_fixed_reg_p (reg + 1))) { if (start_reg != reg) saved_size += vfp_emit_fstmd (start_reg, @@ -25137,7 +25141,7 @@ thumb1_extra_regs_pushed (arm_stack_offsets *offsets, bool for_prologue) } while (reg_base + n_free < 8 && !(live_regs_mask & 1) - && (for_prologue || call_used_regs[reg_base + n_free])) + && (for_prologue || call_used_or_fixed_reg_p (reg_base + n_free))) { live_regs_mask >>= 1; n_free++; @@ -25821,7 +25825,7 @@ cmse_nonsecure_entry_clear_before_return (void) continue; if (IN_RANGE (regno, IP_REGNUM, PC_REGNUM)) continue; - if (call_used_regs[regno]) + if (call_used_or_fixed_reg_p (regno)) bitmap_set_bit (to_clear_bitmap, regno); } @@ -25973,7 +25977,7 @@ thumb1_expand_epilogue (void) /* Emit a clobber for each insn that will be restored in the epilogue, so that flow2 will get register lifetimes correct. */ for (regno = 0; regno < 13; regno++) - if (df_regs_ever_live_p (regno) && !call_used_regs[regno]) + if (df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno)) emit_clobber (gen_rtx_REG (SImode, regno)); if (! df_regs_ever_live_p (LR_REGNUM)) @@ -26039,9 +26043,9 @@ arm_expand_epilogue_apcs_frame (bool really_return) for (i = FIRST_VFP_REGNUM; i < LAST_VFP_REGNUM; i += 2) /* Look for a case where a reg does not need restoring. */ - if ((!df_regs_ever_live_p (i) || call_used_regs[i]) + if ((!df_regs_ever_live_p (i) || call_used_or_fixed_reg_p (i)) && (!df_regs_ever_live_p (i + 1) - || call_used_regs[i + 1])) + || call_used_or_fixed_reg_p (i + 1))) { if (start_reg != i) arm_emit_vfp_multi_reg_pop (start_reg, @@ -26068,7 +26072,7 @@ arm_expand_epilogue_apcs_frame (bool really_return) int lrm_count = (num_regs % 2) ? (num_regs + 2) : (num_regs + 1); for (i = LAST_IWMMXT_REGNUM; i >= FIRST_IWMMXT_REGNUM; i--) - if (df_regs_ever_live_p (i) && !call_used_regs[i]) + if (df_regs_ever_live_p (i) && !call_used_or_fixed_reg_p (i)) { rtx addr = gen_frame_mem (V2SImode, plus_constant (Pmode, hard_frame_pointer_rtx, @@ -26273,9 +26277,9 @@ arm_expand_epilogue (bool really_return) unlike pop, vldm can only do consecutive regs. */ for (i = LAST_VFP_REGNUM - 1; i >= FIRST_VFP_REGNUM; i -= 2) /* Look for a case where a reg does not need restoring. */ - if ((!df_regs_ever_live_p (i) || call_used_regs[i]) + if ((!df_regs_ever_live_p (i) || call_used_or_fixed_reg_p (i)) && (!df_regs_ever_live_p (i + 1) - || call_used_regs[i + 1])) + || call_used_or_fixed_reg_p (i + 1))) { /* Restore the regs discovered so far (from reg+2 to end_reg). */ @@ -26297,7 +26301,7 @@ arm_expand_epilogue (bool really_return) if (TARGET_IWMMXT) for (i = FIRST_IWMMXT_REGNUM; i <= LAST_IWMMXT_REGNUM; i++) - if (df_regs_ever_live_p (i) && !call_used_regs[i]) + if (df_regs_ever_live_p (i) && !call_used_or_fixed_reg_p (i)) { rtx_insn *insn; rtx addr = gen_rtx_MEM (V2SImode, diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index 6a5271d..04fc00f 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -1183,9 +1183,9 @@ avr_regs_to_save (HARD_REG_SET *set) if (fixed_regs[reg]) continue; - if ((int_or_sig_p && !crtl->is_leaf && call_used_regs[reg]) + if ((int_or_sig_p && !crtl->is_leaf && call_used_or_fixed_reg_p (reg)) || (df_regs_ever_live_p (reg) - && (int_or_sig_p || !call_used_regs[reg]) + && (int_or_sig_p || !call_used_or_fixed_reg_p (reg)) /* Don't record frame pointer registers here. They are treated indivitually in prologue. */ && !(frame_pointer_needed @@ -1367,7 +1367,7 @@ sequent_regs_live (void) continue; } - if (!call_used_regs[reg]) + if (!call_used_or_fixed_reg_p (reg)) { if (df_regs_ever_live_p (reg)) { @@ -3421,7 +3421,7 @@ avr_function_arg_advance (cumulative_args_t cum_v, if (cum->regno >= 8 && cum->nregs >= 0 - && !call_used_regs[cum->regno]) + && !call_used_or_fixed_reg_p (cum->regno)) { /* FIXME: We ship info on failing tail-call in struct machine_function. This uses internals of calls.c:expand_call() and the way args_so_far @@ -3568,7 +3568,7 @@ avr_find_unused_d_reg (rtx_insn *insn, rtx exclude) && (TREE_THIS_VOLATILE (current_function_decl) || cfun->machine->is_OS_task || cfun->machine->is_OS_main - || (!isr_p && call_used_regs[regno]))) + || (!isr_p && call_used_or_fixed_reg_p (regno)))) { return reg; } @@ -9552,7 +9552,7 @@ _reg_unused_after (rtx_insn *insn, rtx reg) && REG_P (XEXP (XEXP (tem, 0), 0)) && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0))) return 0; - if (call_used_regs[REGNO (reg)]) + if (call_used_or_fixed_reg_p (REGNO (reg))) return 1; } diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c index 49f18b6..fbe4c10 100644 --- a/gcc/config/bfin/bfin.c +++ b/gcc/config/bfin/bfin.c @@ -235,13 +235,13 @@ must_save_p (bool is_inthandler, unsigned regno) return (is_eh_return_reg || (df_regs_ever_live_p (regno) && !fixed_regs[regno] - && (is_inthandler || !call_used_regs[regno]))); + && (is_inthandler || !call_used_or_fixed_reg_p (regno)))); } else if (P_REGNO_P (regno)) { return ((df_regs_ever_live_p (regno) && !fixed_regs[regno] - && (is_inthandler || !call_used_regs[regno])) + && (is_inthandler || !call_used_or_fixed_reg_p (regno))) || (is_inthandler && (ENABLE_WA_05000283 || ENABLE_WA_05000315) && regno == REG_P5) @@ -251,9 +251,9 @@ must_save_p (bool is_inthandler, unsigned regno) || (TARGET_ID_SHARED_LIBRARY && !crtl->is_leaf)))); } else - return ((is_inthandler || !call_used_regs[regno]) + return ((is_inthandler || !call_used_or_fixed_reg_p (regno)) && (df_regs_ever_live_p (regno) - || (!leaf_function_p () && call_used_regs[regno]))); + || (!leaf_function_p () && call_used_or_fixed_reg_p (regno)))); } @@ -419,7 +419,7 @@ expand_prologue_reg_save (rtx spreg, int saveall, bool is_inthandler) if (saveall || (is_inthandler && (df_regs_ever_live_p (i) - || (!leaf_function_p () && call_used_regs[i])))) + || (!leaf_function_p () && call_used_or_fixed_reg_p (i))))) { rtx_insn *insn; if (i == REG_A0 || i == REG_A1) @@ -458,7 +458,7 @@ expand_epilogue_reg_restore (rtx spreg, bool saveall, bool is_inthandler) if (saveall || (is_inthandler && (df_regs_ever_live_p (i) - || (!leaf_function_p () && call_used_regs[i])))) + || (!leaf_function_p () && call_used_or_fixed_reg_p (i))))) { if (i == REG_A0 || i == REG_A1) { @@ -652,7 +652,7 @@ n_regs_saved_by_prologue (void) if (all || (fkind != SUBROUTINE && (df_regs_ever_live_p (i) - || (!leaf_function_p () && call_used_regs[i])))) + || (!leaf_function_p () && call_used_or_fixed_reg_p (i))))) n += i == REG_A0 || i == REG_A1 ? 2 : 1; return n; @@ -753,7 +753,7 @@ add_to_reg (rtx reg, HOST_WIDE_INT value, int frame, int epilogue_p) { int i; for (i = REG_P0; i <= REG_P5; i++) - if ((df_regs_ever_live_p (i) && ! call_used_regs[i]) + if ((df_regs_ever_live_p (i) && ! call_used_or_fixed_reg_p (i)) || (!TARGET_FDPIC && i == PIC_OFFSET_TABLE_REGNUM && (crtl->uses_pic_offset_table @@ -3482,7 +3482,7 @@ hwloop_optimize (hwloop_info loop) for (i = REG_P0; i <= REG_P5; i++) if ((df_regs_ever_live_p (i) || (funkind (TREE_TYPE (current_function_decl)) == SUBROUTINE - && call_used_regs[i])) + && call_used_or_fixed_reg_p (i))) && !REGNO_REG_SET_P (df_get_live_out (bb_in), i)) { scratchreg = gen_rtx_REG (SImode, i); diff --git a/gcc/config/bpf/bpf.c b/gcc/config/bpf/bpf.c index 8b2a592..6e57b00 100644 --- a/gcc/config/bpf/bpf.c +++ b/gcc/config/bpf/bpf.c @@ -273,7 +273,7 @@ bpf_compute_frame_layout (void) for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) if ((!fixed_regs[regno] && df_regs_ever_live_p (regno) - && !call_used_regs[regno]) + && !call_used_or_fixed_reg_p (regno)) || (cfun->calls_alloca && regno == STACK_POINTER_REGNUM)) cfun->machine->callee_saved_reg_size += 8; @@ -314,7 +314,7 @@ bpf_expand_prologue (void) { if ((!fixed_regs[regno] && df_regs_ever_live_p (regno) - && !call_used_regs[regno]) + && !call_used_or_fixed_reg_p (regno)) || (cfun->calls_alloca && regno == STACK_POINTER_REGNUM)) { @@ -374,7 +374,7 @@ bpf_expand_epilogue (void) { if ((!fixed_regs[regno] && df_regs_ever_live_p (regno) - && !call_used_regs[regno]) + && !call_used_or_fixed_reg_p (regno)) || (cfun->calls_alloca && regno == STACK_POINTER_REGNUM)) { diff --git a/gcc/config/c6x/c6x.c b/gcc/config/c6x/c6x.c index f7f0dbc..7d1c2f7 100644 --- a/gcc/config/c6x/c6x.c +++ b/gcc/config/c6x/c6x.c @@ -2532,7 +2532,7 @@ static int c6x_save_reg (unsigned int regno) { return ((df_regs_ever_live_p (regno) - && !call_used_regs[regno] + && !call_used_or_fixed_reg_p (regno) && !fixed_regs[regno]) || (regno == RETURN_ADDR_REGNO && (df_regs_ever_live_p (regno) @@ -6694,7 +6694,7 @@ c6x_regno_reg_class (int reg) if (A_REGNO_P (reg)) return NONPREDICATE_A_REGS; - if (call_used_regs[reg]) + if (call_used_or_fixed_reg_p (reg)) return CALL_USED_B_REGS; return B_REGS; diff --git a/gcc/config/cr16/cr16.c b/gcc/config/cr16/cr16.c index c95d5d1..aaac797 100644 --- a/gcc/config/cr16/cr16.c +++ b/gcc/config/cr16/cr16.c @@ -367,7 +367,7 @@ cr16_compute_save_regs (void) /* If this reg is used and not call-used (except RA), save it. */ if (cr16_interrupt_function_p ()) { - if (!crtl->is_leaf && call_used_regs[regno]) + if (!crtl->is_leaf && call_used_or_fixed_reg_p (regno)) /* This is a volatile reg in a non-leaf interrupt routine - save it for the sake of its sons. */ current_frame_info.save_regs[regno] = 1; @@ -382,7 +382,8 @@ cr16_compute_save_regs (void) { /* If this reg is used and not call-used (except RA), save it. */ if (df_regs_ever_live_p (regno) - && (!call_used_regs[regno] || regno == RETURN_ADDRESS_REGNUM)) + && (!call_used_or_fixed_reg_p (regno) + || regno == RETURN_ADDRESS_REGNUM)) current_frame_info.save_regs[regno] = 1; else current_frame_info.save_regs[regno] = 0; diff --git a/gcc/config/cris/cris.c b/gcc/config/cris/cris.c index fff641e9..9f9bc51 100644 --- a/gcc/config/cris/cris.c +++ b/gcc/config/cris/cris.c @@ -716,13 +716,13 @@ cris_reg_saved_in_regsave_area (unsigned int regno, bool got_really_used) { return (((df_regs_ever_live_p (regno) - && !call_used_regs[regno]) + && !call_used_or_fixed_reg_p (regno)) || (regno == PIC_OFFSET_TABLE_REGNUM && (got_really_used /* It is saved anyway, if there would be a gap. */ || (flag_pic && df_regs_ever_live_p (regno + 1) - && !call_used_regs[regno + 1])))) + && !call_used_or_fixed_reg_p (regno + 1))))) && (regno != FRAME_POINTER_REGNUM || !frame_pointer_needed) && regno != CRIS_SRP_REGNUM) || (crtl->calls_eh_return diff --git a/gcc/config/epiphany/epiphany.c b/gcc/config/epiphany/epiphany.c index d8b1cee..12cb4b4 100644 --- a/gcc/config/epiphany/epiphany.c +++ b/gcc/config/epiphany/epiphany.c @@ -434,7 +434,7 @@ epiphany_init_reg_tables (void) epiphany_regno_reg_class[i] = LR_REGS; else if (i <= 7 && TARGET_PREFER_SHORT_INSN_REGS) epiphany_regno_reg_class[i] = SHORT_INSN_REGS; - else if (call_used_regs[i] + else if (call_used_or_fixed_reg_p (i) && TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], i)) epiphany_regno_reg_class[i] = SIBCALL_REGS; else if (i >= CORE_CONTROL_FIRST && i <= CORE_CONTROL_LAST) @@ -1066,8 +1066,8 @@ epiphany_compute_function_type (tree decl) #define MUST_SAVE_REGISTER(regno, interrupt_p) \ ((df_regs_ever_live_p (regno) \ || (interrupt_p && !crtl->is_leaf \ - && call_used_regs[regno] && !fixed_regs[regno])) \ - && (!call_used_regs[regno] || regno == GPR_LR \ + && call_used_or_fixed_reg_p (regno) && !fixed_regs[regno])) \ + && (!call_used_or_fixed_reg_p (regno) || regno == GPR_LR \ || (interrupt_p && regno != GPR_SP))) #define MUST_SAVE_RETURN_ADDR 0 @@ -2892,8 +2892,8 @@ epiphany_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED, assemble_start_function (thunk, fnname); /* We use IP and R16 as a scratch registers. */ - gcc_assert (call_used_regs [GPR_IP]); - gcc_assert (call_used_regs [GPR_16]); + gcc_assert (call_used_or_fixed_reg_p (GPR_IP)); + gcc_assert (call_used_or_fixed_reg_p (GPR_16)); /* Add DELTA. When possible use a plain add, otherwise load it into a register first. */ @@ -2999,7 +2999,7 @@ epiphany_start_function (FILE *file, const char *name, tree decl) fputs ("\tstrd r0,[sp,-1]\n", file); else tmp = GPR_16; - gcc_assert (call_used_regs[tmp]); + gcc_assert (call_used_or_fixed_reg_p (tmp)); fprintf (file, "\tmov r%d,%%low(", tmp); assemble_name (file, dst_name); fprintf (file, ")\n" diff --git a/gcc/config/fr30/fr30.c b/gcc/config/fr30/fr30.c index 675198f..d765c4b 100644 --- a/gcc/config/fr30/fr30.c +++ b/gcc/config/fr30/fr30.c @@ -141,7 +141,7 @@ static int fr30_num_arg_regs (const function_arg_info &); ( (regno) != RETURN_POINTER_REGNUM \ && (regno) != FRAME_POINTER_REGNUM \ && df_regs_ever_live_p (regno) \ - && ! call_used_regs [regno] ) + && ! call_used_or_fixed_reg_p (regno)) #define MUST_SAVE_FRAME_POINTER (df_regs_ever_live_p (FRAME_POINTER_REGNUM) || frame_pointer_needed) #define MUST_SAVE_RETURN_POINTER (df_regs_ever_live_p (RETURN_POINTER_REGNUM) || crtl->profile) diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c index 936c532..223415e 100644 --- a/gcc/config/frv/frv.c +++ b/gcc/config/frv/frv.c @@ -1101,7 +1101,8 @@ frv_stack_info (void) default: for (regno = first; regno <= last; regno++) { - if ((df_regs_ever_live_p (regno) && !call_used_regs[regno]) + if ((df_regs_ever_live_p (regno) + && !call_used_or_fixed_reg_p (regno)) || (crtl->calls_eh_return && (regno >= FIRST_EH_REGNUM && regno <= LAST_EH_REGNUM)) || (!TARGET_FDPIC && flag_pic diff --git a/gcc/config/ft32/ft32.c b/gcc/config/ft32/ft32.c index e9eb4d4..3361df1 100644 --- a/gcc/config/ft32/ft32.c +++ b/gcc/config/ft32/ft32.c @@ -411,7 +411,7 @@ ft32_compute_frame (void) /* Save callee-saved registers. */ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) - if (df_regs_ever_live_p (regno) && (!call_used_regs[regno])) + if (df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno)) cfun->machine->callee_saved_reg_size += 4; cfun->machine->size_for_adjusting_sp = @@ -475,7 +475,7 @@ ft32_expand_prologue (void) { for (regno = FIRST_PSEUDO_REGISTER; regno-- > 0;) { - if (!fixed_regs[regno] && !call_used_regs[regno] + if (!fixed_regs[regno] && !call_used_or_fixed_reg_p (regno) && df_regs_ever_live_p (regno)) { rtx preg = gen_rtx_REG (Pmode, regno); @@ -489,7 +489,7 @@ ft32_expand_prologue (void) for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) { if (!fixed_regs[regno] && df_regs_ever_live_p (regno) - && !call_used_regs[regno]) + && !call_used_or_fixed_reg_p (regno)) { insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno))); RTX_FRAME_RELATED_P (insn) = 1; @@ -554,7 +554,7 @@ ft32_expand_epilogue (void) { for (regno = FIRST_PSEUDO_REGISTER; regno-- > 0;) { - if (!fixed_regs[regno] && !call_used_regs[regno] + if (!fixed_regs[regno] && !call_used_or_fixed_reg_p (regno) && df_regs_ever_live_p (regno)) { rtx preg = gen_rtx_REG (Pmode, regno); diff --git a/gcc/config/gcn/gcn.c b/gcc/config/gcn/gcn.c index 473f6ed..50ae8e1 100644 --- a/gcc/config/gcn/gcn.c +++ b/gcc/config/gcn/gcn.c @@ -2540,7 +2540,7 @@ gcn_compute_frame_offsets (void) offsets->callee_saves = offsets->lr_needs_saving ? 8 : 0; for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) - if ((df_regs_ever_live_p (regno) && !call_used_regs[regno]) + if ((df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno)) || ((regno & ~1) == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)) offsets->callee_saves += (VGPR_REGNO_P (regno) ? 256 : 4); @@ -2572,7 +2572,7 @@ move_callee_saved_registers (rtx sp, machine_function *offsets, /* Move scalars into two vector registers. */ for (regno = 0, saved_scalars = 0; regno < FIRST_VGPR_REG; regno++) - if ((df_regs_ever_live_p (regno) && !call_used_regs[regno]) + if ((df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno)) || ((regno & ~1) == LINK_REGNUM && offsets->lr_needs_saving) || ((regno & ~1) == HARD_FRAME_POINTER_REGNUM && offsets->need_frame_pointer)) @@ -2618,7 +2618,7 @@ move_callee_saved_registers (rtx sp, machine_function *offsets, /* Move vectors. */ for (regno = FIRST_VGPR_REG, offset = offsets->pretend_size; regno < FIRST_PSEUDO_REGISTER; regno++) - if ((df_regs_ever_live_p (regno) && !call_used_regs[regno]) + if ((df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno)) || (regno == VGPR_REGNO (6) && saved_scalars > 0) || (regno == VGPR_REGNO (7) && saved_scalars > 63)) { diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c index c51b32d..87529c3 100644 --- a/gcc/config/h8300/h8300.c +++ b/gcc/config/h8300/h8300.c @@ -485,7 +485,8 @@ byte_reg (rtx x, int b) && ! TREE_THIS_VOLATILE (current_function_decl) \ && (h8300_saveall_function_p (current_function_decl) \ /* Save any call saved register that was used. */ \ - || (df_regs_ever_live_p (regno) && !call_used_regs[regno]) \ + || (df_regs_ever_live_p (regno) \ + && !call_used_or_fixed_reg_p (regno)) \ /* Save the frame pointer if it was used. */ \ || (regno == HARD_FRAME_POINTER_REGNUM && df_regs_ever_live_p (regno)) \ /* Save any register used in an interrupt handler. */ \ @@ -494,7 +495,7 @@ byte_reg (rtx x, int b) /* Save call clobbered registers in non-leaf interrupt \ handlers. */ \ || (h8300_current_function_interrupt_function_p () \ - && call_used_regs[regno] \ + && call_used_or_fixed_reg_p (regno) \ && !crtl->is_leaf))) /* We use this to wrap all emitted insns in the prologue. */ diff --git a/gcc/config/i386/i386-options.c b/gcc/config/i386/i386-options.c index 703e44e..c148aa2 100644 --- a/gcc/config/i386/i386-options.c +++ b/gcc/config/i386/i386-options.c @@ -3076,7 +3076,7 @@ ix86_set_current_function (tree fndecl) Avoid expensive re-initialization of init_regs each time we switch function context. */ if (TARGET_64BIT - && (call_used_regs[SI_REG] + && (call_used_or_fixed_reg_p (SI_REG) == (cfun->machine->call_abi == MS_ABI))) reinit_regs (); /* Need to re-initialize init_regs if caller-saved registers are diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 5e68a87..7525b9d 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -5665,7 +5665,7 @@ ix86_save_reg (unsigned int regno, bool maybe_eh_return, bool ignore_outlined) return true; return (df_regs_ever_live_p (regno) - && !call_used_regs[regno] + && !call_used_or_fixed_reg_p (regno) && !fixed_regs[regno] && (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed)); } @@ -7837,7 +7837,7 @@ ix86_expand_prologue (void) "around by avoiding functions with aggregate return."); /* Only need to push parameter pointer reg if it is caller saved. */ - if (!call_used_regs[REGNO (crtl->drap_reg)]) + if (!call_used_or_fixed_reg_p (REGNO (crtl->drap_reg))) { /* Push arg pointer reg */ insn = emit_insn (gen_push (crtl->drap_reg)); @@ -8012,7 +8012,7 @@ ix86_expand_prologue (void) if (ix86_static_chain_on_stack) stack_size += UNITS_PER_WORD; - if (!call_used_regs[REGNO (crtl->drap_reg)]) + if (!call_used_or_fixed_reg_p (REGNO (crtl->drap_reg))) stack_size += UNITS_PER_WORD; /* This over-estimates by 1 minimal-stack-alignment-unit but @@ -8903,7 +8903,7 @@ ix86_expand_epilogue (int style) if (ix86_static_chain_on_stack) param_ptr_offset += UNITS_PER_WORD; - if (!call_used_regs[REGNO (crtl->drap_reg)]) + if (!call_used_or_fixed_reg_p (REGNO (crtl->drap_reg))) param_ptr_offset += UNITS_PER_WORD; insn = emit_insn (gen_rtx_SET @@ -8921,7 +8921,7 @@ ix86_expand_epilogue (int style) GEN_INT (param_ptr_offset))); RTX_FRAME_RELATED_P (insn) = 1; - if (!call_used_regs[REGNO (crtl->drap_reg)]) + if (!call_used_or_fixed_reg_p (REGNO (crtl->drap_reg))) ix86_emit_restore_reg_using_pop (crtl->drap_reg); } @@ -19643,12 +19643,12 @@ x86_order_regs_for_local_alloc (void) /* First allocate the local general purpose registers. */ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (GENERAL_REGNO_P (i) && call_used_regs[i]) + if (GENERAL_REGNO_P (i) && call_used_or_fixed_reg_p (i)) reg_alloc_order [pos++] = i; /* Global general purpose registers. */ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (GENERAL_REGNO_P (i) && !call_used_regs[i]) + if (GENERAL_REGNO_P (i) && !call_used_or_fixed_reg_p (i)) reg_alloc_order [pos++] = i; /* x87 registers come first in case we are doing FP math diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 5e8f671..72f8e7e 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -690,7 +690,7 @@ if (GET_CODE (op) == PLUS && REG_P (XEXP (op, 0))) { int regno = REGNO (XEXP (op, 0)); - if (!HARD_REGISTER_NUM_P (regno) || call_used_regs[regno]) + if (!HARD_REGISTER_NUM_P (regno) || call_used_or_fixed_reg_p (regno)) { op = XEXP (op, 1); if (GOT32_symbol_operand (op, VOIDmode)) diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index ca69656..ff2ad20 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -2523,11 +2523,12 @@ emit_safe_across_calls (void) out_state = 0; while (1) { - while (rs < 64 && call_used_regs[PR_REG (rs)]) + while (rs < 64 && call_used_or_fixed_reg_p (PR_REG (rs))) rs++; if (rs >= 64) break; - for (re = rs + 1; re < 64 && ! call_used_regs[PR_REG (re)]; re++) + for (re = rs + 1; + re < 64 && ! call_used_or_fixed_reg_p (PR_REG (re)); re++) continue; if (out_state == 0) { @@ -2593,7 +2594,7 @@ find_gr_spill (enum ia64_frame_regs r, int try_locals) { for (regno = GR_REG (1); regno <= GR_REG (31); regno++) if (! df_regs_ever_live_p (regno) - && call_used_regs[regno] + && call_used_or_fixed_reg_p (regno) && ! fixed_regs[regno] && ! global_regs[regno] && ((current_frame_info.gr_used_mask >> regno) & 1) == 0 @@ -2641,7 +2642,7 @@ next_scratch_gr_reg (void) for (i = 0; i < 32; ++i) { regno = (last_scratch_gr_reg + i + 1) & 31; - if (call_used_regs[regno] + if (call_used_or_fixed_reg_p (regno) && ! fixed_regs[regno] && ! global_regs[regno] && ((current_frame_info.gr_used_mask >> regno) & 1) == 0) @@ -2762,7 +2763,7 @@ ia64_compute_frame_size (HOST_WIDE_INT size) which will always wind up on the stack. */ for (regno = FR_REG (2); regno <= FR_REG (127); regno++) - if (df_regs_ever_live_p (regno) && ! call_used_regs[regno]) + if (df_regs_ever_live_p (regno) && ! call_used_or_fixed_reg_p (regno)) { SET_HARD_REG_BIT (mask, regno); spill_size += 16; @@ -2771,7 +2772,7 @@ ia64_compute_frame_size (HOST_WIDE_INT size) } for (regno = GR_REG (1); regno <= GR_REG (31); regno++) - if (df_regs_ever_live_p (regno) && ! call_used_regs[regno]) + if (df_regs_ever_live_p (regno) && ! call_used_or_fixed_reg_p (regno)) { SET_HARD_REG_BIT (mask, regno); spill_size += 8; @@ -2780,7 +2781,7 @@ ia64_compute_frame_size (HOST_WIDE_INT size) } for (regno = BR_REG (1); regno <= BR_REG (7); regno++) - if (df_regs_ever_live_p (regno) && ! call_used_regs[regno]) + if (df_regs_ever_live_p (regno) && ! call_used_or_fixed_reg_p (regno)) { SET_HARD_REG_BIT (mask, regno); spill_size += 8; @@ -2840,7 +2841,8 @@ ia64_compute_frame_size (HOST_WIDE_INT size) } else { - if (df_regs_ever_live_p (BR_REG (0)) && ! call_used_regs[BR_REG (0)]) + if (df_regs_ever_live_p (BR_REG (0)) + && ! call_used_or_fixed_reg_p (BR_REG (0))) { SET_HARD_REG_BIT (mask, BR_REG (0)); extra_spill_size += 8; @@ -2894,7 +2896,7 @@ ia64_compute_frame_size (HOST_WIDE_INT size) /* See if we need to store the predicate register block. */ for (regno = PR_REG (0); regno <= PR_REG (63); regno++) - if (df_regs_ever_live_p (regno) && ! call_used_regs[regno]) + if (df_regs_ever_live_p (regno) && ! call_used_or_fixed_reg_p (regno)) break; if (regno <= PR_REG (63)) { diff --git a/gcc/config/iq2000/iq2000.h b/gcc/config/iq2000/iq2000.h index 89efdaf..163a6d3 100644 --- a/gcc/config/iq2000/iq2000.h +++ b/gcc/config/iq2000/iq2000.h @@ -687,7 +687,7 @@ enum delay_type /* Tell prologue and epilogue if register REGNO should be saved / restored. */ #define MUST_SAVE_REGISTER(regno) \ - ((df_regs_ever_live_p (regno) && !call_used_regs[regno]) \ + ((df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno)) \ || (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed) \ || (regno == (GP_REG_FIRST + 31) && df_regs_ever_live_p (GP_REG_FIRST + 31))) diff --git a/gcc/config/lm32/lm32.c b/gcc/config/lm32/lm32.c index 267ff27..67706a4 100644 --- a/gcc/config/lm32/lm32.c +++ b/gcc/config/lm32/lm32.c @@ -457,7 +457,7 @@ lm32_compute_frame_size (int size) and calculate size required to store them in the stack. */ for (regno = 1; regno < SP_REGNUM; regno++) { - if (df_regs_ever_live_p (regno) && !call_used_regs[regno]) + if (df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno)) { reg_save_mask |= 1 << regno; callee_size += UNITS_PER_WORD; diff --git a/gcc/config/m32c/m32c.c b/gcc/config/m32c/m32c.c index b60044f..d8dc63e 100644 --- a/gcc/config/m32c/m32c.c +++ b/gcc/config/m32c/m32c.c @@ -1114,7 +1114,7 @@ need_to_save (int regno) )) return 1; if (df_regs_ever_live_p (regno) - && (!call_used_regs[regno] || cfun->machine->is_interrupt)) + && (!call_used_or_fixed_reg_p (regno) || cfun->machine->is_interrupt)) return 1; return 0; } diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c index fd69511..1030dfa 100644 --- a/gcc/config/m68k/m68k.c +++ b/gcc/config/m68k/m68k.c @@ -944,7 +944,7 @@ m68k_save_reg (unsigned int regno, bool interrupt_handler) if (df_regs_ever_live_p (regno)) return true; - if (!crtl->is_leaf && call_used_regs[regno]) + if (!crtl->is_leaf && call_used_or_fixed_reg_p (regno)) return true; } @@ -953,7 +953,7 @@ m68k_save_reg (unsigned int regno, bool interrupt_handler) return false; /* Otherwise save everything that isn't call-clobbered. */ - return !call_used_regs[regno]; + return !call_used_or_fixed_reg_p (regno); } /* Emit RTL for a MOVEM or FMOVEM instruction. BASE + OFFSET represents diff --git a/gcc/config/mcore/mcore.c b/gcc/config/mcore/mcore.c index b259da5..a419d42 100644 --- a/gcc/config/mcore/mcore.c +++ b/gcc/config/mcore/mcore.c @@ -316,7 +316,7 @@ calc_live_regs (int * count) for (reg = 0; reg < FIRST_PSEUDO_REGISTER; reg++) { - if (df_regs_ever_live_p (reg) && !call_used_regs[reg]) + if (df_regs_ever_live_p (reg) && !call_used_or_fixed_reg_p (reg)) { (*count)++; live_regs_mask |= (1 << reg); diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c index 3d0f593..6705168 100644 --- a/gcc/config/microblaze/microblaze.c +++ b/gcc/config/microblaze/microblaze.c @@ -2012,7 +2012,7 @@ microblaze_must_save_register (int regno) (regno == MB_ABI_PIC_ADDR_REGNUM) && df_regs_ever_live_p (regno)) return 1; - if (df_regs_ever_live_p (regno) && !call_used_regs[regno]) + if (df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno)) return 1; if (frame_pointer_needed && (regno == HARD_FRAME_POINTER_REGNUM)) diff --git a/gcc/config/mmix/mmix.c b/gcc/config/mmix/mmix.c index 8ebb829..b8d379d 100644 --- a/gcc/config/mmix/mmix.c +++ b/gcc/config/mmix/mmix.c @@ -464,7 +464,8 @@ mmix_opposite_regno (int regno, int incoming) int mmix_local_regno (int regno) { - return regno <= MMIX_LAST_STACK_REGISTER_REGNUM && !call_used_regs[regno]; + return (regno <= MMIX_LAST_STACK_REGISTER_REGNUM + && !call_used_or_fixed_reg_p (regno)); } /* TARGET_PREFERRED_RELOAD_CLASS. @@ -604,7 +605,7 @@ mmix_initial_elimination_offset (int fromreg, int toreg) for (regno = MMIX_FIRST_GLOBAL_REGNUM; regno <= 255; regno++) - if ((df_regs_ever_live_p (regno) && ! call_used_regs[regno]) + if ((df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno)) || IS_MMIX_EH_RETURN_DATA_REG (regno)) fp_sp_offset += 8; @@ -866,7 +867,7 @@ mmix_reorg (void) for (regno = MMIX_LAST_STACK_REGISTER_REGNUM; regno >= 0; regno--) - if ((df_regs_ever_live_p (regno) && !call_used_regs[regno]) + if ((df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno)) || (regno == MMIX_FRAME_POINTER_REGNUM && frame_pointer_needed)) break; @@ -1958,7 +1959,7 @@ mmix_use_simple_return (void) /* Note that we assume that the frame-pointer-register is one of these registers, in which case we don't count it here. */ if ((((regno != MMIX_FRAME_POINTER_REGNUM || !frame_pointer_needed) - && df_regs_ever_live_p (regno) && !call_used_regs[regno])) + && df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno))) || IS_MMIX_EH_RETURN_DATA_REG (regno)) return 0; @@ -1994,7 +1995,7 @@ mmix_expand_prologue (void) /* Note that we assume that the frame-pointer-register is one of these registers, in which case we don't count it here. */ if ((((regno != MMIX_FRAME_POINTER_REGNUM || !frame_pointer_needed) - && df_regs_ever_live_p (regno) && !call_used_regs[regno])) + && df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno))) || IS_MMIX_EH_RETURN_DATA_REG (regno)) stack_space_to_allocate += 8; @@ -2180,7 +2181,7 @@ mmix_expand_prologue (void) regno >= MMIX_FIRST_GLOBAL_REGNUM; regno--) if (((regno != MMIX_FRAME_POINTER_REGNUM || !frame_pointer_needed) - && df_regs_ever_live_p (regno) && ! call_used_regs[regno]) + && df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno)) || IS_MMIX_EH_RETURN_DATA_REG (regno)) { rtx insn; @@ -2233,7 +2234,7 @@ mmix_expand_epilogue (void) regno >= MMIX_FIRST_GLOBAL_REGNUM; regno--) if (((regno != MMIX_FRAME_POINTER_REGNUM || !frame_pointer_needed) - && df_regs_ever_live_p (regno) && !call_used_regs[regno]) + && df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno)) || IS_MMIX_EH_RETURN_DATA_REG (regno)) stack_space_to_deallocate += 8; @@ -2262,7 +2263,7 @@ mmix_expand_epilogue (void) regno <= 255; regno++) if (((regno != MMIX_FRAME_POINTER_REGNUM || !frame_pointer_needed) - && df_regs_ever_live_p (regno) && !call_used_regs[regno]) + && df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno)) || IS_MMIX_EH_RETURN_DATA_REG (regno)) { if (offset > 255) diff --git a/gcc/config/moxie/moxie.c b/gcc/config/moxie/moxie.c index d840463..aa5948e 100644 --- a/gcc/config/moxie/moxie.c +++ b/gcc/config/moxie/moxie.c @@ -264,7 +264,7 @@ moxie_compute_frame (void) /* Save callee-saved registers. */ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) - if (df_regs_ever_live_p (regno) && (! call_used_regs[regno])) + if (df_regs_ever_live_p (regno) && (! call_used_or_fixed_reg_p (regno))) cfun->machine->callee_saved_reg_size += 4; cfun->machine->size_for_adjusting_sp = @@ -288,7 +288,9 @@ moxie_expand_prologue (void) /* Save callee-saved registers. */ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) { - if (!fixed_regs[regno] && df_regs_ever_live_p (regno) && !call_used_regs[regno]) + if (!fixed_regs[regno] + && df_regs_ever_live_p (regno) + && !call_used_or_fixed_reg_p (regno)) { insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno))); RTX_FRAME_RELATED_P (insn) = 1; @@ -349,7 +351,7 @@ moxie_expand_epilogue (void) emit_insn (gen_addsi3 (reg, reg, hard_frame_pointer_rtx)); } for (regno = FIRST_PSEUDO_REGISTER; regno-- > 0; ) - if (!fixed_regs[regno] && !call_used_regs[regno] + if (!fixed_regs[regno] && !call_used_or_fixed_reg_p (regno) && df_regs_ever_live_p (regno)) { rtx preg = gen_rtx_REG (Pmode, regno); diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c index 521d9ba..6430823 100644 --- a/gcc/config/msp430/msp430.c +++ b/gcc/config/msp430/msp430.c @@ -1152,7 +1152,7 @@ msp430_preserve_reg_p (int regno) return true; } - if (!call_used_regs[regno] + if (!call_used_or_fixed_reg_p (regno) && df_regs_ever_live_p (regno)) return true; diff --git a/gcc/config/nds32/nds32.h b/gcc/config/nds32/nds32.h index 6e62258..64cc455 100644 --- a/gcc/config/nds32/nds32.h +++ b/gcc/config/nds32/nds32.h @@ -226,7 +226,7 @@ enum nds32_16bit_address_type As long as the register satisfies both criteria above, it is required to be saved. */ #define NDS32_REQUIRED_CALLEE_SAVED_P(regno) \ - ((!call_used_regs[regno]) && (df_regs_ever_live_p (regno))) + (!call_used_or_fixed_reg_p (regno) && df_regs_ever_live_p (regno)) /* This macro is to check if the push25/pop25 are available to be used for code generation. Because pop25 also performs return behavior, diff --git a/gcc/config/nios2/nios2.c b/gcc/config/nios2/nios2.c index 6167803..4cea0f4 100644 --- a/gcc/config/nios2/nios2.c +++ b/gcc/config/nios2/nios2.c @@ -1080,7 +1080,7 @@ prologue_saved_reg_p (unsigned regno) { gcc_assert (GP_REG_P (regno)); - if (df_regs_ever_live_p (regno) && !call_used_regs[regno]) + if (df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno)) return true; if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed) diff --git a/gcc/config/or1k/or1k.c b/gcc/config/or1k/or1k.c index 34b9d6f..eff83b9 100644 --- a/gcc/config/or1k/or1k.c +++ b/gcc/config/or1k/or1k.c @@ -100,7 +100,7 @@ static bool callee_saved_regno_p (int regno) { /* Check call-saved registers. */ - if (!call_used_regs[regno] && df_regs_ever_live_p (regno)) + if (!call_used_or_fixed_reg_p (regno) && df_regs_ever_live_p (regno)) return true; switch (regno) diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 9366b106..80a0ea0 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -4053,7 +4053,7 @@ pa_expand_prologue (void) } for (i = 18; i >= 4; i--) - if (df_regs_ever_live_p (i) && ! call_used_regs[i]) + if (df_regs_ever_live_p (i) && !call_used_or_fixed_reg_p (i)) { store_reg (i, offset, HARD_FRAME_POINTER_REGNUM); offset += UNITS_PER_WORD; @@ -4093,7 +4093,7 @@ pa_expand_prologue (void) } for (i = 18; i >= 3; i--) - if (df_regs_ever_live_p (i) && ! call_used_regs[i]) + if (df_regs_ever_live_p (i) && !call_used_or_fixed_reg_p (i)) { /* If merge_sp_adjust_with_store is nonzero, then we can optimize the first GR save. */ @@ -4394,7 +4394,7 @@ pa_expand_epilogue (void) } for (i = 18; i >= 4; i--) - if (df_regs_ever_live_p (i) && ! call_used_regs[i]) + if (df_regs_ever_live_p (i) && !call_used_or_fixed_reg_p (i)) { load_reg (i, offset, HARD_FRAME_POINTER_REGNUM); offset += UNITS_PER_WORD; @@ -4431,7 +4431,7 @@ pa_expand_epilogue (void) for (i = 18; i >= 3; i--) { - if (df_regs_ever_live_p (i) && ! call_used_regs[i]) + if (df_regs_ever_live_p (i) && !call_used_or_fixed_reg_p (i)) { /* Only for the first load. merge_sp_adjust_with_load holds the register load diff --git a/gcc/config/pdp11/pdp11.c b/gcc/config/pdp11/pdp11.c index 2d3b94b..d7c6809 100644 --- a/gcc/config/pdp11/pdp11.c +++ b/gcc/config/pdp11/pdp11.c @@ -313,7 +313,7 @@ static bool pdp11_scalar_mode_supported_p (scalar_mode); static inline bool pdp11_saved_regno (unsigned regno) { - return !call_used_regs[regno] && df_regs_ever_live_p (regno); + return !call_used_or_fixed_reg_p (regno) && df_regs_ever_live_p (regno); } /* Expand the function prologue. */ diff --git a/gcc/config/pru/pru.c b/gcc/config/pru/pru.c index 579d3d4..416399e 100644 --- a/gcc/config/pru/pru.c +++ b/gcc/config/pru/pru.c @@ -443,7 +443,7 @@ prologue_saved_reg_p (int regno) { gcc_assert (GP_REG_P (regno)); - if (df_regs_ever_live_p (regno) && !call_used_regs[regno]) + if (df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno)) return true; /* 32-bit FP. */ diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c index 9b16a1e..39bf87a 100644 --- a/gcc/config/riscv/riscv.c +++ b/gcc/config/riscv/riscv.c @@ -3442,7 +3442,7 @@ riscv_frame_set (rtx mem, rtx reg) static bool riscv_save_reg_p (unsigned int regno) { - bool call_saved = !global_regs[regno] && !call_used_regs[regno]; + bool call_saved = !global_regs[regno] && !call_used_or_fixed_reg_p (regno); bool might_clobber = crtl->saves_all_registers || df_regs_ever_live_p (regno); @@ -3473,7 +3473,7 @@ riscv_save_reg_p (unsigned int regno) /* We must save every register used in this function. If this is not a leaf function, then we must save all temporary registers. */ if (df_regs_ever_live_p (regno) - || (!crtl->is_leaf && call_used_regs[regno])) + || (!crtl->is_leaf && call_used_or_fixed_reg_p (regno))) return true; } @@ -4198,7 +4198,7 @@ riscv_epilogue_uses (unsigned int regno) /* An interrupt function restores temp regs, so we must indicate that they are live at function end. */ if (df_regs_ever_live_p (regno) - || (!crtl->is_leaf && call_used_regs[regno])) + || (!crtl->is_leaf && call_used_or_fixed_reg_p (regno))) return true; } @@ -4361,7 +4361,7 @@ riscv_hard_regno_mode_ok (unsigned int regno, machine_mode mode) /* Only use callee-saved registers if a potential callee is guaranteed to spill the requisite width. */ if (GET_MODE_UNIT_SIZE (mode) > UNITS_PER_FP_REG - || (!call_used_regs[regno] + || (!call_used_or_fixed_reg_p (regno) && GET_MODE_UNIT_SIZE (mode) > UNITS_PER_FP_ARG)) return false; } @@ -4370,7 +4370,8 @@ riscv_hard_regno_mode_ok (unsigned int regno, machine_mode mode) /* Require same callee-savedness for all registers. */ for (unsigned i = 1; i < nregs; i++) - if (call_used_regs[regno] != call_used_regs[regno + i]) + if (call_used_or_fixed_reg_p (regno) + != call_used_or_fixed_reg_p (regno + i)) return false; return true; diff --git a/gcc/config/rl78/rl78.c b/gcc/config/rl78/rl78.c index 1c5d1e1..f132b47 100644 --- a/gcc/config/rl78/rl78.c +++ b/gcc/config/rl78/rl78.c @@ -723,7 +723,7 @@ need_to_save (unsigned int regno) any call_used registers, so we have to preserve them. We do not have to worry about the frame pointer register though, as that is handled below. */ - if (!crtl->is_leaf && call_used_regs[regno] && regno < 22) + if (!crtl->is_leaf && call_used_or_fixed_reg_p (regno) && regno < 22) return true; /* Otherwise we only have to save a register, call_used @@ -739,7 +739,7 @@ need_to_save (unsigned int regno) if (crtl->calls_eh_return) return true; if (df_regs_ever_live_p (regno) - && !call_used_regs[regno]) + && !call_used_or_fixed_reg_p (regno)) return true; return false; } diff --git a/gcc/config/rs6000/rs6000-logue.c b/gcc/config/rs6000/rs6000-logue.c index ebfe533..633a253 100644 --- a/gcc/config/rs6000/rs6000-logue.c +++ b/gcc/config/rs6000/rs6000-logue.c @@ -117,7 +117,7 @@ save_reg_p (int reg) return true; } - return !call_used_regs[reg] && df_regs_ever_live_p (reg); + return !call_used_or_fixed_reg_p (reg) && df_regs_ever_live_p (reg); } /* Return the first fixed-point register that is required to be @@ -875,7 +875,7 @@ rs6000_stack_info (void) using_static_chain_p = (cfun->static_chain_decl != NULL_TREE && df_regs_ever_live_p (STATIC_CHAIN_REGNUM) - && call_used_regs[STATIC_CHAIN_REGNUM]); + && call_used_or_fixed_reg_p (STATIC_CHAIN_REGNUM)); info->savres_strategy = rs6000_savres_strategy (info, using_static_chain_p); if (!(info->savres_strategy & SAVE_INLINE_GPRS) @@ -2082,7 +2082,7 @@ generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep) for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i) if (info->vrsave_mask & ALTIVEC_REG_BIT (i)) { - if (!epiloguep || call_used_regs [i]) + if (!epiloguep || call_used_or_fixed_reg_p (i)) clobs[nclobs++] = gen_hard_reg_clobber (V4SImode, i); else { @@ -2971,9 +2971,10 @@ rs6000_emit_prologue (void) rtx cr_save_rtx = NULL_RTX; rtx_insn *insn; int strategy; - int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE - && df_regs_ever_live_p (STATIC_CHAIN_REGNUM) - && call_used_regs[STATIC_CHAIN_REGNUM]); + int using_static_chain_p + = (cfun->static_chain_decl != NULL_TREE + && df_regs_ever_live_p (STATIC_CHAIN_REGNUM) + && call_used_or_fixed_reg_p (STATIC_CHAIN_REGNUM)); int using_split_stack = (flag_split_stack && (lookup_attribute ("no_split_stack", DECL_ATTRIBUTES (cfun->decl)) @@ -3571,7 +3572,7 @@ rs6000_emit_prologue (void) emit_insn (gen_prologue_movesi_from_cr (crsave)); for (i = 0; i < 8; i++) - if (!call_used_regs[CR0_REGNO + i]) + if (!call_used_or_fixed_reg_p (CR0_REGNO + i)) { rtvec p = rtvec_alloc (2); RTVEC_ELT (p, 0) @@ -4704,7 +4705,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type) int i, cr_off = info->ehcr_offset; for (i = 0; i < 8; i++) - if (!call_used_regs[CR0_REGNO + i]) + if (!call_used_or_fixed_reg_p (CR0_REGNO + i)) { rtx reg = gen_rtx_REG (SImode, 0); emit_insn (gen_frame_load (reg, frame_reg_rtx, diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 03349e8..f657ff3 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1990,7 +1990,7 @@ rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name) comma = ", "; } - if (call_used_regs[r]) + if (call_used_or_fixed_reg_p (r)) { if (len > 70) { diff --git a/gcc/config/rx/rx.c b/gcc/config/rx/rx.c index a1fc22b..c7ce19c 100644 --- a/gcc/config/rx/rx.c +++ b/gcc/config/rx/rx.c @@ -1483,10 +1483,10 @@ rx_get_stack_layout (unsigned int * lowest, /* Always save all call clobbered registers inside non-leaf interrupt handlers, even if they are not live - they may be used in (non-interrupt aware) routines called from this one. */ - || (call_used_regs[reg] + || (call_used_or_fixed_reg_p (reg) && is_interrupt_func (NULL_TREE) && ! crtl->is_leaf)) - && (! call_used_regs[reg] + && (! call_used_or_fixed_reg_p (reg) /* Even call clobbered registered must be pushed inside interrupt handlers. */ || is_interrupt_func (NULL_TREE) diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 2c6b598..93e77d1 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -13341,7 +13341,7 @@ s390_call_saved_register_used (tree call_expr) if (REG_P (parm_rtx)) { for (reg = 0; reg < REG_NREGS (parm_rtx); reg++) - if (!call_used_regs[reg + REGNO (parm_rtx)]) + if (!call_used_or_fixed_reg_p (reg + REGNO (parm_rtx))) return true; } @@ -13356,7 +13356,7 @@ s390_call_saved_register_used (tree call_expr) gcc_assert (REG_P (r)); for (reg = 0; reg < REG_NREGS (r); reg++) - if (!call_used_regs[reg + REGNO (r)]) + if (!call_used_or_fixed_reg_p (reg + REGNO (r))) return true; } } diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index ab3a78f..ef60b8c 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -7055,7 +7055,8 @@ calc_live_regs (HARD_REG_SET *live_regs_mask) || (df_regs_ever_live_p (reg) && ((!call_really_used_regs[reg] && !(reg != PIC_OFFSET_TABLE_REGNUM - && fixed_regs[reg] && call_used_regs[reg])) + && fixed_regs[reg] + && call_used_or_fixed_reg_p (reg))) || (trapa_handler && reg == FPSCR_REG && TARGET_FPU_ANY))) || (crtl->calls_eh_return && (reg == EH_RETURN_DATA_REGNO (0) @@ -10815,16 +10816,16 @@ sh_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED, registers are used for argument passing, are callee-saved, or reserved. */ /* We need to check call_used_regs / fixed_regs in case -fcall_saved-reg / -ffixed-reg has been used. */ - if (! call_used_regs[0] || fixed_regs[0]) + if (! call_used_or_fixed_reg_p (0) || fixed_regs[0]) error ("r0 needs to be available as a call-clobbered register"); scratch0 = scratch1 = scratch2 = gen_rtx_REG (Pmode, 0); { - if (call_used_regs[1] && ! fixed_regs[1]) + if (call_used_or_fixed_reg_p (1) && ! fixed_regs[1]) scratch1 = gen_rtx_REG (ptr_mode, 1); /* N.B., if not TARGET_HITACHI, register 2 is used to pass the pointer pointing where to return struct values. */ - if (call_used_regs[3] && ! fixed_regs[3]) + if (call_used_or_fixed_reg_p (3) && ! fixed_regs[3]) scratch2 = gen_rtx_REG (Pmode, 3); } diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 32767bc..43c6dd5 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -5446,7 +5446,7 @@ static inline bool save_global_or_fp_reg_p (unsigned int regno, int leaf_function ATTRIBUTE_UNUSED) { - return !call_used_regs[regno] && df_regs_ever_live_p (regno); + return !call_used_or_fixed_reg_p (regno) && df_regs_ever_live_p (regno); } /* Return whether the return address register (%i7) is needed. */ @@ -5474,7 +5474,7 @@ static bool save_local_or_in_reg_p (unsigned int regno, int leaf_function) { /* General case: call-saved registers live at some point. */ - if (!call_used_regs[regno] && df_regs_ever_live_p (regno)) + if (!call_used_or_fixed_reg_p (regno) && df_regs_ever_live_p (regno)) return true; /* Frame pointer register (%fp) if needed. */ diff --git a/gcc/config/stormy16/stormy16.c b/gcc/config/stormy16/stormy16.c index 23f546a..b2d4146 100644 --- a/gcc/config/stormy16/stormy16.c +++ b/gcc/config/stormy16/stormy16.c @@ -926,8 +926,8 @@ struct xstormy16_stack_layout /* Does REGNO need to be saved? */ #define REG_NEEDS_SAVE(REGNUM, IFUN) \ - ((df_regs_ever_live_p (REGNUM) && ! call_used_regs[REGNUM]) \ - || (IFUN && ! fixed_regs[REGNUM] && call_used_regs[REGNUM] \ + ((df_regs_ever_live_p (REGNUM) && !call_used_or_fixed_reg_p (REGNUM)) \ + || (IFUN && !fixed_regs[REGNUM] && call_used_or_fixed_reg_p (REGNUM) \ && (REGNUM != CARRY_REGNUM) \ && (df_regs_ever_live_p (REGNUM) || ! crtl->is_leaf))) @@ -1191,7 +1191,7 @@ xstormy16_expand_epilogue (void) int xstormy16_epilogue_uses (int regno) { - if (reload_completed && call_used_regs[regno]) + if (reload_completed && call_used_or_fixed_reg_p (regno)) { const int ifun = xstormy16_interrupt_function_p (); return REG_NEEDS_SAVE (regno, ifun); diff --git a/gcc/config/tilegx/tilegx.c b/gcc/config/tilegx/tilegx.c index 4f29655..66a0ba5 100644 --- a/gcc/config/tilegx/tilegx.c +++ b/gcc/config/tilegx/tilegx.c @@ -3660,7 +3660,7 @@ tilegx_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED) static bool need_to_save_reg (unsigned int regno) { - if (!fixed_regs[regno] && !call_used_regs[regno] + if (!fixed_regs[regno] && !call_used_or_fixed_reg_p (regno) && df_regs_ever_live_p (regno)) return true; diff --git a/gcc/config/tilepro/tilepro.c b/gcc/config/tilepro/tilepro.c index 2e14b2e..ff01428 100644 --- a/gcc/config/tilepro/tilepro.c +++ b/gcc/config/tilepro/tilepro.c @@ -3202,7 +3202,7 @@ tilepro_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED) static bool need_to_save_reg (unsigned int regno) { - if (!fixed_regs[regno] && !call_used_regs[regno] + if (!fixed_regs[regno] && !call_used_or_fixed_reg_p (regno) && df_regs_ever_live_p (regno)) return true; diff --git a/gcc/config/v850/v850.c b/gcc/config/v850/v850.c index d5c9ba7..9a367ab 100644 --- a/gcc/config/v850/v850.c +++ b/gcc/config/v850/v850.c @@ -1461,7 +1461,7 @@ compute_register_save_size (long * p_reg_saved) { /* Find the first register that needs to be saved. */ for (i = 0; i <= 31; i++) - if (df_regs_ever_live_p (i) && ((! call_used_regs[i]) + if (df_regs_ever_live_p (i) && ((! call_used_or_fixed_reg_p (i)) || i == LINK_POINTER_REGNUM)) break; @@ -1502,7 +1502,7 @@ compute_register_save_size (long * p_reg_saved) else { for (; i <= 31; i++) - if (df_regs_ever_live_p (i) && ((! call_used_regs[i]) + if (df_regs_ever_live_p (i) && ((! call_used_or_fixed_reg_p (i)) || i == LINK_POINTER_REGNUM)) { size += 4; diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c index 1c220ff..7a8c86d 100644 --- a/gcc/config/vax/vax.c +++ b/gcc/config/vax/vax.c @@ -166,7 +166,7 @@ vax_expand_prologue (void) rtx insn; for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) - if (df_regs_ever_live_p (regno) && !call_used_regs[regno]) + if (df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno)) mask |= 1 << regno; insn = emit_insn (gen_procedure_entry_mask (GEN_INT (mask))); diff --git a/gcc/config/visium/visium.c b/gcc/config/visium/visium.c index b51c23f..367e1e5 100644 --- a/gcc/config/visium/visium.c +++ b/gcc/config/visium/visium.c @@ -3589,7 +3589,7 @@ visium_save_reg_p (int interrupt, int regno) if (df_regs_ever_live_p (regno)) return 1; } - else if (call_used_regs[regno]) + else if (call_used_or_fixed_reg_p (regno)) return 1; /* To save mdb requires two temporary registers. To save mdc or @@ -3616,7 +3616,7 @@ visium_save_reg_p (int interrupt, int regno) } } - return df_regs_ever_live_p (regno) && !call_used_regs[regno]; + return df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno); } /* Compute the frame size required by the function. This function is called diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c index 98f30c5..822c215 100644 --- a/gcc/config/xtensa/xtensa.c +++ b/gcc/config/xtensa/xtensa.c @@ -2686,7 +2686,7 @@ xtensa_call_save_reg(int regno) if (crtl->calls_eh_return && regno >= 2 && regno < 4) return true; - return !fixed_regs[regno] && !call_used_regs[regno] && + return !fixed_regs[regno] && !call_used_or_fixed_reg_p (regno) && df_regs_ever_live_p (regno); } diff --git a/gcc/cselib.c b/gcc/cselib.c index 87b3d33..109cc27 100644 --- a/gcc/cselib.c +++ b/gcc/cselib.c @@ -2766,7 +2766,7 @@ cselib_process_insn (rtx_insn *insn) if (CALL_P (insn)) { for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (call_used_regs[i] + if (call_used_or_fixed_reg_p (i) || (REG_VALUES (i) && REG_VALUES (i)->elt && (targetm.hard_regno_call_part_clobbered (insn, i, GET_MODE (REG_VALUES (i)->elt->val_rtx))))) diff --git a/gcc/df-scan.c b/gcc/df-scan.c index d7bc2d8..9b08bdc 100644 --- a/gcc/df-scan.c +++ b/gcc/df-scan.c @@ -3500,7 +3500,7 @@ df_get_entry_block_def_set (bitmap entry_block_defs) /* Defs for the callee saved registers are inserted so that the pushes have some defining location. */ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if ((call_used_regs[i] == 0) && (df_regs_ever_live_p (i))) + if ((call_used_or_fixed_reg_p (i) == 0) && (df_regs_ever_live_p (i))) bitmap_set_bit (entry_block_defs, i); } diff --git a/gcc/function.c b/gcc/function.c index 33e3f3e..e60b6fa 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -2122,7 +2122,7 @@ aggregate_value_p (const_tree exp, const_tree fntype) regno = REGNO (reg); nregs = hard_regno_nregs (regno, TYPE_MODE (type)); for (i = 0; i < nregs; i++) - if (! call_used_regs[regno + i]) + if (! call_used_or_fixed_reg_p (regno + i)) return 1; return 0; diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c index 5025aae..dba3acf 100644 --- a/gcc/haifa-sched.c +++ b/gcc/haifa-sched.c @@ -7207,7 +7207,7 @@ alloc_global_sched_pressure_data (void) fixed_regs_num[cl] = 0; for (int i = 0; i < ira_class_hard_regs_num[cl]; ++i) - if (!call_used_regs[ira_class_hard_regs[cl][i]]) + if (!call_used_or_fixed_reg_p (ira_class_hard_regs[cl][i])) ++call_saved_regs_num[cl]; else if (fixed_regs[ira_class_hard_regs[cl][i]]) ++fixed_regs_num[cl]; diff --git a/gcc/hard-reg-set.h b/gcc/hard-reg-set.h index 33ac640..8fd787a 100644 --- a/gcc/hard-reg-set.h +++ b/gcc/hard-reg-set.h @@ -511,4 +511,13 @@ extern const char * reg_class_names[]; #define REG_CAN_CHANGE_MODE_P(REGN, FROM, TO) \ (targetm.can_change_mode_class (FROM, TO, REGNO_REG_CLASS (REGN))) +/* Return true if register REGNO is either fixed or call-used + (aka call-clobbered). */ + +inline bool +call_used_or_fixed_reg_p (unsigned int regno) +{ + return fixed_regs[regno] || call_used_regs[regno]; +} + #endif /* ! GCC_HARD_REG_SET_H */ diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c index eb7eb0f..166bd7b 100644 --- a/gcc/ira-lives.c +++ b/gcc/ira-lives.c @@ -1380,7 +1380,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) if (!cfun->has_nonlocal_label && has_abnormal_call_or_eh_pred_edge_p (bb)) for (px = 0; px < FIRST_PSEUDO_REGISTER; px++) - if (call_used_regs[px] + if (call_used_or_fixed_reg_p (px) #ifdef REAL_PIC_OFFSET_TABLE_REGNUM /* We should create a conflict of PIC pseudo with PIC hard reg as PIC hard reg can have a wrong diff --git a/gcc/ira.c b/gcc/ira.c index b44647f..a4321d3 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -5589,7 +5589,9 @@ do_reload (void) poly_int64 size = get_frame_size () + STACK_CHECK_FIXED_FRAME_SIZE; for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (df_regs_ever_live_p (i) && !fixed_regs[i] && call_used_regs[i]) + if (df_regs_ever_live_p (i) + && !fixed_regs[i] + && call_used_or_fixed_reg_p (i)) size += UNITS_PER_WORD; if (constant_lower_bound (size) > STACK_CHECK_MAX_FRAME_SIZE) diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c index e509cc3..6f08159 100644 --- a/gcc/lra-lives.c +++ b/gcc/lra-lives.c @@ -1106,7 +1106,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) if (!cfun->has_nonlocal_label && has_abnormal_call_or_eh_pred_edge_p (bb)) for (px = 0; HARD_REGISTER_NUM_P (px); px++) - if (call_used_regs[px] + if (call_used_or_fixed_reg_p (px) #ifdef REAL_PIC_OFFSET_TABLE_REGNUM /* We should create a conflict of PIC pseudo with PIC hard reg as PIC hard reg can have a wrong value after diff --git a/gcc/lra-remat.c b/gcc/lra-remat.c index 18c0a6a..ea6e817 100644 --- a/gcc/lra-remat.c +++ b/gcc/lra-remat.c @@ -1309,7 +1309,7 @@ lra_remat (void) all_cands.create (8000); call_used_regs_arr_len = 0; for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (call_used_regs[i]) + if (call_used_or_fixed_reg_p (i)) call_used_regs_arr[call_used_regs_arr_len++] = i; initiate_cand_table (); create_remat_bb_data (); diff --git a/gcc/lra.c b/gcc/lra.c index 886fb10..65c0877 100644 --- a/gcc/lra.c +++ b/gcc/lra.c @@ -2420,7 +2420,7 @@ lra (FILE *f) if (crtl->saves_all_registers) for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (! call_used_regs[i] && ! fixed_regs[i] && ! LOCAL_REGNO (i)) + if (!call_used_or_fixed_reg_p (i) && !fixed_regs[i] && !LOCAL_REGNO (i)) df_set_regs_ever_live (i, true); /* We don't DF from now and avoid its using because it is to diff --git a/gcc/postreload.c b/gcc/postreload.c index af64def..73b0afa 100644 --- a/gcc/postreload.c +++ b/gcc/postreload.c @@ -1135,7 +1135,7 @@ reload_combine_recognize_pattern (rtx_insn *insn) if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], i) && reg_state[i].use_index == RELOAD_COMBINE_MAX_USES && reg_state[i].store_ruid <= reg_state[regno].use_ruid - && (call_used_regs[i] || df_regs_ever_live_p (i)) + && (call_used_or_fixed_reg_p (i) || df_regs_ever_live_p (i)) && (!frame_pointer_needed || i != HARD_FRAME_POINTER_REGNUM) && !fixed_regs[i] && !global_regs[i] && hard_regno_nregs (i, GET_MODE (reg)) == 1 @@ -2126,7 +2126,7 @@ reload_cse_move2add (rtx_insn *first) { for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--) { - if (call_used_regs[i]) + if (call_used_or_fixed_reg_p (i)) /* Reset the information about this register. */ reg_mode[i] = VOIDmode; } diff --git a/gcc/recog.c b/gcc/recog.c index a9f584b..f3e8a4c 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -3227,7 +3227,8 @@ peep2_find_free_register (int from, int to, const char *class_str, break; } /* And that we don't create an extra save/restore. */ - if (! call_used_regs[regno + j] && ! df_regs_ever_live_p (regno + j)) + if (! call_used_or_fixed_reg_p (regno + j) + && ! df_regs_ever_live_p (regno + j)) { success = 0; break; diff --git a/gcc/regrename.c b/gcc/regrename.c index 47d8224..14ce954 100644 --- a/gcc/regrename.c +++ b/gcc/regrename.c @@ -322,7 +322,7 @@ check_new_reg_p (int reg ATTRIBUTE_UNUSED, int new_reg, || global_regs[new_reg + i] /* Can't use regs which aren't saved by the prologue. */ || (! df_regs_ever_live_p (new_reg + i) - && ! call_used_regs[new_reg + i]) + && ! call_used_or_fixed_reg_p (new_reg + i)) #ifdef LEAF_REGISTERS /* We can't use a non-leaf register if we're in a leaf function. */ diff --git a/gcc/reload.c b/gcc/reload.c index 72cc38a..7731e0f 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -6911,14 +6911,14 @@ find_equiv_reg (rtx goal, rtx_insn *insn, enum reg_class rclass, int other, if (regno >= 0 && regno < FIRST_PSEUDO_REGISTER) for (i = 0; i < nregs; ++i) - if (call_used_regs[regno + i] + if (call_used_or_fixed_reg_p (regno + i) || targetm.hard_regno_call_part_clobbered (NULL, regno + i, mode)) return 0; if (valueno >= 0 && valueno < FIRST_PSEUDO_REGISTER) for (i = 0; i < valuenregs; ++i) - if (call_used_regs[valueno + i] + if (call_used_or_fixed_reg_p (valueno + i) || targetm.hard_regno_call_part_clobbered (NULL, valueno + i, mode)) return 0; diff --git a/gcc/reload1.c b/gcc/reload1.c index 8234e1e..c619c54 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -795,7 +795,9 @@ reload (rtx_insn *first, int global) if (crtl->saves_all_registers) for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (! call_used_regs[i] && ! fixed_regs[i] && ! LOCAL_REGNO (i)) + if (! call_used_or_fixed_reg_p (i) + && ! fixed_regs[i] + && ! LOCAL_REGNO (i)) df_set_regs_ever_live (i, true); /* Find all the pseudo registers that didn't get hard regs @@ -1906,8 +1908,8 @@ find_reg (class insn_chain *chain, int order) && (inv_reg_alloc_order[regno] < inv_reg_alloc_order[best_reg]) #else - && call_used_regs[regno] - && ! call_used_regs[best_reg] + && call_used_or_fixed_reg_p (regno) + && ! call_used_or_fixed_reg_p (best_reg) #endif )) { diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c index e515b1b..077845e 100644 --- a/gcc/sel-sched.c +++ b/gcc/sel-sched.c @@ -1123,7 +1123,7 @@ init_hard_regs_data (void) CLEAR_HARD_REG_SET (sel_hrd.regs_ever_used); for (cur_reg = 0; cur_reg < FIRST_PSEUDO_REGISTER; cur_reg++) - if (df_regs_ever_live_p (cur_reg) || call_used_regs[cur_reg]) + if (df_regs_ever_live_p (cur_reg) || call_used_or_fixed_reg_p (cur_reg)) SET_HARD_REG_BIT (sel_hrd.regs_ever_used, cur_reg); /* Initialize registers that are valid based on mode when this is -- cgit v1.1 From 2e3d041b1328f123e60244df9e78f9c30e73462c Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 10 Sep 2019 18:56:59 +0000 Subject: Remove redundant fixed_regs tests This patch removes redundant fixed_regs tests in things like: !fixed_regs[i] && !call_used_or_fixed_reg_p (i) 2019-09-10 Richard Sandiford gcc/ * config/alpha/alpha.c (alpha_compute_frame_layout): Remove redundant fixed_regs test. * config/bpf/bpf.c (bpf_compute_frame_layout, bpf_expand_prologue) (bpf_expand_epilogue): Likewise. * config/c6x/c6x.c (c6x_save_reg): Likewise. * config/ft32/ft32.c (ft32_expand_prologue): Likewise. (ft32_expand_epilogue): Likewise. * config/i386/i386.c (ix86_save_reg): Likewise. * config/moxie/moxie.c (moxie_expand_prologue): Likewise. (moxie_expand_epilogue): Likewise. * config/tilegx/tilegx.c (need_to_save_reg): Likewise. * config/tilepro/tilepro.c (need_to_save_reg): Likewise. * config/xtensa/xtensa.c (xtensa_call_save_reg): Likewise. From-SVN: r275603 --- gcc/ChangeLog | 16 ++++++++++++++++ gcc/config/alpha/alpha.c | 2 +- gcc/config/bpf/bpf.c | 9 +++------ gcc/config/c6x/c6x.c | 3 +-- gcc/config/ft32/ft32.c | 6 +++--- gcc/config/i386/i386.c | 1 - gcc/config/moxie/moxie.c | 5 ++--- gcc/config/tilegx/tilegx.c | 2 +- gcc/config/tilepro/tilepro.c | 2 +- gcc/config/xtensa/xtensa.c | 3 +-- 10 files changed, 29 insertions(+), 20 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 099652b..86aa676 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,21 @@ 2019-09-10 Richard Sandiford + * config/alpha/alpha.c (alpha_compute_frame_layout): Remove redundant + fixed_regs test. + * config/bpf/bpf.c (bpf_compute_frame_layout, bpf_expand_prologue) + (bpf_expand_epilogue): Likewise. + * config/c6x/c6x.c (c6x_save_reg): Likewise. + * config/ft32/ft32.c (ft32_expand_prologue): Likewise. + (ft32_expand_epilogue): Likewise. + * config/i386/i386.c (ix86_save_reg): Likewise. + * config/moxie/moxie.c (moxie_expand_prologue): Likewise. + (moxie_expand_epilogue): Likewise. + * config/tilegx/tilegx.c (need_to_save_reg): Likewise. + * config/tilepro/tilepro.c (need_to_save_reg): Likewise. + * config/xtensa/xtensa.c (xtensa_call_save_reg): Likewise. + +2019-09-10 Richard Sandiford + * hard-reg-set.h (call_used_or_fixed_reg_p): New macro. * cfgloopanal.c (init_set_costs): Use call_used_or_fixed_reg_p instead of testing call_used_regs directly. diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index 5c07b95..f01305b 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -7225,7 +7225,7 @@ alpha_compute_frame_layout (void) /* One for every register we have to save. */ for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (! fixed_regs[i] && ! call_used_or_fixed_reg_p (i) + if (! call_used_or_fixed_reg_p (i) && df_regs_ever_live_p (i) && i != REG_RA) sa_mask |= HOST_WIDE_INT_1U << i; diff --git a/gcc/config/bpf/bpf.c b/gcc/config/bpf/bpf.c index 6e57b00..0fe80ce 100644 --- a/gcc/config/bpf/bpf.c +++ b/gcc/config/bpf/bpf.c @@ -271,8 +271,7 @@ bpf_compute_frame_layout (void) the current function. There is no need to round up, since the registers are all 8 bytes wide. */ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) - if ((!fixed_regs[regno] - && df_regs_ever_live_p (regno) + if ((df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno)) || (cfun->calls_alloca && regno == STACK_POINTER_REGNUM)) @@ -312,8 +311,7 @@ bpf_expand_prologue (void) right after the local variables. */ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) { - if ((!fixed_regs[regno] - && df_regs_ever_live_p (regno) + if ((df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno)) || (cfun->calls_alloca && regno == STACK_POINTER_REGNUM)) @@ -372,8 +370,7 @@ bpf_expand_epilogue (void) /* Restore callee-saved hard registes from the stack. */ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) { - if ((!fixed_regs[regno] - && df_regs_ever_live_p (regno) + if ((df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno)) || (cfun->calls_alloca && regno == STACK_POINTER_REGNUM)) diff --git a/gcc/config/c6x/c6x.c b/gcc/config/c6x/c6x.c index 7d1c2f7..e593273 100644 --- a/gcc/config/c6x/c6x.c +++ b/gcc/config/c6x/c6x.c @@ -2532,8 +2532,7 @@ static int c6x_save_reg (unsigned int regno) { return ((df_regs_ever_live_p (regno) - && !call_used_or_fixed_reg_p (regno) - && !fixed_regs[regno]) + && !call_used_or_fixed_reg_p (regno)) || (regno == RETURN_ADDR_REGNO && (df_regs_ever_live_p (regno) || !crtl->is_leaf)) diff --git a/gcc/config/ft32/ft32.c b/gcc/config/ft32/ft32.c index 3361df1..840882f 100644 --- a/gcc/config/ft32/ft32.c +++ b/gcc/config/ft32/ft32.c @@ -475,7 +475,7 @@ ft32_expand_prologue (void) { for (regno = FIRST_PSEUDO_REGISTER; regno-- > 0;) { - if (!fixed_regs[regno] && !call_used_or_fixed_reg_p (regno) + if (!call_used_or_fixed_reg_p (regno) && df_regs_ever_live_p (regno)) { rtx preg = gen_rtx_REG (Pmode, regno); @@ -488,7 +488,7 @@ ft32_expand_prologue (void) { for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) { - if (!fixed_regs[regno] && df_regs_ever_live_p (regno) + if (df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno)) { insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno))); @@ -554,7 +554,7 @@ ft32_expand_epilogue (void) { for (regno = FIRST_PSEUDO_REGISTER; regno-- > 0;) { - if (!fixed_regs[regno] && !call_used_or_fixed_reg_p (regno) + if (!call_used_or_fixed_reg_p (regno) && df_regs_ever_live_p (regno)) { rtx preg = gen_rtx_REG (Pmode, regno); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 7525b9d..9a87413 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -5666,7 +5666,6 @@ ix86_save_reg (unsigned int regno, bool maybe_eh_return, bool ignore_outlined) return (df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno) - && !fixed_regs[regno] && (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed)); } diff --git a/gcc/config/moxie/moxie.c b/gcc/config/moxie/moxie.c index aa5948e..fa4ed3f 100644 --- a/gcc/config/moxie/moxie.c +++ b/gcc/config/moxie/moxie.c @@ -288,8 +288,7 @@ moxie_expand_prologue (void) /* Save callee-saved registers. */ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) { - if (!fixed_regs[regno] - && df_regs_ever_live_p (regno) + if (df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno)) { insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno))); @@ -351,7 +350,7 @@ moxie_expand_epilogue (void) emit_insn (gen_addsi3 (reg, reg, hard_frame_pointer_rtx)); } for (regno = FIRST_PSEUDO_REGISTER; regno-- > 0; ) - if (!fixed_regs[regno] && !call_used_or_fixed_reg_p (regno) + if (!call_used_or_fixed_reg_p (regno) && df_regs_ever_live_p (regno)) { rtx preg = gen_rtx_REG (Pmode, regno); diff --git a/gcc/config/tilegx/tilegx.c b/gcc/config/tilegx/tilegx.c index 66a0ba5..f2ea9bb 100644 --- a/gcc/config/tilegx/tilegx.c +++ b/gcc/config/tilegx/tilegx.c @@ -3660,7 +3660,7 @@ tilegx_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED) static bool need_to_save_reg (unsigned int regno) { - if (!fixed_regs[regno] && !call_used_or_fixed_reg_p (regno) + if (!call_used_or_fixed_reg_p (regno) && df_regs_ever_live_p (regno)) return true; diff --git a/gcc/config/tilepro/tilepro.c b/gcc/config/tilepro/tilepro.c index ff01428..a1d59b1 100644 --- a/gcc/config/tilepro/tilepro.c +++ b/gcc/config/tilepro/tilepro.c @@ -3202,7 +3202,7 @@ tilepro_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED) static bool need_to_save_reg (unsigned int regno) { - if (!fixed_regs[regno] && !call_used_or_fixed_reg_p (regno) + if (!call_used_or_fixed_reg_p (regno) && df_regs_ever_live_p (regno)) return true; diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c index 822c215..3c129fd 100644 --- a/gcc/config/xtensa/xtensa.c +++ b/gcc/config/xtensa/xtensa.c @@ -2686,8 +2686,7 @@ xtensa_call_save_reg(int regno) if (crtl->calls_eh_return && regno >= 2 && regno < 4) return true; - return !fixed_regs[regno] && !call_used_or_fixed_reg_p (regno) && - df_regs_ever_live_p (regno); + return !call_used_or_fixed_reg_p (regno) && df_regs_ever_live_p (regno); } /* Return the bytes needed to compute the frame pointer from the current -- cgit v1.1 From 53bee79caba4fb88acbcd9bad7891ea45b5511e3 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 10 Sep 2019 18:57:03 +0000 Subject: Hide call_used_regs in target-independent code Now that tests of call_used_regs go through call_used_or_fixed_reg_p, we can hide call_used_regs from target-independent code. (It still needs to be available to targets for the conditional register usage hooks.) 2019-09-10 Richard Sandiford gcc/ * hard-reg-set.h (call_used_regs): Only define if IN_TARGET_CODE. (call_used_or_fixed_reg_p): Expand definition of call_used_regs. * reginfo.c (call_used_regs): New macro. From-SVN: r275604 --- gcc/ChangeLog | 6 ++++++ gcc/hard-reg-set.h | 4 +++- gcc/reginfo.c | 3 +++ 3 files changed, 12 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 86aa676..7c8c5c5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2019-09-10 Richard Sandiford + * hard-reg-set.h (call_used_regs): Only define if IN_TARGET_CODE. + (call_used_or_fixed_reg_p): Expand definition of call_used_regs. + * reginfo.c (call_used_regs): New macro. + +2019-09-10 Richard Sandiford + * config/alpha/alpha.c (alpha_compute_frame_layout): Remove redundant fixed_regs test. * config/bpf/bpf.c (bpf_compute_frame_layout, bpf_expand_prologue) diff --git a/gcc/hard-reg-set.h b/gcc/hard-reg-set.h index 8fd787a..654e0d6 100644 --- a/gcc/hard-reg-set.h +++ b/gcc/hard-reg-set.h @@ -473,8 +473,10 @@ extern struct target_hard_regs *this_target_hard_regs; (this_target_hard_regs->x_fixed_reg_set) #define fixed_nonglobal_reg_set \ (this_target_hard_regs->x_fixed_nonglobal_reg_set) +#ifdef IN_TARGET_CODE #define call_used_regs \ (this_target_hard_regs->x_call_used_regs) +#endif #define call_really_used_regs \ (this_target_hard_regs->x_call_really_used_regs) #define savable_regs \ @@ -517,7 +519,7 @@ extern const char * reg_class_names[]; inline bool call_used_or_fixed_reg_p (unsigned int regno) { - return fixed_regs[regno] || call_used_regs[regno]; + return fixed_regs[regno] || this_target_hard_regs->x_call_used_regs[regno]; } #endif /* ! GCC_HARD_REG_SET_H */ diff --git a/gcc/reginfo.c b/gcc/reginfo.c index 026a7bf..e860def 100644 --- a/gcc/reginfo.c +++ b/gcc/reginfo.c @@ -66,6 +66,9 @@ struct target_hard_regs *this_target_hard_regs = &default_target_hard_regs; struct target_regs *this_target_regs = &default_target_regs; #endif +#define call_used_regs \ + (this_target_hard_regs->x_call_used_regs) + /* Data for initializing fixed_regs. */ static const char initial_fixed_regs[] = FIXED_REGISTERS; -- cgit v1.1 From d7fb4c3162307590c0babddcea4fb60c07a7c033 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 10 Sep 2019 18:57:09 +0000 Subject: Remove call_really_used_regs After previous patches, it's now possible for call_used_regs to be the "real" set of call-clobbered registers, without any special handling for fixed registers. This patch therefore removes the separate call_really_used_regs and updates the targets that define CALL_REALLY_USED_REGISTERS so that they handle call_used_regs in the same way that they used to handle call_really_used_regs. With this change, it's no longer necessary for targets that define CALL_REALLY_USED_REGISTERS to define CALL_USED_REGISTER as well. 2019-09-10 Richard Sandiford gcc/ * doc/tm.texi.in: Document that exactly one of CALL_USED_REGISTERS and CALL_REALLY_USED_REGISTERS must be defined, and that CALL_REALLY_USED_REGISTERS is preferred. * doc/tm.texi: Regenerate. * hard-reg-set.h (target_hard_regs::x_call_really_used_regs): Delete. (call_really_used_regs): Likewise. * reginfo.c: Raise an #error if both CALL_USED_REGISTERS and CALL_REALLY_USED_REGISTERS are defined. (initial_call_used_regs): Use CALL_REALLY_USED_REGISTERS as the initial value if defined. (initial_call_really_used_regs): Delete. (saved_call_really_used_regs): Likewise. (CALL_REALLY_USED_REGNO_P): Likewise. (init_reg_sets): Remove handling of call_really_used_regs. (save_register_info, restore_register_info, globalize_reg): Likewise. (init_reg_sets_1): Likewise. Use call_used_regs instead of CALL_REALLY_USED_REGNO_P. Don't set call_used_regs for registers outside operand_reg_set. (fix_register): Don't change call_used_regs if CALL_REALLY_USED_REGISTERS is defined. * config/csky/csky.h (CALL_USED_REGISTERS): Delete. * config/csky/csky.c (get_csky_live_regs): Use call_used_regs instead of call_really_used_regs. (csky_conditional_register_usage): Remove the old handling of call_used_regs and change the handling of call_really_used_regs to use call_used_regs instead. * config/ia64/ia64.h (CALL_USED_REGISTERS): Delete. * config/ia64/ia64.c (fix_range): Don't set call_used_regs when making a register fixed. * config/m32r/m32r.h (CALL_USED_REGISTERS): Delete. * config/m32r/m32r.c (MUST_SAVE_REGISTER): Use call_used_regs instead of call_really_used_regs. (m32r_conditional_register_usage): Don't set call_used_regs when making a register fixed. * config/mips/mips.h (CALL_USED_REGISTERS): Delete. * config/mips/mips.c (mips_global_pointer): Use call_used_regs instead of call_really_used_regs. (mips_interrupt_extra_call_saved_reg_p): Likewise. (mips_cfun_call_saved_reg_p): Likewise. (mips_swap_registers): Remove the old handling of call_used_regs and change the handling of call_really_used_regs to use call_used_regs instead. (mips_conditional_register_usage): Likewise. * config/mn10300/mn10300.h (CALL_USED_REGISTERS): Delete. * config/mn10300/mn10300.c (fp_regs_to_save): Use call_used_regs instead of call_really_used_regs. (mn10300_get_live_callee_saved_regs): Likewise. (mn10300_expand_prologue, mn10300_expand_epilogue): Likewise. (mn10300_conditional_register_usage): Don't set call_used_regs when making a register fixed. * config/rs6000/rs6000.h (CALL_USED_REGISTERS): Delete. * config/rs6000/rs6000.c (rs6000_conditional_register_usage): Remove the old handling of call_used_regs and change the handling of call_really_used_regs to use call_used_regs instead. * config/s390/s390.h (CALL_USED_REGISTERS): Delete. * config/s390/s390.c (s390_regs_ever_clobbered): Use call_used_regs instead of call_really_used_regs. (s390_register_info_gprtofpr, s390_register_info): Likewise. (s390_hard_regno_rename_ok, s390_hard_regno_scratch_ok): Likewise. (s390_emit_prologue, s300_set_up_by_prologue): Likewise. (s390_can_use_return_insn, s390_optimize_prologue): Likewise. (s390_conditional_register_usage): Remove the old handling of call_used_regs and change the handling of call_really_used_regs to use call_used_regs instead. * config/sh/sh.h (CALL_USED_REGISTERS): Delete. * config/sh/sh.c (output_stack_adjust, calc_live_regs): Likewise. (sh_fix_range, reg_unused_after): Likewise. (sh_conditional_register_usage): Remove the old handling of call_used_regs and change the handling of call_really_used_regs to use call_used_regs instead. * config/sparc/sparc.h (CALL_USED_REGISTERS): Delete. * config/sparc/sparc.c (sparc_conditional_register_usage): Don't set call_used_regs when making a register fixed. * config/tilegx/tilegx.h (CALL_USED_REGISTERS): Delete. * config/tilegx/tilegx.c (tilegx_conditional_register_usage): Don't set call_used_regs when making a register fixed. * config/tilepro/tilepro.h (CALL_USED_REGISTERS): Delete. * config/tilepro/tilepro.c (tilepro_conditional_register_usage): Don't set call_used_regs when making a register fixed. * config/visium/visium.h (CALL_USED_REGISTERS): Delete. * config/visium/visium.c (visium_conditional_register_usage): Remove the old handling of call_used_regs and change the handling of call_really_used_regs to use call_used_regs instead. From-SVN: r275605 --- gcc/ChangeLog | 86 ++++++++++++++++++++++++++++++++++++++++++++ gcc/config/csky/csky.c | 15 +++----- gcc/config/csky/csky.h | 28 --------------- gcc/config/ia64/ia64.c | 2 +- gcc/config/ia64/ia64.h | 35 ------------------ gcc/config/m32r/m32r.c | 7 ++-- gcc/config/m32r/m32r.h | 4 +-- gcc/config/mips/mips.c | 49 +++++++++++++------------ gcc/config/mips/mips.h | 23 ------------ gcc/config/mn10300/mn10300.c | 21 ++++++----- gcc/config/mn10300/mn10300.h | 9 +---- gcc/config/rs6000/rs6000.c | 25 ++++++------- gcc/config/rs6000/rs6000.h | 25 ------------- gcc/config/s390/s390.c | 41 ++++++++++----------- gcc/config/s390/s390.h | 16 --------- gcc/config/sh/sh.c | 30 +++++++--------- gcc/config/sh/sh.h | 39 -------------------- gcc/config/sparc/sparc.c | 5 +-- gcc/config/sparc/sparc.h | 25 ------------- gcc/config/tilegx/tilegx.c | 15 ++------ gcc/config/tilegx/tilegx.h | 5 +-- gcc/config/tilepro/tilepro.c | 15 ++------ gcc/config/tilepro/tilepro.h | 5 +-- gcc/config/visium/visium.c | 28 +++++++-------- gcc/config/visium/visium.h | 21 ----------- gcc/doc/tm.texi | 8 +++-- gcc/doc/tm.texi.in | 8 +++-- gcc/hard-reg-set.h | 4 --- gcc/reginfo.c | 58 +++++------------------------- 29 files changed, 214 insertions(+), 438 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7c8c5c5..a0badf5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,91 @@ 2019-09-10 Richard Sandiford + * doc/tm.texi.in: Document that exactly one of CALL_USED_REGISTERS + and CALL_REALLY_USED_REGISTERS must be defined, and that + CALL_REALLY_USED_REGISTERS is preferred. + * doc/tm.texi: Regenerate. + * hard-reg-set.h (target_hard_regs::x_call_really_used_regs): Delete. + (call_really_used_regs): Likewise. + * reginfo.c: Raise an #error if both CALL_USED_REGISTERS and + CALL_REALLY_USED_REGISTERS are defined. + (initial_call_used_regs): Use CALL_REALLY_USED_REGISTERS as the + initial value if defined. + (initial_call_really_used_regs): Delete. + (saved_call_really_used_regs): Likewise. + (CALL_REALLY_USED_REGNO_P): Likewise. + (init_reg_sets): Remove handling of call_really_used_regs. + (save_register_info, restore_register_info, globalize_reg): Likewise. + (init_reg_sets_1): Likewise. Use call_used_regs instead of + CALL_REALLY_USED_REGNO_P. Don't set call_used_regs for registers + outside operand_reg_set. + (fix_register): Don't change call_used_regs if + CALL_REALLY_USED_REGISTERS is defined. + * config/csky/csky.h (CALL_USED_REGISTERS): Delete. + * config/csky/csky.c (get_csky_live_regs): Use call_used_regs + instead of call_really_used_regs. + (csky_conditional_register_usage): Remove the old handling of + call_used_regs and change the handling of call_really_used_regs + to use call_used_regs instead. + * config/ia64/ia64.h (CALL_USED_REGISTERS): Delete. + * config/ia64/ia64.c (fix_range): Don't set call_used_regs when + making a register fixed. + * config/m32r/m32r.h (CALL_USED_REGISTERS): Delete. + * config/m32r/m32r.c (MUST_SAVE_REGISTER): Use call_used_regs + instead of call_really_used_regs. + (m32r_conditional_register_usage): Don't set call_used_regs when + making a register fixed. + * config/mips/mips.h (CALL_USED_REGISTERS): Delete. + * config/mips/mips.c (mips_global_pointer): Use call_used_regs + instead of call_really_used_regs. + (mips_interrupt_extra_call_saved_reg_p): Likewise. + (mips_cfun_call_saved_reg_p): Likewise. + (mips_swap_registers): Remove the old handling of call_used_regs + and change the handling of call_really_used_regs to use call_used_regs + instead. + (mips_conditional_register_usage): Likewise. + * config/mn10300/mn10300.h (CALL_USED_REGISTERS): Delete. + * config/mn10300/mn10300.c (fp_regs_to_save): Use call_used_regs + instead of call_really_used_regs. + (mn10300_get_live_callee_saved_regs): Likewise. + (mn10300_expand_prologue, mn10300_expand_epilogue): Likewise. + (mn10300_conditional_register_usage): Don't set call_used_regs when + making a register fixed. + * config/rs6000/rs6000.h (CALL_USED_REGISTERS): Delete. + * config/rs6000/rs6000.c (rs6000_conditional_register_usage): + Remove the old handling of call_used_regs and change the handling + of call_really_used_regs to use call_used_regs instead. + * config/s390/s390.h (CALL_USED_REGISTERS): Delete. + * config/s390/s390.c (s390_regs_ever_clobbered): Use call_used_regs + instead of call_really_used_regs. + (s390_register_info_gprtofpr, s390_register_info): Likewise. + (s390_hard_regno_rename_ok, s390_hard_regno_scratch_ok): Likewise. + (s390_emit_prologue, s300_set_up_by_prologue): Likewise. + (s390_can_use_return_insn, s390_optimize_prologue): Likewise. + (s390_conditional_register_usage): Remove the old handling of + call_used_regs and change the handling of call_really_used_regs + to use call_used_regs instead. + * config/sh/sh.h (CALL_USED_REGISTERS): Delete. + * config/sh/sh.c (output_stack_adjust, calc_live_regs): Likewise. + (sh_fix_range, reg_unused_after): Likewise. + (sh_conditional_register_usage): Remove the old handling of + call_used_regs and change the handling of call_really_used_regs + to use call_used_regs instead. + * config/sparc/sparc.h (CALL_USED_REGISTERS): Delete. + * config/sparc/sparc.c (sparc_conditional_register_usage): Don't set + call_used_regs when making a register fixed. + * config/tilegx/tilegx.h (CALL_USED_REGISTERS): Delete. + * config/tilegx/tilegx.c (tilegx_conditional_register_usage): Don't set + call_used_regs when making a register fixed. + * config/tilepro/tilepro.h (CALL_USED_REGISTERS): Delete. + * config/tilepro/tilepro.c (tilepro_conditional_register_usage): Don't + set call_used_regs when making a register fixed. + * config/visium/visium.h (CALL_USED_REGISTERS): Delete. + * config/visium/visium.c (visium_conditional_register_usage): Remove + the old handling of call_used_regs and change the handling of + call_really_used_regs to use call_used_regs instead. + +2019-09-10 Richard Sandiford + * hard-reg-set.h (call_used_regs): Only define if IN_TARGET_CODE. (call_used_or_fixed_reg_p): Expand definition of call_used_regs. * reginfo.c (call_used_regs): New macro. diff --git a/gcc/config/csky/csky.c b/gcc/config/csky/csky.c index 309d00d..0759ddc 100644 --- a/gcc/config/csky/csky.c +++ b/gcc/config/csky/csky.c @@ -1655,7 +1655,7 @@ get_csky_live_regs (int *count) break; /* Caller-saved registers marked as used. */ - if (df_regs_ever_live_p (reg) && !call_really_used_regs[reg]) + if (df_regs_ever_live_p (reg) && !call_used_regs[reg]) save = true; /* Frame pointer marked used. */ @@ -2074,7 +2074,6 @@ csky_conditional_register_usage (void) { fixed_regs[i] = 1; call_used_regs[i] = 1; - call_really_used_regs[i] = 1; } } /* For some targets, the high registers are not supported. @@ -2090,7 +2089,6 @@ csky_conditional_register_usage (void) { fixed_regs[i] = 1; call_used_regs[i] = 1; - call_really_used_regs[i] = 1; } } @@ -2103,8 +2101,7 @@ csky_conditional_register_usage (void) if (CSKY_TARGET_ARCH (CK801) || CSKY_TARGET_ARCH (CK802)) { fixed_regs[CSKY_LR_REGNUM] = 1; - call_used_regs[CSKY_LR_REGNUM] = 1; - call_really_used_regs[CSKY_LR_REGNUM] = 0; + call_used_regs[CSKY_LR_REGNUM] = 0; } /* The hi/lo registers are only supported in dsp mode. */ @@ -2112,11 +2109,9 @@ csky_conditional_register_usage (void) { fixed_regs[CSKY_HI_REGNUM] = 1; call_used_regs[CSKY_HI_REGNUM] = 1; - call_really_used_regs[CSKY_HI_REGNUM] = 1; fixed_regs[CSKY_LO_REGNUM] = 1; call_used_regs[CSKY_LO_REGNUM] = 1; - call_really_used_regs[CSKY_LO_REGNUM] = 1; } /* The V_REGS are only supported in hard float mode. */ @@ -2129,18 +2124,16 @@ csky_conditional_register_usage (void) { fixed_regs[regno] = 1; call_used_regs[regno] = 1; - call_really_used_regs[regno] = 1; } } /* In pic mode, the gb register is not available for register allocation. Since gb is not clobbered by function - calls, set its call_really_used_regs to 0. */ + calls, set its call_used_regs to 0. */ if (flag_pic) { fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; - call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; - call_really_used_regs[PIC_OFFSET_TABLE_REGNUM] = 0; + call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 0; } } diff --git a/gcc/config/csky/csky.h b/gcc/config/csky/csky.h index ea95290..bc4178b 100644 --- a/gcc/config/csky/csky.h +++ b/gcc/config/csky/csky.h @@ -428,34 +428,6 @@ extern int csky_arch_isa_features[]; 1 \ } -/* 1 for registers that is clobbered (in general) by function calls. - If a register has 0, the compiler automatically saves it on - function entry and restores it on function exit, if the register - is used within the function. */ -#define CALL_USED_REGISTERS \ - /* r0 r1 r2 r3 r4 r5 r6 r7 */ \ -{ 1, 1, 1, 1, 0, 0, 0, 0, \ - /* r8 r9 r10 r11 r12 r13 r14 r15 */ \ - 0, 0, 0, 0, 1, 1, 1, 0, \ - /* r16 r17 r18 r19 r20 r21 r22 r23 */ \ - 0, 0, 1, 1, 1, 1, 1, 1, \ - /* r24 r25 r26 r27 r28 r29 r30 r31 */ \ - 1, 1, 1, 1, 1, 1, 1, 1, \ - /* reserved c hi lo */ \ - 1, 1, 1, 1, \ - /* reserved */ \ - 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, \ - /* vr0 vr1 vr2 vr3 vr4 vr5 vr6 vr7 */ \ - 1, 1, 1, 1, 1, 1, 1, 1, \ - /* vr8 vr9 vr10 vr11 vr12 vr13 vr14 vr15 */ \ - 1, 1, 1, 1, 1, 1, 1, 1, \ - /* reserved */ \ - 1, 1, \ - /* epc */ \ - 1 \ -} - /* Like `CALL_USED_REGISTERS' but used to overcome a historical problem which makes CALL_USED_REGISTERS *always* include all the FIXED_REGISTERS. Until this problem has been diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index ff2ad20..7697e90 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -6054,7 +6054,7 @@ fix_range (const char *const_str) } for (i = first; i <= last; ++i) - fixed_regs[i] = call_used_regs[i] = 1; + fixed_regs[i] = 1; if (!comma) break; diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h index 5f2a396..d9d78fd 100644 --- a/gcc/config/ia64/ia64.h +++ b/gcc/config/ia64/ia64.h @@ -371,41 +371,6 @@ while (0) 1, 1, 1, 1, 1, 1 \ } -/* Like `FIXED_REGISTERS' but has 1 for each register that is clobbered - (in general) by function calls as well as for fixed registers. This - macro therefore identifies the registers that are not available for - general allocation of values that must live across function calls. */ - -#define CALL_USED_REGISTERS \ -{ /* General registers. */ \ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, \ - /* Floating-point registers. */ \ - 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ - /* Predicate registers. */ \ - 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - /* Branch registers. */ \ - 1, 0, 0, 0, 0, 0, 1, 1, \ - /*FP CCV UNAT PFS LC EC */ \ - 1, 1, 1, 1, 1, 1 \ -} - /* Like `CALL_USED_REGISTERS' but used to overcome a historical problem which makes CALL_USED_REGISTERS *always* include all the FIXED_REGISTERS. Until this problem has been diff --git a/gcc/config/m32r/m32r.c b/gcc/config/m32r/m32r.c index 52a1e26..c3bb17b 100644 --- a/gcc/config/m32r/m32r.c +++ b/gcc/config/m32r/m32r.c @@ -1526,7 +1526,7 @@ static struct m32r_frame_info zero_frame_info; Don't consider them here. */ #define MUST_SAVE_REGISTER(regno, interrupt_p) \ ((regno) != RETURN_ADDR_REGNUM && (regno) != FRAME_POINTER_REGNUM \ - && (df_regs_ever_live_p (regno) && (!call_really_used_regs[regno] || interrupt_p))) + && (df_regs_ever_live_p (regno) && (!call_used_regs[regno] || interrupt_p))) #define MUST_SAVE_FRAME_POINTER (df_regs_ever_live_p (FRAME_POINTER_REGNUM)) #define MUST_SAVE_RETURN_ADDR (df_regs_ever_live_p (RETURN_ADDR_REGNUM) || crtl->profile) @@ -2927,10 +2927,7 @@ static void m32r_conditional_register_usage (void) { if (flag_pic) - { - fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; - call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; - } + fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; } /* Implement TARGET_LEGITIMATE_CONSTANT_P diff --git a/gcc/config/m32r/m32r.h b/gcc/config/m32r/m32r.h index 2e7aacf..73f9856 100644 --- a/gcc/config/m32r/m32r.h +++ b/gcc/config/m32r/m32r.h @@ -348,7 +348,7 @@ #define SUBTARGET_CALL_USED_REGISTERS #endif -#define CALL_USED_REGISTERS \ +#define CALL_REALLY_USED_REGISTERS \ { \ 1, 1, 1, 1, 1, 1, 1, 1, \ 0, 0, 0, 0, 0, 0, 1, 1, \ @@ -356,8 +356,6 @@ SUBTARGET_CALL_USED_REGISTERS \ } -#define CALL_REALLY_USED_REGISTERS CALL_USED_REGISTERS - /* If defined, an initializer for a vector of integers, containing the numbers of hard registers in the order in which GCC should prefer to use them (from most preferred to least). */ diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 4c61154..c682ebd 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -10636,7 +10636,7 @@ mips_global_pointer (void) if (TARGET_CALL_SAVED_GP && crtl->is_leaf) for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++) if (!df_regs_ever_live_p (regno) - && call_really_used_regs[regno] + && call_used_regs[regno] && !fixed_regs[regno] && regno != PIC_FUNCTION_ADDR_REGNUM) return regno; @@ -10789,7 +10789,7 @@ mips_interrupt_extra_call_saved_reg_p (unsigned int regno) /* Otherwise, return true for registers that aren't ordinarily call-clobbered. */ - return call_really_used_regs[regno]; + return call_used_regs[regno]; } return false; @@ -10812,12 +10812,12 @@ mips_cfun_call_saved_reg_p (unsigned int regno) return true; /* call_insns preserve $28 unless they explicitly say otherwise, - so call_really_used_regs[] treats $28 as call-saved. However, + so call_used_regs[] treats $28 as call-saved. However, we want the ABI property rather than the default call_insn property here. */ return (regno == GLOBAL_POINTER_REGNUM ? TARGET_CALL_SAVED_GP - : !call_really_used_regs[regno]); + : !call_used_regs[regno]); } /* Return true if the function body might clobber register REGNO. @@ -20411,7 +20411,6 @@ mips_swap_registers (unsigned int i) SWAP_INT (fixed_regs[i], fixed_regs[i + 1]); SWAP_INT (call_used_regs[i], call_used_regs[i + 1]); - SWAP_INT (call_really_used_regs[i], call_really_used_regs[i + 1]); SWAP_STRING (reg_names[i], reg_names[i + 1]); #undef SWAP_STRING @@ -20447,7 +20446,7 @@ mips_conditional_register_usage (void) accessible_reg_set &= ~reg_class_contents[ST_REGS]; if (!ISA_HAS_CCF) SET_HARD_REG_BIT (accessible_reg_set, FPSW_REGNUM); - fixed_regs[FPSW_REGNUM] = call_used_regs[FPSW_REGNUM] = 1; + fixed_regs[FPSW_REGNUM] = 1; } if (TARGET_MIPS16) { @@ -20462,25 +20461,25 @@ mips_conditional_register_usage (void) and $25 (t9) because it is used as the function call address in SVR4 PIC code. */ - fixed_regs[18] = call_used_regs[18] = 1; - fixed_regs[19] = call_used_regs[19] = 1; - fixed_regs[20] = call_used_regs[20] = 1; - fixed_regs[21] = call_used_regs[21] = 1; - fixed_regs[22] = call_used_regs[22] = 1; - fixed_regs[23] = call_used_regs[23] = 1; - fixed_regs[26] = call_used_regs[26] = 1; - fixed_regs[27] = call_used_regs[27] = 1; - fixed_regs[30] = call_used_regs[30] = 1; + fixed_regs[18] = 1; + fixed_regs[19] = 1; + fixed_regs[20] = 1; + fixed_regs[21] = 1; + fixed_regs[22] = 1; + fixed_regs[23] = 1; + fixed_regs[26] = 1; + fixed_regs[27] = 1; + fixed_regs[30] = 1; if (optimize_size) { - fixed_regs[8] = call_used_regs[8] = 1; - fixed_regs[9] = call_used_regs[9] = 1; - fixed_regs[10] = call_used_regs[10] = 1; - fixed_regs[11] = call_used_regs[11] = 1; - fixed_regs[12] = call_used_regs[12] = 1; - fixed_regs[13] = call_used_regs[13] = 1; - fixed_regs[14] = call_used_regs[14] = 1; - fixed_regs[15] = call_used_regs[15] = 1; + fixed_regs[8] = 1; + fixed_regs[9] = 1; + fixed_regs[10] = 1; + fixed_regs[11] = 1; + fixed_regs[12] = 1; + fixed_regs[13] = 1; + fixed_regs[14] = 1; + fixed_regs[15] = 1; } /* Do not allow HI and LO to be treated as register operands. @@ -20493,7 +20492,7 @@ mips_conditional_register_usage (void) { int regno; for (regno = FP_REG_FIRST + 20; regno < FP_REG_FIRST + 24; regno++) - call_really_used_regs[regno] = call_used_regs[regno] = 1; + call_used_regs[regno] = 1; } /* Odd registers in the range $f21-$f31 (inclusive) are call-clobbered for n32 and o32 FP64. */ @@ -20503,7 +20502,7 @@ mips_conditional_register_usage (void) { int regno; for (regno = FP_REG_FIRST + 21; regno <= FP_REG_FIRST + 31; regno+=2) - call_really_used_regs[regno] = call_used_regs[regno] = 1; + call_used_regs[regno] = 1; } /* Make sure that double-register accumulator values are correctly ordered for the current endianness. */ diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index a5be7fa3..881c23a 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -1817,29 +1817,6 @@ FP_ASM_SPEC "\ called function in tact. EPILOGUE_USES says that $31 is useful to the called function. */ -#define CALL_USED_REGISTERS \ -{ \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ - /* COP0 registers */ \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ - /* COP2 registers */ \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ - /* COP3 registers */ \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ - /* 6 DSP accumulator registers & 6 control registers */ \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 \ -} - - -/* Define this since $28, though fixed, is call-saved in many ABIs. */ - #define CALL_REALLY_USED_REGISTERS \ { /* General registers. */ \ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ diff --git a/gcc/config/mn10300/mn10300.c b/gcc/config/mn10300/mn10300.c index 5502d65..da27c90 100644 --- a/gcc/config/mn10300/mn10300.c +++ b/gcc/config/mn10300/mn10300.c @@ -552,7 +552,7 @@ fp_regs_to_save (void) return 0; for (i = FIRST_FP_REGNUM; i <= LAST_FP_REGNUM; ++i) - if (df_regs_ever_live_p (i) && ! call_really_used_regs[i]) + if (df_regs_ever_live_p (i) && ! call_used_regs[i]) ++n; return n; @@ -640,7 +640,7 @@ mn10300_get_live_callee_saved_regs (unsigned int * bytes_saved) count = mask = 0; for (i = 0; i <= LAST_EXTENDED_REGNUM; i++) - if (df_regs_ever_live_p (i) && ! call_really_used_regs[i]) + if (df_regs_ever_live_p (i) && ! call_used_regs[i]) { mask |= (1 << i); ++ count; @@ -878,7 +878,7 @@ mn10300_expand_prologue (void) frame pointer, size is nonzero and the user hasn't changed the calling conventions of a0. */ if (! frame_pointer_needed && size - && call_really_used_regs [FIRST_ADDRESS_REGNUM] + && call_used_regs[FIRST_ADDRESS_REGNUM] && ! fixed_regs[FIRST_ADDRESS_REGNUM]) { /* Insn: add -(size + 4 * num_regs_to_save), sp. */ @@ -902,7 +902,7 @@ mn10300_expand_prologue (void) /* Consider alternative save_a0_no_merge if the user hasn't changed the calling conventions of a0. */ - if (call_really_used_regs [FIRST_ADDRESS_REGNUM] + if (call_used_regs[FIRST_ADDRESS_REGNUM] && ! fixed_regs[FIRST_ADDRESS_REGNUM]) { /* Insn: add -4 * num_regs_to_save, sp. */ @@ -984,7 +984,7 @@ mn10300_expand_prologue (void) /* Now actually save the FP registers. */ for (i = FIRST_FP_REGNUM; i <= LAST_FP_REGNUM; ++i) - if (df_regs_ever_live_p (i) && ! call_really_used_regs [i]) + if (df_regs_ever_live_p (i) && ! call_used_regs[i]) { rtx addr; @@ -1118,7 +1118,7 @@ mn10300_expand_epilogue (void) /* Consider using a1 in post-increment mode, as long as the user hasn't changed the calling conventions of a1. */ - if (call_really_used_regs [FIRST_ADDRESS_REGNUM + 1] + if (call_used_regs[FIRST_ADDRESS_REGNUM + 1] && ! fixed_regs[FIRST_ADDRESS_REGNUM+1]) { /* Insn: mov sp,a1. */ @@ -1186,7 +1186,7 @@ mn10300_expand_epilogue (void) reg = gen_rtx_POST_INC (SImode, reg); for (i = FIRST_FP_REGNUM; i <= LAST_FP_REGNUM; ++i) - if (df_regs_ever_live_p (i) && ! call_really_used_regs [i]) + if (df_regs_ever_live_p (i) && ! call_used_regs[i]) { rtx addr; @@ -2830,17 +2830,16 @@ mn10300_conditional_register_usage (void) { for (i = FIRST_EXTENDED_REGNUM; i <= LAST_EXTENDED_REGNUM; i++) - fixed_regs[i] = call_used_regs[i] = 1; + fixed_regs[i] = 1; } if (!TARGET_AM33_2) { for (i = FIRST_FP_REGNUM; i <= LAST_FP_REGNUM; i++) - fixed_regs[i] = call_used_regs[i] = 1; + fixed_regs[i] = 1; } if (flag_pic) - fixed_regs[PIC_OFFSET_TABLE_REGNUM] = - call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; + fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; } /* Worker function for TARGET_MD_ASM_ADJUST. diff --git a/gcc/config/mn10300/mn10300.h b/gcc/config/mn10300/mn10300.h index b36c8f5..6946e72 100644 --- a/gcc/config/mn10300/mn10300.h +++ b/gcc/config/mn10300/mn10300.h @@ -197,7 +197,7 @@ extern enum processor_type mn10300_tune_cpu; Aside from that, you can include as many other registers as you like. */ -#define CALL_USED_REGISTERS \ +#define CALL_REALLY_USED_REGISTERS \ { 1, 1, 0, 0, /* data regs */ \ 1, 1, 0, 0, /* addr regs */ \ 1, /* arg reg */ \ @@ -211,13 +211,6 @@ extern enum processor_type mn10300_tune_cpu; 1 /* cc reg */ \ } -/* Note: The definition of CALL_REALLY_USED_REGISTERS is not - redundant. It is needed when compiling in PIC mode because - the a2 register becomes fixed (and hence must be marked as - call_used) but in order to preserve the ABI it is not marked - as call_really_used. */ -#define CALL_REALLY_USED_REGISTERS CALL_USED_REGISTERS - #define REG_ALLOC_ORDER \ { 0, 1, 4, 5, 2, 3, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 8, 9 \ , 42, 43, 44, 45, 46, 47, 48, 49, 34, 35, 36, 37, 38, 39, 40, 41 \ diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index f657ff3..217548c 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -8904,42 +8904,37 @@ rs6000_conditional_register_usage (void) /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */ if (TARGET_64BIT) - fixed_regs[13] = call_used_regs[13] - = call_really_used_regs[13] = 1; + fixed_regs[13] = call_used_regs[13] = 1; /* Conditionally disable FPRs. */ if (TARGET_SOFT_FLOAT) for (i = 32; i < 64; i++) - fixed_regs[i] = call_used_regs[i] - = call_really_used_regs[i] = 1; + fixed_regs[i] = call_used_regs[i] = 1; /* The TOC register is not killed across calls in a way that is visible to the compiler. */ if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) - call_really_used_regs[2] = 0; + call_used_regs[2] = 0; if (DEFAULT_ABI == ABI_V4 && flag_pic == 2) fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1; if (DEFAULT_ABI == ABI_V4 && flag_pic == 1) fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] - = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] - = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1; + = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1; if (DEFAULT_ABI == ABI_DARWIN && flag_pic) fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] - = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] - = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1; + = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1; if (TARGET_TOC && TARGET_MINIMAL_TOC) - fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] - = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1; + fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1; if (!TARGET_ALTIVEC && !TARGET_VSX) { for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i) - fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1; - call_really_used_regs[VRSAVE_REGNO] = 1; + fixed_regs[i] = call_used_regs[i] = 1; + call_used_regs[VRSAVE_REGNO] = 1; } if (TARGET_ALTIVEC || TARGET_VSX) @@ -8948,12 +8943,12 @@ rs6000_conditional_register_usage (void) if (TARGET_ALTIVEC_ABI) { for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i) - call_used_regs[i] = call_really_used_regs[i] = 1; + call_used_regs[i] = 1; /* AIX reserves VR20:31 in non-extended ABI mode. */ if (TARGET_XCOFF) for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i) - fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1; + fixed_regs[i] = call_used_regs[i] = 1; } } diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 9c11a3e..8f5c70e 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -882,31 +882,6 @@ enum data_align { align_abi, align_opt, align_both }; 1, 1, 1 \ } -/* 1 for registers not available across function calls. - These must include the FIXED_REGISTERS and also any - registers that can be used without being saved. - The latter must include the registers where values are returned - and the register where structure-value addresses are passed. - Aside from that, you can include as many other registers as you like. */ - -#define CALL_USED_REGISTERS \ - {/* GPRs */ \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, FIXED_R13, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - /* FPRs */ \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - /* VRs */ \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - /* lr ctr ca ap */ \ - 1, 1, 1, 1, \ - /* cr0..cr7 */ \ - 1, 1, 0, 0, 0, 1, 1, 1, \ - /* vrsave vscr sfp */ \ - 1, 1, 1 \ -} - /* Like `CALL_USED_REGISTERS' except this macro doesn't require that the entire set of `FIXED_REGISTERS' be included. (`CALL_USED_REGISTERS' must be a superset of `FIXED_REGISTERS'). diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 93e77d1..cfdfa4e 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -9416,7 +9416,7 @@ s390_regs_ever_clobbered (char regs_ever_clobbered[]) if (!crtl->is_leaf) { for (i = 0; i < 32; i++) - regs_ever_clobbered[i] = call_really_used_regs[i]; + regs_ever_clobbered[i] = call_used_regs[i]; } /* Make the "magic" eh_return registers live if necessary. For regs_ever_live @@ -9438,7 +9438,7 @@ s390_regs_ever_clobbered (char regs_ever_clobbered[]) reload. */ if (crtl->saves_all_registers) for (i = 0; i < 32; i++) - if (!call_really_used_regs[i]) + if (!call_used_regs[i]) regs_ever_clobbered[i] = 1; FOR_EACH_BB_FN (cur_bb, cfun) @@ -9552,7 +9552,7 @@ s390_register_info_gprtofpr () /* Advance to the next FP register which can be used as a GPR save slot. */ - while ((!call_really_used_regs[save_reg_slot] + while ((!call_used_regs[save_reg_slot] || df_regs_ever_live_p (save_reg_slot) || cfun_fpr_save_p (save_reg_slot)) && FP_REGNO_P (save_reg_slot)) @@ -9711,7 +9711,7 @@ s390_register_info () cfun_frame_layout.fpr_bitmap = 0; cfun_frame_layout.high_fprs = 0; for (i = FPR0_REGNUM; i <= FPR15_REGNUM; i++) - if (clobbered_regs[i] && !call_really_used_regs[i]) + if (clobbered_regs[i] && !call_used_regs[i]) { cfun_set_fpr_save (i); if (i >= FPR8_REGNUM) @@ -10269,7 +10269,7 @@ s390_hard_regno_rename_ok (unsigned int old_reg, unsigned int new_reg) df_regs_ever_live. Since we have our own routine we have to tell regrename manually about it. */ if (GENERAL_REGNO_P (new_reg) - && !call_really_used_regs[new_reg] + && !call_used_regs[new_reg] && cfun_gpr_save_slot (new_reg) == SAVE_SLOT_NONE) return false; @@ -10284,7 +10284,7 @@ s390_hard_regno_scratch_ok (unsigned int regno) { /* See s390_hard_regno_rename_ok. */ if (GENERAL_REGNO_P (regno) - && !call_really_used_regs[regno] + && !call_used_regs[regno] && cfun_gpr_save_slot (regno) == SAVE_SLOT_NONE) return false; @@ -11129,10 +11129,10 @@ s390_emit_prologue (void) /* If f4 and f6 are call clobbered they are saved due to stdargs and therefore are not frame related. */ - if (!call_really_used_regs[i]) + if (!call_used_regs[i]) RTX_FRAME_RELATED_P (insn) = 1; } - else if (!TARGET_PACKED_STACK || call_really_used_regs[i]) + else if (!TARGET_PACKED_STACK || call_used_regs[i]) offset += 8; } @@ -11585,7 +11585,7 @@ static void s300_set_up_by_prologue (hard_reg_set_container *regs) { if (cfun->machine->base_reg - && !call_really_used_regs[REGNO (cfun->machine->base_reg)]) + && !call_used_regs[REGNO (cfun->machine->base_reg)]) SET_HARD_REG_BIT (regs->set, REGNO (cfun->machine->base_reg)); } @@ -11786,7 +11786,7 @@ s390_can_use_return_insn (void) return false; if (cfun->machine->base_reg - && !call_really_used_regs[REGNO (cfun->machine->base_reg)]) + && !call_used_regs[REGNO (cfun->machine->base_reg)]) return false; return cfun_frame_layout.frame_size == 0; @@ -13543,36 +13543,31 @@ s390_conditional_register_usage (void) int i; if (flag_pic) - { - fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; - call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; - } + fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; fixed_regs[BASE_REGNUM] = 0; - call_used_regs[BASE_REGNUM] = 0; fixed_regs[RETURN_REGNUM] = 0; - call_used_regs[RETURN_REGNUM] = 0; if (TARGET_64BIT) { for (i = FPR8_REGNUM; i <= FPR15_REGNUM; i++) - call_used_regs[i] = call_really_used_regs[i] = 0; + call_used_regs[i] = 0; } else { - call_used_regs[FPR4_REGNUM] = call_really_used_regs[FPR4_REGNUM] = 0; - call_used_regs[FPR6_REGNUM] = call_really_used_regs[FPR6_REGNUM] = 0; + call_used_regs[FPR4_REGNUM] = 0; + call_used_regs[FPR6_REGNUM] = 0; } if (TARGET_SOFT_FLOAT) { for (i = FPR0_REGNUM; i <= FPR15_REGNUM; i++) - call_used_regs[i] = fixed_regs[i] = 1; + fixed_regs[i] = 1; } /* Disable v16 - v31 for non-vector target. */ if (!TARGET_VX) { for (i = VR16_REGNUM; i <= VR31_REGNUM; i++) - fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1; + fixed_regs[i] = call_used_regs[i] = 1; } } @@ -13662,8 +13657,8 @@ s390_optimize_prologue (void) fpr_regno = FP_REGNO_P (src_regno) ? src_regno : dest_regno; /* GPR must be call-saved, FPR must be call-clobbered. */ - if (!call_really_used_regs[fpr_regno] - || call_really_used_regs[gpr_regno]) + if (!call_used_regs[fpr_regno] + || call_used_regs[gpr_regno]) continue; /* It must not happen that what we once saved in an FPR now diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h index 969f58a..2658e95 100644 --- a/gcc/config/s390/s390.h +++ b/gcc/config/s390/s390.h @@ -453,22 +453,6 @@ extern const char *s390_host_detect_local_cpu (int argc, const char **argv); 0, 0, 0, 0, \ 0, 0, 0, 0 } -#define CALL_USED_REGISTERS \ -{ 1, 1, 1, 1, \ - 1, 1, 0, 0, \ - 0, 0, 0, 0, \ - 0, 1, 1, 1, \ - 1, 1, 1, 1, \ - 1, 1, 1, 1, \ - 1, 1, 1, 1, \ - 1, 1, 1, 1, \ - 1, 1, 1, 1, \ - 1, 1, \ - 1, 1, 1, 1, \ - 1, 1, 1, 1, \ - 1, 1, 1, 1, \ - 1, 1, 1, 1 } - #define CALL_REALLY_USED_REGISTERS \ { 1, 1, 1, 1, /* r0 - r15 */ \ 1, 1, 0, 0, \ diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index ef60b8c..e3eea10 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -6703,7 +6703,7 @@ output_stack_adjust (int size, rtx reg, int epilogue_p, to handle this case, so just die when we see it. */ if (epilogue_p < 0 || current_function_interrupt - || ! call_really_used_regs[temp] || fixed_regs[temp]) + || ! call_used_regs[temp] || fixed_regs[temp]) temp = -1; if (temp < 0 && ! current_function_interrupt && epilogue_p >= 0) { @@ -7009,7 +7009,7 @@ calc_live_regs (HARD_REG_SET *live_regs_mask) else if (TARGET_FPU_DOUBLE && TARGET_FMOVD && TARGET_FPU_SINGLE) for (int count = 0, reg = FIRST_FP_REG; reg <= LAST_FP_REG; reg += 2) if (df_regs_ever_live_p (reg) && df_regs_ever_live_p (reg+1) - && (! call_really_used_regs[reg] + && (! call_used_regs[reg] || interrupt_handler) && ++count > 2) { @@ -7040,7 +7040,7 @@ calc_live_regs (HARD_REG_SET *live_regs_mask) : interrupt_handler ? (/* Need to save all the regs ever live. */ (df_regs_ever_live_p (reg) - || (call_really_used_regs[reg] + || (call_used_regs[reg] && (! fixed_regs[reg] || reg == MACH_REG || reg == MACL_REG || reg == PIC_OFFSET_TABLE_REGNUM) && has_call)) @@ -7053,7 +7053,7 @@ calc_live_regs (HARD_REG_SET *live_regs_mask) : (/* Only push those regs which are used and need to be saved. */ (false) || (df_regs_ever_live_p (reg) - && ((!call_really_used_regs[reg] + && ((!call_used_regs[reg] && !(reg != PIC_OFFSET_TABLE_REGNUM && fixed_regs[reg] && call_used_or_fixed_reg_p (reg))) @@ -8289,7 +8289,7 @@ sh_fix_range (const char *const_str) } for (int i = first; i <= last; ++i) - fixed_regs[i] = call_used_regs[i] = 1; + fixed_regs[i] = 1; if (!comma) break; @@ -8809,7 +8809,7 @@ reg_unused_after (rtx reg, rtx_insn *insn) if (set == NULL && reg_overlap_mentioned_p (reg, PATTERN (insn))) return false; - if (code == CALL_INSN && call_really_used_regs[REGNO (reg)]) + if (code == CALL_INSN && call_used_regs[REGNO (reg)]) return true; } return true; @@ -11447,32 +11447,28 @@ sh_conditional_register_usage (void) { for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno ++) if (! VALID_REGISTER_P (regno)) - fixed_regs[regno] = call_used_regs[regno] = 1; + fixed_regs[regno] = 1; /* R8 and R9 are call-clobbered on SH5, but not on earlier SH ABIs. */ if (flag_pic) - { - fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; - call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; - } + fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; if (TARGET_FDPIC) { fixed_regs[PIC_REG] = 1; call_used_regs[PIC_REG] = 1; - call_really_used_regs[PIC_REG] = 1; } /* Renesas saves and restores mac registers on call. */ if (TARGET_HITACHI && ! TARGET_NOMACSAVE) { - call_really_used_regs[MACH_REG] = 0; - call_really_used_regs[MACL_REG] = 0; + call_used_regs[MACH_REG] = 0; + call_used_regs[MACL_REG] = 0; } for (int regno = FIRST_GENERAL_REG; regno <= LAST_GENERAL_REG; regno++) - if (! fixed_regs[regno] && call_really_used_regs[regno]) + if (! fixed_regs[regno] && call_used_regs[regno]) SET_HARD_REG_BIT (reg_class_contents[SIBCALL_REGS], regno); - call_really_used_regs[FPSCR_MODES_REG] = 0; - call_really_used_regs[FPSCR_STAT_REG] = 0; + call_used_regs[FPSCR_MODES_REG] = 0; + call_used_regs[FPSCR_STAT_REG] = 0; } /* Implement TARGET_LEGITIMATE_CONSTANT_P diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h index 0204872..3e38488 100644 --- a/gcc/config/sh/sh.h +++ b/gcc/config/sh/sh.h @@ -732,45 +732,6 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \ 1, 1, 1, 1, \ } -/* 1 for registers not available across function calls. - These must include the FIXED_REGISTERS and also any - registers that can be used without being saved. - The latter must include the registers where values are returned - and the register where structure-value addresses are passed. - Aside from that, you can include as many other registers as you like. */ -#define CALL_USED_REGISTERS \ -{ \ -/* Regular registers. */ \ - 1, 1, 1, 1, 1, 1, 1, 1, \ - /* R8 and R9 are call-clobbered on SH5, but not on earlier SH ABIs. \ - Only the lower 32bits of R10-R14 are guaranteed to be preserved \ - across SH5 function calls. */ \ - 0, 0, 0, 0, 0, 0, 0, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 0, 0, 0, 0, \ - 0, 0, 0, 0, 1, 1, 1, 1, \ - 1, 1, 1, 1, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 1, 1, 1, 1, \ -/* FP registers. */ \ - 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 0, 0, 0, 0, \ - 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, \ -/* Branch target registers. */ \ - 1, 1, 1, 1, 1, 0, 0, 0, \ -/* XD registers. */ \ - 1, 1, 1, 1, 1, 1, 0, 0, \ -/*"gbr", "ap", "pr", "t", "mach", "macl", "fpul", "fpscr", */ \ - 1, 1, 1, 1, 1, 1, 1, 1, \ -/*"rap", "sfp","fpscr0","fpscr1" */ \ - 1, 1, 1, 1, \ -} - /* CALL_REALLY_USED_REGISTERS is used as a default setting, which is then overridden by -fcall-saved-* and -fcall-used-* options and then by TARGET_CONDITIONAL_REGISTER_USAGE. There we might want to make a diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 43c6dd5..fe5e941 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -13008,10 +13008,7 @@ static void sparc_conditional_register_usage (void) { if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) - { - fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; - call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; - } + fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; /* If the user has passed -f{fixed,call-{used,saved}}-g5 */ /* then honor it. */ if (TARGET_ARCH32 && fixed_regs[5]) diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 2dd765b..defcba8 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -678,31 +678,6 @@ along with GCC; see the file COPYING3. If not see 0, 0, 0, 0, 1, 1, 1} /* 1 for registers not available across function calls. - These must include the FIXED_REGISTERS and also any - registers that can be used without being saved. - The latter must include the registers where values are returned - and the register where structure-value addresses are passed. - Aside from that, you can include as many other registers as you like. */ - -#define CALL_USED_REGISTERS \ - {1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, \ - 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 1, \ - \ - 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, \ - \ - 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, \ - \ - 1, 1, 1, 1, 1, 1, 1} - -/* 1 for registers not available across function calls. Unlike the above, this need not include the FIXED_REGISTERS, but any registers that can be used without being saved. The latter must include the registers where values are returned diff --git a/gcc/config/tilegx/tilegx.c b/gcc/config/tilegx/tilegx.c index f2ea9bb..59c3859 100644 --- a/gcc/config/tilegx/tilegx.c +++ b/gcc/config/tilegx/tilegx.c @@ -4341,20 +4341,11 @@ static void tilegx_conditional_register_usage (void) { global_regs[TILEGX_NETORDER_REGNUM] = 1; - /* TILEGX_PIC_TEXT_LABEL_REGNUM is conditionally used. It is a - member of fixed_regs, and therefore must be member of - call_used_regs, but it is not a member of call_really_used_regs[] - because it is not clobbered by a call. */ + /* TILEGX_PIC_TEXT_LABEL_REGNUM is conditionally used. */ if (TILEGX_PIC_TEXT_LABEL_REGNUM != INVALID_REGNUM) - { - fixed_regs[TILEGX_PIC_TEXT_LABEL_REGNUM] = 1; - call_used_regs[TILEGX_PIC_TEXT_LABEL_REGNUM] = 1; - } + fixed_regs[TILEGX_PIC_TEXT_LABEL_REGNUM] = 1; if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) - { - fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; - call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; - } + fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; } diff --git a/gcc/config/tilegx/tilegx.h b/gcc/config/tilegx/tilegx.h index 2645043..de3f9f6 100644 --- a/gcc/config/tilegx/tilegx.h +++ b/gcc/config/tilegx/tilegx.h @@ -114,16 +114,13 @@ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1} -#define CALL_USED_REGISTERS \ +#define CALL_REALLY_USED_REGISTERS \ {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1} -#define CALL_REALLY_USED_REGISTERS \ - CALL_USED_REGISTERS - #define REG_ALLOC_ORDER { \ 10, 11, 12, 13, 14, /* call used */ \ 15, 16, 17, 18, 19, \ diff --git a/gcc/config/tilepro/tilepro.c b/gcc/config/tilepro/tilepro.c index a1d59b1..1a5c883 100644 --- a/gcc/config/tilepro/tilepro.c +++ b/gcc/config/tilepro/tilepro.c @@ -3864,20 +3864,11 @@ static void tilepro_conditional_register_usage (void) { global_regs[TILEPRO_NETORDER_REGNUM] = 1; - /* TILEPRO_PIC_TEXT_LABEL_REGNUM is conditionally used. It is a - member of fixed_regs, and therefore must be member of - call_used_regs, but it is not a member of call_really_used_regs[] - because it is not clobbered by a call. */ + /* TILEPRO_PIC_TEXT_LABEL_REGNUM is conditionally used. */ if (TILEPRO_PIC_TEXT_LABEL_REGNUM != INVALID_REGNUM) - { - fixed_regs[TILEPRO_PIC_TEXT_LABEL_REGNUM] = 1; - call_used_regs[TILEPRO_PIC_TEXT_LABEL_REGNUM] = 1; - } + fixed_regs[TILEPRO_PIC_TEXT_LABEL_REGNUM] = 1; if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) - { - fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; - call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; - } + fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; } diff --git a/gcc/config/tilepro/tilepro.h b/gcc/config/tilepro/tilepro.h index 507625f..409a727 100644 --- a/gcc/config/tilepro/tilepro.h +++ b/gcc/config/tilepro/tilepro.h @@ -79,16 +79,13 @@ 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1} -#define CALL_USED_REGISTERS \ +#define CALL_REALLY_USED_REGISTERS \ {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1} -#define CALL_REALLY_USED_REGISTERS \ - CALL_USED_REGISTERS - #define REG_ALLOC_ORDER { \ 10, 11, 12, 13, 14, /* call used */ \ 15, 16, 17, 18, 19, \ diff --git a/gcc/config/visium/visium.c b/gcc/config/visium/visium.c index 367e1e5..8477008 100644 --- a/gcc/config/visium/visium.c +++ b/gcc/config/visium/visium.c @@ -754,20 +754,20 @@ visium_conditional_register_usage (void) { if (visium_cpu_and_features == PROCESSOR_GR5) { - fixed_regs[24] = call_used_regs[24] = 1; - fixed_regs[25] = call_used_regs[25] = 1; - fixed_regs[26] = call_used_regs[26] = 1; - fixed_regs[27] = call_used_regs[27] = 1; - fixed_regs[28] = call_used_regs[28] = 1; - call_really_used_regs[24] = 0; - call_really_used_regs[25] = 0; - call_really_used_regs[26] = 0; - call_really_used_regs[27] = 0; - call_really_used_regs[28] = 0; + fixed_regs[24] = 1; + fixed_regs[25] = 1; + fixed_regs[26] = 1; + fixed_regs[27] = 1; + fixed_regs[28] = 1; + call_used_regs[24] = 0; + call_used_regs[25] = 0; + call_used_regs[26] = 0; + call_used_regs[27] = 0; + call_used_regs[28] = 0; } - fixed_regs[31] = call_used_regs[31] = 1; - call_really_used_regs[31] = 0; + fixed_regs[31] = 1; + call_used_regs[31] = 0; /* We also need to change the long-branch register. */ if (visium_cpu_and_features == PROCESSOR_GR5) @@ -781,8 +781,8 @@ visium_conditional_register_usage (void) { for (int i = FP_FIRST_REGNUM; i <= FP_LAST_REGNUM; i++) { - fixed_regs[i] = call_used_regs[i] = 1; - call_really_used_regs[i] = 0; + fixed_regs[i] = 1; + call_used_regs[i] = 0; } } } diff --git a/gcc/config/visium/visium.h b/gcc/config/visium/visium.h index c9376b2..0d7ae0f 100644 --- a/gcc/config/visium/visium.h +++ b/gcc/config/visium/visium.h @@ -488,27 +488,6 @@ 0, 0, 0, 0, 0, 0, 0, 0, /* f8 .. f15 */ \ 1, 1, 1 } /* flags, arg, frame */ -/* `CALL_USED_REGISTERS' - - Like `FIXED_REGISTERS' but has 1 for each register that is - clobbered (in general) by function calls as well as for fixed - registers. This macro therefore identifies the registers that are - not available for general allocation of values that must live - across function calls. - - If a register has 0 in `CALL_USED_REGISTERS', the compiler - automatically saves it on function entry and restores it on - function exit, if the register is used within the function. */ -#define CALL_USED_REGISTERS \ - { 1, 1, 1, 1, 1, 1, 1, 1, /* r0 .. r7 */ \ - 1, 1, 1, 0, 0, 0, 0, 0, /* r8 .. r15 */ \ - 0, 0, 0, 0, 1, 1, 0, 1, /* r16 .. r23 */ \ - 1, 1, 1, 1, 1, 1, 1, 1, /* r24 .. r31 */ \ - 1, 1, /* mdb, mdc */ \ - 1, 1, 1, 1, 1, 1, 1, 1, /* f0 .. f7 */ \ - 1, 0, 0, 0, 0, 0, 0, 0, /* f8 .. f15 */ \ - 1, 1, 1 } /* flags, arg, frame */ - /* Like `CALL_USED_REGISTERS' except this macro doesn't require that the entire set of `FIXED_REGISTERS' be included. (`CALL_USED_REGISTERS' must be a superset of `FIXED_REGISTERS'). diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 7bb8157..159ccd2 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -1878,6 +1878,9 @@ function calls. If a register has 0 in @code{CALL_USED_REGISTERS}, the compiler automatically saves it on function entry and restores it on function exit, if the register is used within the function. + +Exactly one of @code{CALL_USED_REGISTERS} and @code{CALL_REALLY_USED_REGISTERS} +must be defined. Modern ports should define @code{CALL_REALLY_USED_REGISTERS}. @end defmac @defmac CALL_REALLY_USED_REGISTERS @@ -1887,8 +1890,9 @@ exit, if the register is used within the function. Like @code{CALL_USED_REGISTERS} except this macro doesn't require that the entire set of @code{FIXED_REGISTERS} be included. (@code{CALL_USED_REGISTERS} must be a superset of @code{FIXED_REGISTERS}). -This macro is optional. If not specified, it defaults to the value -of @code{CALL_USED_REGISTERS}. + +Exactly one of @code{CALL_USED_REGISTERS} and @code{CALL_REALLY_USED_REGISTERS} +must be defined. Modern ports should define @code{CALL_REALLY_USED_REGISTERS}. @end defmac @cindex call-used register diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index e926c10..91a2d2b 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -1689,6 +1689,9 @@ function calls. If a register has 0 in @code{CALL_USED_REGISTERS}, the compiler automatically saves it on function entry and restores it on function exit, if the register is used within the function. + +Exactly one of @code{CALL_USED_REGISTERS} and @code{CALL_REALLY_USED_REGISTERS} +must be defined. Modern ports should define @code{CALL_REALLY_USED_REGISTERS}. @end defmac @defmac CALL_REALLY_USED_REGISTERS @@ -1698,8 +1701,9 @@ exit, if the register is used within the function. Like @code{CALL_USED_REGISTERS} except this macro doesn't require that the entire set of @code{FIXED_REGISTERS} be included. (@code{CALL_USED_REGISTERS} must be a superset of @code{FIXED_REGISTERS}). -This macro is optional. If not specified, it defaults to the value -of @code{CALL_USED_REGISTERS}. + +Exactly one of @code{CALL_USED_REGISTERS} and @code{CALL_REALLY_USED_REGISTERS} +must be defined. Modern ports should define @code{CALL_REALLY_USED_REGISTERS}. @end defmac @cindex call-used register diff --git a/gcc/hard-reg-set.h b/gcc/hard-reg-set.h index 654e0d6..a54c167 100644 --- a/gcc/hard-reg-set.h +++ b/gcc/hard-reg-set.h @@ -395,8 +395,6 @@ struct target_hard_regs { a pseudo reg whose life crosses calls. */ char x_call_used_regs[FIRST_PSEUDO_REGISTER]; - char x_call_really_used_regs[FIRST_PSEUDO_REGISTER]; - /* For targets that use reload rather than LRA, this is the set of registers that we are able to save and restore around calls (i.e. those for which we know a suitable mode and set of @@ -477,8 +475,6 @@ extern struct target_hard_regs *this_target_hard_regs; #define call_used_regs \ (this_target_hard_regs->x_call_used_regs) #endif -#define call_really_used_regs \ - (this_target_hard_regs->x_call_really_used_regs) #define savable_regs \ (this_target_hard_regs->x_savable_regs) #define regs_invalidated_by_call \ diff --git a/gcc/reginfo.c b/gcc/reginfo.c index e860def..22d0e68 100644 --- a/gcc/reginfo.c +++ b/gcc/reginfo.c @@ -73,17 +73,13 @@ struct target_regs *this_target_regs = &default_target_regs; static const char initial_fixed_regs[] = FIXED_REGISTERS; /* Data for initializing call_used_regs. */ -static const char initial_call_used_regs[] = CALL_USED_REGISTERS; - #ifdef CALL_REALLY_USED_REGISTERS -/* Data for initializing call_really_used_regs. */ -static const char initial_call_really_used_regs[] = CALL_REALLY_USED_REGISTERS; +#ifdef CALL_USED_REGISTERS +#error CALL_USED_REGISTERS and CALL_REALLY_USED_REGISTERS are both defined #endif - -#ifdef CALL_REALLY_USED_REGISTERS -#define CALL_REALLY_USED_REGNO_P(X) call_really_used_regs[X] +static const char initial_call_used_regs[] = CALL_REALLY_USED_REGISTERS; #else -#define CALL_REALLY_USED_REGNO_P(X) call_used_regs[X] +static const char initial_call_used_regs[] = CALL_USED_REGISTERS; #endif /* Indexed by hard register number, contains 1 for registers @@ -164,10 +160,6 @@ init_reg_sets (void) CALL_USED_REGISTERS had the right number of initializers. */ gcc_assert (sizeof fixed_regs == sizeof initial_fixed_regs); gcc_assert (sizeof call_used_regs == sizeof initial_call_used_regs); -#ifdef CALL_REALLY_USED_REGISTERS - gcc_assert (sizeof call_really_used_regs - == sizeof initial_call_really_used_regs); -#endif #ifdef REG_ALLOC_ORDER gcc_assert (sizeof reg_alloc_order == sizeof initial_reg_alloc_order); #endif @@ -175,10 +167,6 @@ init_reg_sets (void) memcpy (fixed_regs, initial_fixed_regs, sizeof fixed_regs); memcpy (call_used_regs, initial_call_used_regs, sizeof call_used_regs); -#ifdef CALL_REALLY_USED_REGISTERS - memcpy (call_really_used_regs, initial_call_really_used_regs, - sizeof call_really_used_regs); -#endif #ifdef REG_ALLOC_ORDER memcpy (reg_alloc_order, initial_reg_alloc_order, sizeof reg_alloc_order); #endif @@ -193,9 +181,6 @@ init_reg_sets (void) subsequent back-end reinitialization. */ static char saved_fixed_regs[FIRST_PSEUDO_REGISTER]; static char saved_call_used_regs[FIRST_PSEUDO_REGISTER]; -#ifdef CALL_REALLY_USED_REGISTERS -static char saved_call_really_used_regs[FIRST_PSEUDO_REGISTER]; -#endif static const char *saved_reg_names[FIRST_PSEUDO_REGISTER]; static HARD_REG_SET saved_accessible_reg_set; static HARD_REG_SET saved_operand_reg_set; @@ -211,14 +196,6 @@ save_register_info (void) memcpy (saved_fixed_regs, fixed_regs, sizeof fixed_regs); memcpy (saved_call_used_regs, call_used_regs, sizeof call_used_regs); - /* Likewise for call_really_used_regs. */ -#ifdef CALL_REALLY_USED_REGISTERS - gcc_assert (sizeof call_really_used_regs - == sizeof saved_call_really_used_regs); - memcpy (saved_call_really_used_regs, call_really_used_regs, - sizeof call_really_used_regs); -#endif - /* And similarly for reg_names. */ gcc_assert (sizeof reg_names == sizeof saved_reg_names); memcpy (saved_reg_names, reg_names, sizeof reg_names); @@ -233,11 +210,6 @@ restore_register_info (void) memcpy (fixed_regs, saved_fixed_regs, sizeof fixed_regs); memcpy (call_used_regs, saved_call_used_regs, sizeof call_used_regs); -#ifdef CALL_REALLY_USED_REGISTERS - memcpy (call_really_used_regs, saved_call_really_used_regs, - sizeof call_really_used_regs); -#endif - memcpy (reg_names, saved_reg_names, sizeof reg_names); accessible_reg_set = saved_accessible_reg_set; operand_reg_set = saved_operand_reg_set; @@ -371,17 +343,7 @@ init_reg_sets_1 (void) /* If a register is too limited to be treated as a register operand, then it should never be allocated to a pseudo. */ if (!TEST_HARD_REG_BIT (operand_reg_set, i)) - { - fixed_regs[i] = 1; - call_used_regs[i] = 1; - } - - /* call_used_regs must include fixed_regs. */ - gcc_assert (!fixed_regs[i] || call_used_regs[i]); -#ifdef CALL_REALLY_USED_REGISTERS - /* call_used_regs must include call_really_used_regs. */ - gcc_assert (!call_really_used_regs[i] || call_used_regs[i]); -#endif + fixed_regs[i] = 1; if (fixed_regs[i]) SET_HARD_REG_BIT (fixed_reg_set, i); @@ -411,7 +373,7 @@ init_reg_sets_1 (void) else if (!PIC_OFFSET_TABLE_REG_CALL_CLOBBERED && i == (unsigned) PIC_OFFSET_TABLE_REGNUM && fixed_regs[i]) ; - else if (CALL_REALLY_USED_REGNO_P (i)) + else if (call_used_regs[i]) SET_HARD_REG_BIT (regs_invalidated_by_call, i); } @@ -713,10 +675,11 @@ fix_register (const char *name, int fixed, int call_used) else { fixed_regs[i] = fixed; - call_used_regs[i] = call_used; #ifdef CALL_REALLY_USED_REGISTERS if (fixed == 0) - call_really_used_regs[i] = call_used; + call_used_regs[i] = call_used; +#else + call_used_regs[i] = call_used; #endif } } @@ -772,9 +735,6 @@ globalize_reg (tree decl, int i) return; fixed_regs[i] = call_used_regs[i] = 1; -#ifdef CALL_REALLY_USED_REGISTERS - call_really_used_regs[i] = 1; -#endif SET_HARD_REG_BIT (fixed_reg_set, i); -- cgit v1.1 From a1fc3891ebb77c1bdf68ce70c074eb907d21771a Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 10 Sep 2019 20:25:32 +0000 Subject: go/internal/gccgoimporter: support embedded field in pointer loop Backport of https://golang.org/cl/194440. Original description: If an embedded field refers to a type via a pointer, the parser needs to know the name of the embedded field. It is possible that the pointer type is not yet resolved. This CL fixes the parser to handle that case by setting the pointer element type to the unresolved named type while the pointer is being resolved. Updates golang/go#34182 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/194562 From-SVN: r275606 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 183dac5..5591c1d 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -68038b4fdf1456482af986cb05dcf3121bd43ffc +556451586b10584e4778694c84b03d0ecbbab150 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From 4d7bfeec428c5bfd005bb6028221c22e5a8abcdf Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 10 Sep 2019 20:32:20 +0000 Subject: re PR go/91621 (libgo/mksysinfo.sh: please avoid test ==) PR go/91621 mksysinfo: change test == to test = Fixes https://gcc.gnu.org/PR91621 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/194569 From-SVN: r275608 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 5591c1d..0c9b3ff 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -556451586b10584e4778694c84b03d0ecbbab150 +2f6dd921a21351e94f55a5365a3176af563b5945 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From efc864927f57fa1a4aa8d1f22e4071343f0b8cbb Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 10 Sep 2019 20:41:04 +0000 Subject: libgo: Solaris and x/sys/cpu compatibility fixes Restore Solaris compatibility fixes lost when internal/x/net/lif moved to golang.org/x/net/lif. Also fix the Makefile for x/net/lif and x/net/route. Change x/sys/cpu to get the cache line size from goarch.sh as the gofrontend version of internal/cpu does. Partially based on work by Rainer Orth. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/194438 From-SVN: r275611 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 0c9b3ff..61845bc 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -2f6dd921a21351e94f55a5365a3176af563b5945 +bf4832d604e7522dee78fca76de220b62a131d54 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From d85569f63db86e656ecb79b81c74a906f27bf509 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Tue, 10 Sep 2019 21:04:33 +0000 Subject: PR c++/91705 - constexpr evaluation rejects ++/-- on floats. * constexpr.c (cxx_eval_increment_expression): Call fold_simple on the offset. * g++.dg/cpp1y/constexpr-incr2.C: New test. From-SVN: r275613 --- gcc/cp/ChangeLog | 6 +++ gcc/cp/constexpr.c | 4 ++ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/g++.dg/cpp1y/constexpr-incr2.C | 66 ++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-incr2.C (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2c48829..15b1fbf 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2019-09-10 Marek Polacek + + PR c++/91705 - constexpr evaluation rejects ++/-- on floats. + * constexpr.c (cxx_eval_increment_expression): Call fold_simple on + the offset. + 2019-09-10 Paolo Carlini * decl.c (has_designator_problem): Use cp_expr_loc_or_input_loc diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 6c547d6..58db691 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -4164,6 +4164,10 @@ cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t, tree offset = TREE_OPERAND (t, 1); gcc_assert (TREE_CONSTANT (offset)); + /* OFFSET is constant, but perhaps not constant enough. We need to + e.g. bash FLOAT_EXPRs to REAL_CSTs. */ + offset = fold_simple (offset); + /* The operand as an lvalue. */ op = cxx_eval_constant_expression (ctx, op, true, non_constant_p, overflow_p); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c8779bb..464765d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-10 Marek Polacek + + PR c++/91705 - constexpr evaluation rejects ++/-- on floats. + * g++.dg/cpp1y/constexpr-incr2.C: New test. + 2019-09-10 David Edelsohn * gfortran.dg/default_format_1.f90: Remove XFAIL AIX. diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-incr2.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-incr2.C new file mode 100644 index 0000000..0d22851 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-incr2.C @@ -0,0 +1,66 @@ +// PR c++/91705 - constexpr evaluation rejects ++/-- on floats. +// { dg-do compile { target c++14 } } + +#define SA(X) static_assert((X),#X) + +template +constexpr T fn1(T t) +{ + return ++t; +} + +constexpr float fn2(float t) +{ + return ++t; +} + +template +constexpr T fn3(T t) +{ + return --t; +} + +constexpr float fn4(float t) +{ + return --t; +} + +template +constexpr T fn5(T t) +{ + return t++; +} + +constexpr float fn6(float t) +{ + return t++; +} + +template +constexpr T fn7(T t) +{ + return t--; +} + +constexpr float fn8(float t) +{ + return t--; +} + +constexpr double r1 = fn1(2.0f); +SA(r1 == 3); +constexpr double r2 = fn2(2.0f); +SA(r2 == 3); +constexpr double r3 = fn3(2.0f); +SA(r3 == 1); +constexpr double r4 = fn4(2.0f); +SA(r4 == 1); + +constexpr double r5 = fn5(2.0f); +SA(r5 == 2); +constexpr double r6 = fn6(2.0f); +SA(r6 == 2); +constexpr double r7 = fn7(2.0f); +SA(r7 == 2); +constexpr double r8 = fn8(2.0f); +SA(r8 == 2); -- cgit v1.1 From 480c18e16fd69998266850b804024a7559f1bc70 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Tue, 10 Sep 2019 23:22:37 +0000 Subject: PR c++/91673 - ICE with noexcept in alias-declaration. * parser.c (CP_PARSER_FLAGS_DELAY_NOEXCEPT): New parser flag. (cp_parser_lambda_declarator_opt): Pass CP_PARSER_FLAGS_NONE to cp_parser_exception_specification_opt. (cp_parser_direct_declarator): Adjust a call to cp_parser_exception_specification_opt. (cp_parser_member_declaration): Pass CP_PARSER_FLAGS_DELAY_NOEXCEPT to cp_parser_declarator if not processing a friend or typedef declaration. (cp_parser_late_noexcept_specifier): Adjust a call to cp_parser_noexcept_specification_opt. (cp_parser_noexcept_specification_opt): New parameter for parser flags, drop the FRIEND_P parameter. Use the new parameter. (cp_parser_exception_specification_opt): Likewise. (cp_parser_transaction): Adjust a call to cp_parser_noexcept_specification_opt. (cp_parser_transaction_expression): Likewise. * g++.dg/cpp1z/using7.C: New test. * g++.dg/cpp1z/using8.C: New test. From-SVN: r275617 --- gcc/cp/ChangeLog | 20 +++++++++++++ gcc/cp/parser.c | 60 +++++++++++++++++++++---------------- gcc/testsuite/ChangeLog | 6 ++++ gcc/testsuite/g++.dg/cpp1z/using7.C | 33 ++++++++++++++++++++ gcc/testsuite/g++.dg/cpp1z/using8.C | 12 ++++++++ 5 files changed, 105 insertions(+), 26 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1z/using7.C create mode 100644 gcc/testsuite/g++.dg/cpp1z/using8.C (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 15b1fbf..0c37460 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,25 @@ 2019-09-10 Marek Polacek + PR c++/91673 - ICE with noexcept in alias-declaration. + * parser.c (CP_PARSER_FLAGS_DELAY_NOEXCEPT): New parser flag. + (cp_parser_lambda_declarator_opt): Pass CP_PARSER_FLAGS_NONE to + cp_parser_exception_specification_opt. + (cp_parser_direct_declarator): Adjust a call to + cp_parser_exception_specification_opt. + (cp_parser_member_declaration): Pass CP_PARSER_FLAGS_DELAY_NOEXCEPT + to cp_parser_declarator if not processing a friend or typedef + declaration. + (cp_parser_late_noexcept_specifier): Adjust a call to + cp_parser_noexcept_specification_opt. + (cp_parser_noexcept_specification_opt): New parameter for parser flags, + drop the FRIEND_P parameter. Use the new parameter. + (cp_parser_exception_specification_opt): Likewise. + (cp_parser_transaction): Adjust a call to + cp_parser_noexcept_specification_opt. + (cp_parser_transaction_expression): Likewise. + +2019-09-10 Marek Polacek + PR c++/91705 - constexpr evaluation rejects ++/-- on floats. * constexpr.c (cxx_eval_increment_expression): Call fold_simple on the offset. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index baa60b8..254a77b 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -247,8 +247,6 @@ static void cp_lexer_stop_debugging static cp_token_cache *cp_token_cache_new (cp_token *, cp_token *); -static tree cp_parser_noexcept_specification_opt - (cp_parser *, bool, bool *, bool, bool); static tree cp_parser_late_noexcept_specifier (cp_parser *, tree); static void noexcept_override_late_checks @@ -1830,7 +1828,9 @@ enum /* When parsing a decl-specifier-seq, only allow mutable or constexpr. */ CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR = 0x10, /* When parsing a decl-specifier-seq, allow missing typename. */ - CP_PARSER_FLAGS_TYPENAME_OPTIONAL = 0x20 + CP_PARSER_FLAGS_TYPENAME_OPTIONAL = 0x20, + /* When parsing of the noexcept-specifier should be delayed. */ + CP_PARSER_FLAGS_DELAY_NOEXCEPT = 0x40 }; /* This type is used for parameters and variables which hold @@ -2380,7 +2380,7 @@ static void cp_parser_explicit_instantiation static void cp_parser_explicit_specialization (cp_parser *); -/* Exception handling [gram.exception] */ +/* Exception handling [gram.except] */ static tree cp_parser_try_block (cp_parser *); @@ -2395,9 +2395,11 @@ static tree cp_parser_exception_declaration static tree cp_parser_throw_expression (cp_parser *); static tree cp_parser_exception_specification_opt - (cp_parser *, bool = false); + (cp_parser *, cp_parser_flags); static tree cp_parser_type_id_list (cp_parser *); +static tree cp_parser_noexcept_specification_opt + (cp_parser *, cp_parser_flags, bool, bool *, bool); /* GNU Extensions */ @@ -10938,7 +10940,8 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr) tx_qual = cp_parser_tx_qualifier_opt (parser); /* Parse optional exception specification. */ - exception_spec = cp_parser_exception_specification_opt (parser); + exception_spec + = cp_parser_exception_specification_opt (parser, CP_PARSER_FLAGS_NONE); std_attrs = cp_parser_std_attribute_spec_seq (parser); @@ -20877,7 +20880,7 @@ cp_parser_direct_declarator (cp_parser* parser, tree tx_qual = cp_parser_tx_qualifier_opt (parser); /* And the exception-specification. */ exception_specification - = cp_parser_exception_specification_opt (parser, friend_p); + = cp_parser_exception_specification_opt (parser, flags); attrs = cp_parser_std_attribute_spec_seq (parser); @@ -24780,11 +24783,15 @@ cp_parser_member_declaration (cp_parser* parser) tree asm_specification; int ctor_dtor_or_conv_p; bool static_p = (decl_specifiers.storage_class == sc_static); + cp_parser_flags flags = CP_PARSER_FLAGS_TYPENAME_OPTIONAL; + if (!friend_p + && !decl_spec_seq_has_spec_p (&decl_specifiers, ds_typedef)) + flags |= CP_PARSER_FLAGS_DELAY_NOEXCEPT; /* Parse the declarator. */ declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED, - CP_PARSER_FLAGS_TYPENAME_OPTIONAL, + flags, &ctor_dtor_or_conv_p, /*parenthesized_p=*/NULL, /*member_p=*/true, @@ -25359,10 +25366,10 @@ cp_parser_late_noexcept_specifier (cp_parser *parser, tree default_arg) /* Parse the cached noexcept-specifier. */ tree parsed_arg = cp_parser_noexcept_specification_opt (parser, + CP_PARSER_FLAGS_NONE, /*require_constexpr=*/true, /*consumed_expr=*/NULL, - /*return_cond=*/false, - /*friend_p=*/false); + /*return_cond=*/false); /* Revert to the main lexer. */ cp_parser_pop_lexer (parser); @@ -25411,15 +25418,15 @@ noexcept_override_late_checks (tree type, tree fndecl) expression if parentheses follow noexcept, or return BOOLEAN_TRUE_NODE if there are no parentheses. CONSUMED_EXPR will be set accordingly. Otherwise, returns a noexcept specification unless RETURN_COND is true, - in which case a boolean condition is returned instead. If FRIEND_P is true, - the function with this noexcept-specification had the `friend' specifier. */ + in which case a boolean condition is returned instead. The parser flags + FLAGS is used to control parsing. */ static tree cp_parser_noexcept_specification_opt (cp_parser* parser, + cp_parser_flags flags, bool require_constexpr, bool* consumed_expr, - bool return_cond, - bool friend_p) + bool return_cond) { cp_token *token; const char *saved_message; @@ -25446,8 +25453,10 @@ cp_parser_noexcept_specification_opt (cp_parser* parser, /* No need to delay parsing for a number literal or true/false. */ && !literal_p && at_class_scope_p () - /* Don't delay parsing for friend member functions. */ - && !friend_p + /* We don't delay parsing for friend member functions, + alias-declarations, and typedefs, even though the standard seems + to require it. */ + && (flags & CP_PARSER_FLAGS_DELAY_NOEXCEPT) && TYPE_BEING_DEFINED (current_class_type) && !LAMBDA_TYPE_P (current_class_type)) return cp_parser_save_noexcept (parser); @@ -25522,11 +25531,11 @@ cp_parser_noexcept_specification_opt (cp_parser* parser, throw ( type-id-list [opt] ) Returns a TREE_LIST representing the exception-specification. The - TREE_VALUE of each node is a type. If FRIEND_P is true, the function - with this noexcept-specification had the `friend' specifier. */ + TREE_VALUE of each node is a type. The parser flags FLAGS is used to + control parsing. */ static tree -cp_parser_exception_specification_opt (cp_parser* parser, bool friend_p) +cp_parser_exception_specification_opt (cp_parser* parser, cp_parser_flags flags) { cp_token *token; tree type_id_list; @@ -25537,11 +25546,10 @@ cp_parser_exception_specification_opt (cp_parser* parser, bool friend_p) /* Is it a noexcept-specification? */ type_id_list - = cp_parser_noexcept_specification_opt (parser, + = cp_parser_noexcept_specification_opt (parser, flags, /*require_constexpr=*/true, /*consumed_expr=*/NULL, - /*return_cond=*/false, - friend_p); + /*return_cond=*/false); if (type_id_list != NULL_TREE) return type_id_list; @@ -41162,10 +41170,10 @@ cp_parser_transaction (cp_parser *parser, cp_token *token) } else noex = cp_parser_noexcept_specification_opt (parser, + CP_PARSER_FLAGS_NONE, /*require_constexpr=*/true, /*consumed_expr=*/NULL, - /*return_cond=*/true, - /*friend_p=*/false); + /*return_cond=*/true); /* Keep track if we're in the lexical scope of an outer transaction. */ new_in = this_in | (old_in & TM_STMT_ATTR_OUTER); @@ -41226,10 +41234,10 @@ cp_parser_transaction_expression (cp_parser *parser, enum rid keyword) /* Parse a noexcept specification. */ noex = cp_parser_noexcept_specification_opt (parser, + CP_PARSER_FLAGS_NONE, /*require_constexpr=*/false, &noex_expr, - /*return_cond=*/true, - /*friend_p=*/false); + /*return_cond=*/true); if (!noex || !noex_expr || cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 464765d..bbb5d95 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,11 @@ 2019-09-10 Marek Polacek + PR c++/91673 - ICE with noexcept in alias-declaration. + * g++.dg/cpp1z/using7.C: New test. + * g++.dg/cpp1z/using8.C: New test. + +2019-09-10 Marek Polacek + PR c++/91705 - constexpr evaluation rejects ++/-- on floats. * g++.dg/cpp1y/constexpr-incr2.C: New test. diff --git a/gcc/testsuite/g++.dg/cpp1z/using7.C b/gcc/testsuite/g++.dg/cpp1z/using7.C new file mode 100644 index 0000000..f22ac45 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/using7.C @@ -0,0 +1,33 @@ +// PR c++/91673 - ICE with noexcept in alias-declaration. +// { dg-do compile { target c++17 } } + +template +using U1 = T() noexcept(B); + +template +struct S { + int I; + static constexpr bool b = true; + + template + using U2 = T() noexcept(B); + + template + using U8 = T() noexcept(b); + + template + using U10 = T(int p) noexcept(noexcept(p)); + + template + using U11 = T() noexcept(B2); + + using U3 = void() noexcept(B); + using U9 = void() noexcept(b); + using U4 = void() noexcept(noexcept (I)); + using U5 = void(int p) noexcept(noexcept(p)); + + typedef void(*T1)() noexcept(B); + typedef void(*T2)(int p) noexcept(noexcept(p)); +}; + +S s; diff --git a/gcc/testsuite/g++.dg/cpp1z/using8.C b/gcc/testsuite/g++.dg/cpp1z/using8.C new file mode 100644 index 0000000..c3e1a06 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/using8.C @@ -0,0 +1,12 @@ +// PR c++/91673 - ICE with noexcept in alias-declaration. +// { dg-do compile { target c++17 } } + +template +struct overload; + +template +struct overload { + using signature_t = Ret(Args...) noexcept(NoExcept); +}; + +overload x; -- cgit v1.1 From f62592f99de0048dc8a3a62f67a29b65e95e118b Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Wed, 11 Sep 2019 00:16:38 +0000 Subject: Daily bump. From-SVN: r275622 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 757af50..0766c00 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20190910 +20190911 -- cgit v1.1 From dc5b11916a2e318bd15d60f6cfd01d1e306ffbfb Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 11 Sep 2019 08:22:51 +0000 Subject: revert: match.pd: Add flag_unsafe_math_optimizations check before deciding on the widest type in... 2019-09-11 Richard Biener Revert 2019-09-09 Barnaby Wilks * match.pd: Add flag_unsafe_math_optimizations check before deciding on the widest type in a binary math operation. * gcc.dg/fold-binary-math-casts.c: New test. From-SVN: r275632 --- gcc/ChangeLog | 8 ++++ gcc/match.pd | 12 +----- gcc/testsuite/ChangeLog | 7 ++++ gcc/testsuite/gcc.dg/fold-binary-math-casts.c | 58 --------------------------- 4 files changed, 17 insertions(+), 68 deletions(-) delete mode 100644 gcc/testsuite/gcc.dg/fold-binary-math-casts.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a0badf5..0aa93bc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2019-09-11 Richard Biener + + Revert + 2019-09-09 Barnaby Wilks + + * match.pd: Add flag_unsafe_math_optimizations check + before deciding on the widest type in a binary math operation. + 2019-09-10 Richard Sandiford * doc/tm.texi.in: Document that exactly one of CALL_USED_REGISTERS diff --git a/gcc/match.pd b/gcc/match.pd index 309a094..05009bb 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -5056,18 +5056,10 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && newtype == type && types_match (newtype, type)) (op (convert:newtype @1) (convert:newtype @2)) - (with - { - if (!flag_unsafe_math_optimizations) - { - if (TYPE_PRECISION (ty1) > TYPE_PRECISION (newtype)) + (with { if (TYPE_PRECISION (ty1) > TYPE_PRECISION (newtype)) newtype = ty1; - if (TYPE_PRECISION (ty2) > TYPE_PRECISION (newtype)) - newtype = ty2; - } - } - + newtype = ty2; } /* Sometimes this transformation is safe (cannot change results through affecting double rounding cases) and sometimes it is not. If NEWTYPE is diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bbb5d95..8b3dfbb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2019-09-11 Richard Biener + + Revert + 2019-09-09 Barnaby Wilks + + * gcc.dg/fold-binary-math-casts.c: New test. + 2019-09-10 Marek Polacek PR c++/91673 - ICE with noexcept in alias-declaration. diff --git a/gcc/testsuite/gcc.dg/fold-binary-math-casts.c b/gcc/testsuite/gcc.dg/fold-binary-math-casts.c deleted file mode 100644 index 53c247f..0000000 --- a/gcc/testsuite/gcc.dg/fold-binary-math-casts.c +++ /dev/null @@ -1,58 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-Ofast -fdump-tree-optimized" } */ - -#include - -float -f (float x, float y) -{ - double z = 1.0 / x; - return z * y; -} - -float -g (float x, float y) -{ - double a = 1.0 / x; - double b = 1.0 / y; - long double k = x*x*x*x*x*x; - - return a + b - k; -} - -float -h (float x) -{ - double a = x * 2.0; - double b = a / 3.5f; - return a + b; -} - -float -i (float y, float z) -{ - return pow (y, 2.0) / (double) (y + z); -} - -float -j (float x, float y) -{ - double t = 4.0 * x; - double z = t + y; - return z; -} - -float -k (float a) -{ - return 1.0 / sqrtf (a); -} - -float -l (float a) -{ - return (double) a * (a / 2.0); -} - -/* { dg-final { scan-tree-dump-not "\\(double\\)" "optimized" } } */ -/* { dg-final { scan-tree-dump-not "\\(float\\)" "optimized" } } */ -- cgit v1.1 From 6d5093dad6a4927d23a914300605e76dd00c7a15 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 11 Sep 2019 10:33:55 +0200 Subject: re PR middle-end/91725 (ICE in get_nonzero_bits starting with r275587) PR middle-end/91725 * match.pd ((A / (1 << B)) -> (A >> B)): Call tree_nonzero_bits instead of get_nonzero_bits, only call it for integral types. * gcc.c-torture/compile/pr91725.c: New test. From-SVN: r275633 --- gcc/ChangeLog | 6 ++++++ gcc/match.pd | 8 +++++--- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.c-torture/compile/pr91725.c | 7 +++++++ 4 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr91725.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0aa93bc..360e606 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-09-11 Jakub Jelinek + + PR middle-end/91725 + * match.pd ((A / (1 << B)) -> (A >> B)): Call tree_nonzero_bits instead + of get_nonzero_bits, only call it for integral types. + 2019-09-11 Richard Biener Revert diff --git a/gcc/match.pd b/gcc/match.pd index 05009bb..5690cf3 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -325,9 +325,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && (TYPE_UNSIGNED (TREE_TYPE (@1)) || (element_precision (type) == element_precision (TREE_TYPE (@1))) - || (get_nonzero_bits (@0) - & wi::mask (element_precision (TREE_TYPE (@1)) - 1, true, - element_precision (type))) == 0)))) + || (INTEGRAL_TYPE_P (type) + && (tree_nonzero_bits (@0) + & wi::mask (element_precision (TREE_TYPE (@1)) - 1, + true, + element_precision (type))) == 0))))) (rshift @0 @2))) /* Preserve explicit divisions by 0: the C++ front-end wants to detect diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8b3dfbb..8ef8062 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-11 Jakub Jelinek + + PR middle-end/91725 + * gcc.c-torture/compile/pr91725.c: New test. + 2019-09-11 Richard Biener Revert diff --git a/gcc/testsuite/gcc.c-torture/compile/pr91725.c b/gcc/testsuite/gcc.c-torture/compile/pr91725.c new file mode 100644 index 0000000..f614a1c --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr91725.c @@ -0,0 +1,7 @@ +/* PR middle-end/91725 */ + +unsigned long long +foo (unsigned long long x, unsigned long long y, int z) +{ + return (x + y) / (1 << z); +} -- cgit v1.1 From 26d815a3e587ac04dbd63eec3fb5aecb04db7242 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 11 Sep 2019 10:34:41 +0200 Subject: re PR tree-optimization/91723 (builtin fma is not optimized or vectorized as *+) PR tree-optimization/91723 * tree-vect-stmts.c (vectorizable_call): Use types_compatible_p check instead of pointer equality when checking if argument vectypes are the same. * gcc.dg/vect/vect-fma-3.c: New test. From-SVN: r275634 --- gcc/ChangeLog | 5 +++++ gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/gcc.dg/vect/vect-fma-3.c | 17 +++++++++++++++++ gcc/tree-vect-stmts.c | 2 +- 4 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/vect/vect-fma-3.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 360e606..33b4386 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2019-09-11 Jakub Jelinek + PR tree-optimization/91723 + * tree-vect-stmts.c (vectorizable_call): Use types_compatible_p check + instead of pointer equality when checking if argument vectypes are + the same. + PR middle-end/91725 * match.pd ((A / (1 << B)) -> (A >> B)): Call tree_nonzero_bits instead of get_nonzero_bits, only call it for integral types. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8ef8062..d4488b6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2019-09-11 Jakub Jelinek + PR tree-optimization/91723 + * gcc.dg/vect/vect-fma-3.c: New test. + PR middle-end/91725 * gcc.c-torture/compile/pr91725.c: New test. diff --git a/gcc/testsuite/gcc.dg/vect/vect-fma-3.c b/gcc/testsuite/gcc.dg/vect/vect-fma-3.c new file mode 100644 index 0000000..b231a32 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-fma-3.c @@ -0,0 +1,17 @@ +/* PR tree-optimization/91723 */ +/* { dg-do compile { target { scalar_all_fma || { i?86-*-* x86_64-*-* } } } } */ +/* { dg-additional-options "-mfma" { target { i?86-*-* x86_64-*-* } } } */ + +void +foo (double *restrict r, const double *restrict a, + const double *restrict b, const double *restrict c) +{ + for (int i = 0; i < 1024; i++) + { + double x = __builtin_fma (a[i], b[i], c[i]); + x = __builtin_fma (a[i], b[i], x); + r[i] = x; + } +} + +/* { dg-final { scan-tree-dump-times "LOOP VECTORIZED" 1 "vect" { target vect_double } } } */ diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index dd9d45a..edc7e0d 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -3308,7 +3308,7 @@ vectorizable_call (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, if (!vectype_in) vectype_in = vectypes[i]; else if (vectypes[i] - && vectypes[i] != vectype_in) + && !types_compatible_p (vectypes[i], vectype_in)) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, -- cgit v1.1 From 0a237a94c206b53eb73baad2d75fbcca518df65e Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Wed, 11 Sep 2019 10:41:27 +0000 Subject: re PR rtl-optimization/89795 (wrong code with -O2 -fno-dce -fno-forward-propagate -fno-sched-pressure) PR rtl-optimization/89795 * rtlanal.c (nonzero_bits1) : Do not propagate results from inner REGs to paradoxical SUBREGs if WORD_REGISTER_OPERATIONS is set. From-SVN: r275635 --- gcc/ChangeLog | 6 ++++++ gcc/rtlanal.c | 2 +- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.target/sparc/20161111-1.c | 2 +- 4 files changed, 12 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 33b4386..3452012 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-09-11 Eric Botcazou + + PR rtl-optimization/89795 + * rtlanal.c (nonzero_bits1) : Do not propagate results from + inner REGs to paradoxical SUBREGs if WORD_REGISTER_OPERATIONS is set. + 2019-09-11 Jakub Jelinek PR tree-optimization/91723 diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 1fbbeda..3a72db7 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -4819,7 +4819,7 @@ nonzero_bits1 (const_rtx x, scalar_int_mode mode, const_rtx known_x, || ((extend_op = load_extend_op (inner_mode)) == SIGN_EXTEND ? val_signbit_known_set_p (inner_mode, nonzero) : extend_op != ZERO_EXTEND) - || (!MEM_P (SUBREG_REG (x)) && !REG_P (SUBREG_REG (x)))) + || !MEM_P (SUBREG_REG (x))) && xmode_width > inner_width) nonzero |= (GET_MODE_MASK (GET_MODE (x)) & ~GET_MODE_MASK (inner_mode)); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d4488b6..cd9821e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-09-11 Eric Botcazou + + * gcc.target/sparc/20161111-1.c: XFAIL redundant zero-extension test. + 2019-09-11 Jakub Jelinek PR tree-optimization/91723 diff --git a/gcc/testsuite/gcc.target/sparc/20161111-1.c b/gcc/testsuite/gcc.target/sparc/20161111-1.c index eda8b0a..8195fec 100644 --- a/gcc/testsuite/gcc.target/sparc/20161111-1.c +++ b/gcc/testsuite/gcc.target/sparc/20161111-1.c @@ -14,4 +14,4 @@ unsigned char ee_isdigit2(unsigned int i) return retval; } -/* { dg-final { scan-assembler-not "and\t%" } } */ +/* { dg-final { scan-assembler-not "and\t%" { xfail *-*-* } } } */ -- cgit v1.1 From 46dfa8ad6c18feb45d35734eae38798edb7c38cd Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 11 Sep 2019 11:16:54 +0000 Subject: re PR tree-optimization/90387 (__builtin_constant_p and -Warray-bounds warnings) 2019-09-11 Richard Biener PR tree-optimization/90387 * vr-values.c (vr_values::extract_range_basic): After inlining simplify non-constant __builtin_constant_p to false. * gcc.dg/Warray-bounds-44.c: New testcase. From-SVN: r275639 --- gcc/ChangeLog | 6 ++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/Warray-bounds-44.c | 23 +++++++++++++++++++++++ gcc/vr-values.c | 11 ++--------- 4 files changed, 36 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-44.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3452012..21c247b8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-09-11 Richard Biener + + PR tree-optimization/90387 + * vr-values.c (vr_values::extract_range_basic): After inlining + simplify non-constant __builtin_constant_p to false. + 2019-09-11 Eric Botcazou PR rtl-optimization/89795 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cd9821e..940be7f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-11 Richard Biener + + PR tree-optimization/90387 + * gcc.dg/Warray-bounds-44.c: New testcase. + 2019-09-11 Eric Botcazou * gcc.target/sparc/20161111-1.c: XFAIL redundant zero-extension test. diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-44.c b/gcc/testsuite/gcc.dg/Warray-bounds-44.c new file mode 100644 index 0000000..709d004 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-44.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Warray-bounds" } */ + +int foo(unsigned int state, unsigned char * p, unsigned int p_len) +{ + static char const pattern[] = "abcd"; + static unsigned const pattern_length = sizeof(pattern) - 1; + + if (p_len == 1) { + return state; + } + + if (state < pattern_length && + p_len == (pattern_length - state) && + (!__builtin_constant_p(p_len) ? + __builtin_memcmp(p, pattern + state, p_len) : + ((unsigned char*)p)[6] == ((unsigned char*)pattern + state)[6] /* { dg-bogus "array bounds" } */ + )) { + + return 4; + } + return 1; +} diff --git a/gcc/vr-values.c b/gcc/vr-values.c index 256cae7..0ebb6e3 100644 --- a/gcc/vr-values.c +++ b/gcc/vr-values.c @@ -1124,15 +1124,8 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) switch (cfn) { case CFN_BUILT_IN_CONSTANT_P: - /* If the call is __builtin_constant_p and the argument is a - function parameter resolve it to false. This avoids bogus - array bound warnings. - ??? We could do this as early as inlining is finished. */ - arg = gimple_call_arg (stmt, 0); - if (TREE_CODE (arg) == SSA_NAME - && SSA_NAME_IS_DEFAULT_DEF (arg) - && TREE_CODE (SSA_NAME_VAR (arg)) == PARM_DECL - && cfun->after_inlining) + /* Resolve calls to __builtin_constant_p after inlining. */ + if (cfun->after_inlining) { vr->set_zero (type); vr->equiv_clear (); -- cgit v1.1 From 5a307ee54bca63865b6e5e8ad690720adf0b9d78 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 11 Sep 2019 11:20:35 +0000 Subject: lto-opts.c (lto_write_options): Stream -g when debug is enabled. 2019-09-11 Richard Biener * lto-opts.c (lto_write_options): Stream -g when debug is enabled. * lto-wrapper.c (merge_and_complain): Pick up -g. (append_compiler_options): Likewise. (run_gcc): Re-instantiate handling -g0 at link-time. * doc/invoke.texi (flto): Document debug info generation. From-SVN: r275640 --- gcc/ChangeLog | 8 ++++++++ gcc/doc/invoke.texi | 8 ++++++++ gcc/lto-opts.c | 4 ++++ gcc/lto-wrapper.c | 6 ++++++ 4 files changed, 26 insertions(+) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 21c247b8..85bb9ba 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 2019-09-11 Richard Biener + * lto-opts.c (lto_write_options): Stream -g when debug is enabled. + * lto-wrapper.c (merge_and_complain): Pick up -g. + (append_compiler_options): Likewise. + (run_gcc): Re-instantiate handling -g0 at link-time. + * doc/invoke.texi (flto): Document debug info generation. + +2019-09-11 Richard Biener + PR tree-optimization/90387 * vr-values.c (vr_values::extract_range_basic): After inlining simplify non-constant __builtin_constant_p to false. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 234c1b7..6e91a66 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -10339,6 +10339,14 @@ conflicting translation units. Specifically precedence; and for example @option{-ffp-contract=off} takes precedence over @option{-ffp-contract=fast}. You can override them at link time. +To enable debug info generation you need to supply @option{-g} at +compile-time. If any of the input files at link time were built +with debug info generation enabled the link will enable debug info +generation as well. Any elaborate debug info settings +like the dwarf level @option{-gdwarf-5} need to be explicitely repeated +at the linker command line and mixing different settings in different +translation units is discouraged. + If LTO encounters objects with C linkage declared with incompatible types in separate translation units to be linked together (undefined behavior according to ISO C99 6.2.7), a non-fatal diagnostic may be diff --git a/gcc/lto-opts.c b/gcc/lto-opts.c index 494d9c2..0e9f24e 100644 --- a/gcc/lto-opts.c +++ b/gcc/lto-opts.c @@ -94,6 +94,10 @@ lto_write_options (void) : "-fno-pie"); } + /* If debug info is enabled append -g. */ + if (debug_info_level > DINFO_LEVEL_NONE) + append_to_collect_gcc_options (&temporary_obstack, &first_p, "-g"); + /* Append options from target hook and store them to offload_lto section. */ if (lto_stream_offload_p) { diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c index 5423adb..9a7bbd0 100644 --- a/gcc/lto-wrapper.c +++ b/gcc/lto-wrapper.c @@ -265,6 +265,7 @@ merge_and_complain (struct cl_decoded_option **decoded_options, case OPT_fshow_column: case OPT_fcommon: case OPT_fgnu_tm: + case OPT_g: /* Do what the old LTO code did - collect exactly one option setting per OPT code, we pick the first we encounter. ??? This doesn't make too much sense, but when it doesn't @@ -617,6 +618,7 @@ append_compiler_options (obstack *argv_obstack, struct cl_decoded_option *opts, case OPT_fopenacc: case OPT_fopenacc_dim_: case OPT_foffload_abi_: + case OPT_g: case OPT_O: case OPT_Ofast: case OPT_Og: @@ -1399,6 +1401,10 @@ run_gcc (unsigned argc, char *argv[]) linker_output_rel = !strcmp (option->arg, "rel"); break; + case OPT_g: + /* Recognize -g0. */ + skip_debug = option->arg && !strcmp (option->arg, "0"); + break; default: break; -- cgit v1.1 From 7994803c00a3aba210f76d3b61c53300c549969d Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Wed, 11 Sep 2019 11:28:00 +0000 Subject: [PATCH] some tree struct marking https://gcc.gnu.org/ml/gcc-patches/2019-09/msg00697.html gcc/ * tree.h (MARK_TS_TYPE_NON_COMMON): New. * tree.c (tree_node_structure_for_code): Reformat and alphabetize. gcc/cp/ * c-objcp-common.c (cp-objcp-common.c): Alphababetize and correctly mark all C++ nodes. From-SVN: r275641 --- gcc/ChangeLog | 5 ++ gcc/cp/ChangeLog | 6 ++ gcc/cp/cp-objcp-common.c | 153 +++++++++++++++++++++++++---------------------- gcc/cp/decl.c | 16 ++--- gcc/tree.c | 82 +++++++++++-------------- gcc/tree.h | 4 ++ 6 files changed, 140 insertions(+), 126 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 85bb9ba..608f3b9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-09-11 Nathan Sidwell + + * tree.h (MARK_TS_TYPE_NON_COMMON): New. + * tree.c (tree_node_structure_for_code): Reformat and alphabetize. + 2019-09-11 Richard Biener * lto-opts.c (lto_write_options): Stream -g when debug is enabled. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0c37460..8f266a2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2019-09-11 Nathan Sidwell + + * c-objcp-common.c (cp-objcp-common.c): Alphababetize and + correctly mark all C++ nodes. + * decl.c (cp_tree_node_structure): Alphabetize. + 2019-09-10 Marek Polacek PR c++/91673 - ICE with noexcept in alias-declaration. diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c index 4c95180..4369a5b 100644 --- a/gcc/cp/cp-objcp-common.c +++ b/gcc/cp/cp-objcp-common.c @@ -365,104 +365,113 @@ cp_register_dumps (gcc::dump_manager *dumps) void cp_common_init_ts (void) { - MARK_TS_DECL_NON_COMMON (USING_DECL); - MARK_TS_DECL_COMMON (TEMPLATE_DECL); - MARK_TS_DECL_COMMON (WILDCARD_DECL); + /* With type. */ + MARK_TS_TYPED (PTRMEM_CST); + MARK_TS_TYPED (LAMBDA_EXPR); + MARK_TS_TYPED (TYPE_ARGUMENT_PACK); - MARK_TS_COMMON (TEMPLATE_TEMPLATE_PARM); - MARK_TS_COMMON (TEMPLATE_TYPE_PARM); - MARK_TS_COMMON (TEMPLATE_PARM_INDEX); + /* Random new trees. */ + MARK_TS_COMMON (BASELINK); + MARK_TS_COMMON (DECLTYPE_TYPE); MARK_TS_COMMON (OVERLOAD); + MARK_TS_COMMON (TEMPLATE_PARM_INDEX); MARK_TS_COMMON (TYPENAME_TYPE); MARK_TS_COMMON (TYPEOF_TYPE); - MARK_TS_COMMON (UNDERLYING_TYPE); - MARK_TS_COMMON (BASELINK); - MARK_TS_COMMON (TYPE_PACK_EXPANSION); - MARK_TS_COMMON (TYPE_ARGUMENT_PACK); - MARK_TS_COMMON (DECLTYPE_TYPE); - MARK_TS_COMMON (BOUND_TEMPLATE_TEMPLATE_PARM); MARK_TS_COMMON (UNBOUND_CLASS_TEMPLATE); + MARK_TS_COMMON (UNDERLYING_TYPE); - MARK_TS_TYPED (SWITCH_STMT); - MARK_TS_TYPED (IF_STMT); - MARK_TS_TYPED (FOR_STMT); - MARK_TS_TYPED (RANGE_FOR_STMT); - MARK_TS_TYPED (EH_SPEC_BLOCK); - MARK_TS_TYPED (CLEANUP_STMT); - MARK_TS_TYPED (SCOPE_REF); - MARK_TS_TYPED (TRY_BLOCK); - MARK_TS_TYPED (HANDLER); - MARK_TS_TYPED (TYPE_ARGUMENT_PACK); - MARK_TS_TYPED (NOEXCEPT_EXPR); - MARK_TS_TYPED (WHILE_STMT); - MARK_TS_TYPED (BREAK_STMT); - MARK_TS_TYPED (DO_STMT); - MARK_TS_TYPED (CONTINUE_STMT); - MARK_TS_TYPED (PTRMEM_CST); - MARK_TS_TYPED (USING_STMT); - MARK_TS_TYPED (OMP_DEPOBJ); + /* New decls. */ + MARK_TS_DECL_COMMON (TEMPLATE_DECL); + MARK_TS_DECL_COMMON (WILDCARD_DECL); + + MARK_TS_DECL_NON_COMMON (USING_DECL); + /* New Types. */ + MARK_TS_TYPE_NON_COMMON (BOUND_TEMPLATE_TEMPLATE_PARM); + MARK_TS_TYPE_NON_COMMON (TEMPLATE_TEMPLATE_PARM); + MARK_TS_TYPE_NON_COMMON (TEMPLATE_TYPE_PARM); + MARK_TS_TYPE_NON_COMMON (TYPE_ARGUMENT_PACK); + MARK_TS_TYPE_NON_COMMON (TYPE_PACK_EXPANSION); + + /* Statements. */ + MARK_TS_EXP (BREAK_STMT); + MARK_TS_EXP (CLEANUP_STMT); + MARK_TS_EXP (CONTINUE_STMT); + MARK_TS_EXP (DO_STMT); + MARK_TS_EXP (EH_SPEC_BLOCK); + MARK_TS_EXP (FOR_STMT); + MARK_TS_EXP (HANDLER); + MARK_TS_EXP (IF_STMT); + MARK_TS_EXP (OMP_DEPOBJ); + MARK_TS_EXP (RANGE_FOR_STMT); + MARK_TS_EXP (SWITCH_STMT); + MARK_TS_EXP (TRY_BLOCK); + MARK_TS_EXP (USING_STMT); + MARK_TS_EXP (WHILE_STMT); + + /* Random expressions. */ + MARK_TS_EXP (ADDRESSOF_EXPR); MARK_TS_EXP (AGGR_INIT_EXPR); + MARK_TS_EXP (ALIGNOF_EXPR); + MARK_TS_EXP (ARROW_EXPR); + MARK_TS_EXP (AT_ENCODE_EXPR); + MARK_TS_EXP (CAST_EXPR); + MARK_TS_EXP (CONST_CAST_EXPR); MARK_TS_EXP (CTOR_INITIALIZER); - MARK_TS_EXP (EXPR_STMT); - MARK_TS_EXP (TAG_DEFN); + MARK_TS_EXP (DELETE_EXPR); + MARK_TS_EXP (DOTSTAR_EXPR); + MARK_TS_EXP (DYNAMIC_CAST_EXPR); MARK_TS_EXP (EMPTY_CLASS_EXPR); + MARK_TS_EXP (EXPR_STMT); + MARK_TS_EXP (IMPLICIT_CONV_EXPR); + MARK_TS_EXP (MEMBER_REF); MARK_TS_EXP (MODOP_EXPR); - MARK_TS_EXP (THROW_EXPR); - MARK_TS_EXP (CAST_EXPR); - MARK_TS_EXP (TYPE_EXPR); + MARK_TS_EXP (MUST_NOT_THROW_EXPR); + MARK_TS_EXP (NEW_EXPR); + MARK_TS_EXP (NOEXCEPT_EXPR); + MARK_TS_EXP (NON_DEPENDENT_EXPR); + MARK_TS_EXP (OFFSETOF_EXPR); + MARK_TS_EXP (OFFSET_REF); + MARK_TS_EXP (PSEUDO_DTOR_EXPR); MARK_TS_EXP (REINTERPRET_CAST_EXPR); - MARK_TS_EXP (CONST_CAST_EXPR); + MARK_TS_EXP (SCOPE_REF); MARK_TS_EXP (STATIC_CAST_EXPR); - MARK_TS_EXP (DYNAMIC_CAST_EXPR); - MARK_TS_EXP (IMPLICIT_CONV_EXPR); + MARK_TS_EXP (STMT_EXPR); + MARK_TS_EXP (TAG_DEFN); MARK_TS_EXP (TEMPLATE_ID_EXPR); - MARK_TS_EXP (ARROW_EXPR); - MARK_TS_EXP (UNARY_PLUS_EXPR); + MARK_TS_EXP (THROW_EXPR); MARK_TS_EXP (TRAIT_EXPR); - - MARK_TS_EXP (NON_DEPENDENT_EXPR); - MARK_TS_EXP (NEW_EXPR); - MARK_TS_EXP (VEC_NEW_EXPR); - MARK_TS_EXP (MEMBER_REF); - MARK_TS_EXP (DOTSTAR_EXPR); - MARK_TS_EXP (DELETE_EXPR); - MARK_TS_EXP (VEC_DELETE_EXPR); - MARK_TS_EXP (PSEUDO_DTOR_EXPR); MARK_TS_EXP (TYPEID_EXPR); - MARK_TS_EXP (MUST_NOT_THROW_EXPR); - MARK_TS_EXP (STMT_EXPR); - MARK_TS_EXP (OFFSET_REF); - MARK_TS_EXP (OFFSETOF_EXPR); - MARK_TS_EXP (ADDRESSOF_EXPR); + MARK_TS_EXP (TYPE_EXPR); + MARK_TS_EXP (UNARY_PLUS_EXPR); + MARK_TS_EXP (VEC_DELETE_EXPR); MARK_TS_EXP (VEC_INIT_EXPR); - MARK_TS_EXP (LAMBDA_EXPR); - - MARK_TS_EXP (ALIGNOF_EXPR); - MARK_TS_EXP (AT_ENCODE_EXPR); + MARK_TS_EXP (VEC_NEW_EXPR); - MARK_TS_EXP (NONTYPE_ARGUMENT_PACK); + /* Fold expressions. */ + MARK_TS_EXP (BINARY_LEFT_FOLD_EXPR); + MARK_TS_EXP (BINARY_RIGHT_FOLD_EXPR); MARK_TS_EXP (EXPR_PACK_EXPANSION); + MARK_TS_EXP (NONTYPE_ARGUMENT_PACK); MARK_TS_EXP (UNARY_LEFT_FOLD_EXPR); MARK_TS_EXP (UNARY_RIGHT_FOLD_EXPR); - MARK_TS_EXP (BINARY_LEFT_FOLD_EXPR); - MARK_TS_EXP (BINARY_RIGHT_FOLD_EXPR); - MARK_TS_EXP (REQUIRES_EXPR); - MARK_TS_EXP (SIMPLE_REQ); - MARK_TS_EXP (TYPE_REQ); - MARK_TS_EXP (COMPOUND_REQ); - MARK_TS_EXP (NESTED_REQ); - MARK_TS_EXP (PRED_CONSTR); + /* Constraints. */ MARK_TS_EXP (CHECK_CONSTR); - MARK_TS_EXP (EXPR_CONSTR); - MARK_TS_EXP (TYPE_CONSTR); - MARK_TS_EXP (ICONV_CONSTR); + MARK_TS_EXP (COMPOUND_REQ); + MARK_TS_EXP (CONJ_CONSTR); MARK_TS_EXP (DEDUCT_CONSTR); + MARK_TS_EXP (DISJ_CONSTR); MARK_TS_EXP (EXCEPT_CONSTR); + MARK_TS_EXP (EXPR_CONSTR); + MARK_TS_EXP (ICONV_CONSTR); + MARK_TS_EXP (NESTED_REQ); MARK_TS_EXP (PARM_CONSTR); - MARK_TS_EXP (CONJ_CONSTR); - MARK_TS_EXP (DISJ_CONSTR); + MARK_TS_EXP (PRED_CONSTR); + MARK_TS_EXP (REQUIRES_EXPR); + MARK_TS_EXP (SIMPLE_REQ); + MARK_TS_EXP (TYPE_CONSTR); + MARK_TS_EXP (TYPE_REQ); c_common_init_ts (); } diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 8bb398b..9218eef 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -16827,20 +16827,20 @@ cp_tree_node_structure (union lang_tree_node * t) { switch (TREE_CODE (&t->generic)) { - case DEFERRED_PARSE: return TS_CP_DEFERRED_PARSE; + case ARGUMENT_PACK_SELECT: return TS_CP_ARGUMENT_PACK_SELECT; + case BASELINK: return TS_CP_BASELINK; + case CONSTRAINT_INFO: return TS_CP_CONSTRAINT_INFO; case DEFERRED_NOEXCEPT: return TS_CP_DEFERRED_NOEXCEPT; + case DEFERRED_PARSE: return TS_CP_DEFERRED_PARSE; case IDENTIFIER_NODE: return TS_CP_IDENTIFIER; + case LAMBDA_EXPR: return TS_CP_LAMBDA_EXPR; case OVERLOAD: return TS_CP_OVERLOAD; - case TEMPLATE_PARM_INDEX: return TS_CP_TPI; case PTRMEM_CST: return TS_CP_PTRMEM; - case BASELINK: return TS_CP_BASELINK; - case TEMPLATE_DECL: return TS_CP_TEMPLATE_DECL; case STATIC_ASSERT: return TS_CP_STATIC_ASSERT; - case ARGUMENT_PACK_SELECT: return TS_CP_ARGUMENT_PACK_SELECT; - case TRAIT_EXPR: return TS_CP_TRAIT_EXPR; - case LAMBDA_EXPR: return TS_CP_LAMBDA_EXPR; + case TEMPLATE_DECL: return TS_CP_TEMPLATE_DECL; case TEMPLATE_INFO: return TS_CP_TEMPLATE_INFO; - case CONSTRAINT_INFO: return TS_CP_CONSTRAINT_INFO; + case TEMPLATE_PARM_INDEX: return TS_CP_TPI; + case TRAIT_EXPR: return TS_CP_TRAIT_EXPR; case USERDEF_LITERAL: return TS_CP_USERDEF_LITERAL; default: return TS_CP_GENERIC; } diff --git a/gcc/tree.c b/gcc/tree.c index afd7020..6be756c 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -455,71 +455,61 @@ tree_node_structure_for_code (enum tree_code code) switch (TREE_CODE_CLASS (code)) { case tcc_declaration: - { - switch (code) - { - case FIELD_DECL: - return TS_FIELD_DECL; - case PARM_DECL: - return TS_PARM_DECL; - case VAR_DECL: - return TS_VAR_DECL; - case LABEL_DECL: - return TS_LABEL_DECL; - case RESULT_DECL: - return TS_RESULT_DECL; - case DEBUG_EXPR_DECL: - return TS_DECL_WRTL; - case CONST_DECL: - return TS_CONST_DECL; - case TYPE_DECL: - return TS_TYPE_DECL; - case FUNCTION_DECL: - return TS_FUNCTION_DECL; - case TRANSLATION_UNIT_DECL: - return TS_TRANSLATION_UNIT_DECL; - default: - return TS_DECL_NON_COMMON; - } - } - case tcc_type: - return TS_TYPE_NON_COMMON; - case tcc_reference: - case tcc_comparison: - case tcc_unary: + switch (code) + { + case CONST_DECL: return TS_CONST_DECL; + case DEBUG_EXPR_DECL: return TS_DECL_WRTL; + case FIELD_DECL: return TS_FIELD_DECL; + case FUNCTION_DECL: return TS_FUNCTION_DECL; + case LABEL_DECL: return TS_LABEL_DECL; + case PARM_DECL: return TS_PARM_DECL; + case RESULT_DECL: return TS_RESULT_DECL; + case TRANSLATION_UNIT_DECL: return TS_TRANSLATION_UNIT_DECL; + case TYPE_DECL: return TS_TYPE_DECL; + case VAR_DECL: return TS_VAR_DECL; + default: return TS_DECL_NON_COMMON; + } + + case tcc_type: return TS_TYPE_NON_COMMON; + case tcc_binary: + case tcc_comparison: case tcc_expression: + case tcc_reference: case tcc_statement: - case tcc_vl_exp: - return TS_EXP; + case tcc_unary: + case tcc_vl_exp: return TS_EXP; + default: /* tcc_constant and tcc_exceptional */ break; } + switch (code) { /* tcc_constant cases. */ - case VOID_CST: return TS_TYPED; + case COMPLEX_CST: return TS_COMPLEX; + case FIXED_CST: return TS_FIXED_CST; case INTEGER_CST: return TS_INT_CST; case POLY_INT_CST: return TS_POLY_INT_CST; case REAL_CST: return TS_REAL_CST; - case FIXED_CST: return TS_FIXED_CST; - case COMPLEX_CST: return TS_COMPLEX; - case VECTOR_CST: return TS_VECTOR; case STRING_CST: return TS_STRING; + case VECTOR_CST: return TS_VECTOR; + case VOID_CST: return TS_TYPED; + /* tcc_exceptional cases. */ - case ERROR_MARK: return TS_COMMON; - case IDENTIFIER_NODE: return TS_IDENTIFIER; - case TREE_LIST: return TS_LIST; - case TREE_VEC: return TS_VEC; - case SSA_NAME: return TS_SSA_NAME; - case PLACEHOLDER_EXPR: return TS_COMMON; - case STATEMENT_LIST: return TS_STATEMENT_LIST; case BLOCK: return TS_BLOCK; case CONSTRUCTOR: return TS_CONSTRUCTOR; - case TREE_BINFO: return TS_BINFO; + case ERROR_MARK: return TS_COMMON; + case IDENTIFIER_NODE: return TS_IDENTIFIER; case OMP_CLAUSE: return TS_OMP_CLAUSE; case OPTIMIZATION_NODE: return TS_OPTIMIZATION; + case PLACEHOLDER_EXPR: return TS_COMMON; + case SSA_NAME: return TS_SSA_NAME; + case STATEMENT_LIST: return TS_STATEMENT_LIST; case TARGET_OPTION_NODE: return TS_TARGET_OPTION; + case TREE_BINFO: return TS_BINFO; + case TREE_LIST: return TS_LIST; + case TREE_VEC: return TS_VEC; default: gcc_unreachable (); diff --git a/gcc/tree.h b/gcc/tree.h index fc85572..3fc36a4 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -94,6 +94,10 @@ as_internal_fn (combined_fn code) (MARK_TS_TYPE_COMMON (C), \ tree_contains_struct[C][TS_TYPE_WITH_LANG_SPECIFIC] = true) +#define MARK_TS_TYPE_NON_COMMON(C) \ + (MARK_TS_TYPE_WITH_LANG_SPECIFIC (C), \ + tree_contains_struct[C][TS_TYPE_NON_COMMON] = true) \ + #define MARK_TS_DECL_MINIMAL(C) \ (MARK_TS_COMMON (C), \ tree_contains_struct[C][TS_DECL_MINIMAL] = true) -- cgit v1.1 From fd3bfefbd93259ca4af64e821388a6ec824fa0dd Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 11 Sep 2019 13:37:39 +0200 Subject: re PR rtl-optimization/89435 (wrong code with -O1 -march=armv4 -fno-forward-propagate with __builtin_sub_overflow()) PR rtl-optimization/89435 PR rtl-optimization/89795 PR rtl-optimization/91720 * gcc.dg/pr89435.c: New test. * gcc.dg/pr89795.c: New test. * gcc.dg/pr91720.c: New test. From-SVN: r275642 --- gcc/testsuite/ChangeLog | 9 +++++++++ gcc/testsuite/gcc.dg/pr89435.c | 21 +++++++++++++++++++++ gcc/testsuite/gcc.dg/pr89795.c | 25 +++++++++++++++++++++++++ gcc/testsuite/gcc.dg/pr91720.c | 22 ++++++++++++++++++++++ 4 files changed, 77 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr89435.c create mode 100644 gcc/testsuite/gcc.dg/pr89795.c create mode 100644 gcc/testsuite/gcc.dg/pr91720.c (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 940be7f..aa3127c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2019-09-11 Jakub Jelinek + + PR rtl-optimization/89435 + PR rtl-optimization/89795 + PR rtl-optimization/91720 + * gcc.dg/pr89435.c: New test. + * gcc.dg/pr89795.c: New test. + * gcc.dg/pr91720.c: New test. + 2019-09-11 Richard Biener PR tree-optimization/90387 diff --git a/gcc/testsuite/gcc.dg/pr89435.c b/gcc/testsuite/gcc.dg/pr89435.c new file mode 100644 index 0000000..d72d087 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr89435.c @@ -0,0 +1,21 @@ +/* PR rtl-optimization/89435 */ +/* { dg-do run } */ +/* { dg-options "-O1 -fno-forward-propagate -fno-tree-forwprop -fno-tree-ccp" } */ + +unsigned short a; +unsigned int b, c, d, e, f; + +int +main () +{ +#if __CHAR_BIT__ == 8 && __SIZEOF_INT__ == 4 + unsigned char g = e = __builtin_mul_overflow_p (5, 542624702, 0); + d = __builtin_bswap64 (a); + b = __builtin_sub_overflow ((unsigned char) -e, (unsigned int) d, &g); + e = __builtin_mul_overflow (b, c, &a); + f = g + e; + if (f != 0xff) + __builtin_abort (); +#endif + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr89795.c b/gcc/testsuite/gcc.dg/pr89795.c new file mode 100644 index 0000000..4ceaa43 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr89795.c @@ -0,0 +1,25 @@ +/* PR rtl-optimization/89795 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fno-dce -fno-forward-propagate -fno-sched-pressure" } */ + +unsigned char a; +unsigned b, c, d; + +int +main () +{ +#if __CHAR_BIT__ == 8 + unsigned x; + int e, f; + unsigned char g; + e = __builtin_bswap32 (a); + f = __builtin_ffs (~(unsigned short) e); + a = __builtin_mul_overflow ((unsigned char) 0xf7, f, &g); + a |= __builtin_sub_overflow_p (c, 0, (unsigned char) 0); + d = g + b; + x = d; + if (x != 0xf7) + __builtin_abort (); +#endif + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr91720.c b/gcc/testsuite/gcc.dg/pr91720.c new file mode 100644 index 0000000..4abdace --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr91720.c @@ -0,0 +1,22 @@ +/* PR rtl-optimization/91720 */ +/* { dg-do run } */ +/* { dg-options "-Og -fno-forward-propagate -frerun-cse-after-loop -fno-tree-fre" } */ + +unsigned a, b; + +int +main () +{ +#if __CHAR_BIT__ == 8 + unsigned c = 1; + unsigned long long d = 0; + unsigned char e = 0; + e = __builtin_sub_overflow (d, e, &a) ? 0 : 0x80; + e = e << 7 | e >> c; + __builtin_memmove (&d, &a, 2); + b = e; + if (b != 0x40) + __builtin_abort (); +#endif + return 0; +} -- cgit v1.1 From d694576e174d95b7f6066d924715691c55824f30 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 11 Sep 2019 12:44:12 +0000 Subject: gotest: force test package to be imported first When compiling the x_test package, force the test package to be imported first. That ensures that we will see the types defined in the test package before the types defined in the non-test version of the package. This matters if the types differ in some way, such as by adding a new method. This avoids a failure in internal/poll on Solaris, in which the test package adds a method to a type (FD.EOFError). I think it was Solaris- specific because files are sorted in a different order by default. The go tool handles this kind of thing correctly, by rebuilding dependent packages. This is just a hack sufficient to run the libgo testsuite without using the go tool. Fixes https://gcc.gnu.org/PR91712 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/194637 From-SVN: r275648 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 61845bc..895aa6f 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -bf4832d604e7522dee78fca76de220b62a131d54 +1f4ce28409a2d9d4045b1085de55c46de8759d1c The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From debae5232b81f4f0adcdc25ad8c8d2645a6ea376 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 11 Sep 2019 14:06:05 +0000 Subject: golang.org/x/sys/cpu: define doinit when needed Should fix the build on riscv64 and other systems. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/194641 From-SVN: r275650 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 895aa6f..4ae93ee 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -1f4ce28409a2d9d4045b1085de55c46de8759d1c +27b2311fa460b1dd76fb3a796c7c05ebedc64df2 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From a387d636cda7df27df2ad52c3947ef8d37f7aa46 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 11 Sep 2019 14:25:52 +0000 Subject: compiler: suppress type descriptor generation for aliases Change Named_object::get_backend to ignore aliases when creating type descriptors for types, to be consistent with Type::needs_specific_type_functions and the Specific_type_functions traversal class. For example, when compiling a package that creates an alias to an an externally defined type, e.g. import "foo" type MyFoo = foo.Foo it makes sense to skip the alias (not try to generate type specific functions for it) and let the normal mechanisms take care of the alias target, depending on whether the target is defined locally or defined elsewhere. Testcase for this problen can be found in CL 193261. Fixes golang/go#33866. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/191961 From-SVN: r275651 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/gogo.cc | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 4ae93ee..8098eb0 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -27b2311fa460b1dd76fb3a796c7c05ebedc64df2 +0950e905939f88c1421f8667ac4dc9e14528471c The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index f6a8e7a..3ff88cb 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -8718,7 +8718,13 @@ Named_object::get_backend(Gogo* gogo, std::vector& const_decls, case NAMED_OBJECT_TYPE: { Named_type* named_type = this->u_.type_value; - if (!Gogo::is_erroneous_name(this->name_) && !named_type->is_alias()) + + // No need to do anything for aliases-- whatever has to be done + // can be done for the alias target. + if (named_type->is_alias()) + break; + + if (!Gogo::is_erroneous_name(this->name_)) type_decls.push_back(named_type->get_backend(gogo)); // We need to produce a type descriptor for every named -- cgit v1.1 From 19e057e7cc47115ea89f5d222baaae41e0084f50 Mon Sep 17 00:00:00 2001 From: Michael Meissner Date: Wed, 11 Sep 2019 18:20:57 +0000 Subject: Simplify the code. 2019-09-11 Michael Meissner * config/rs6000/predicates.md (non_add_cint_operand): Simplify the code. From-SVN: r275652 --- gcc/ChangeLog | 5 +++++ gcc/config/rs6000/predicates.md | 3 +-- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 608f3b9..7f7f651 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-09-11 Michael Meissner + + * config/rs6000/predicates.md (non_add_cint_operand): Simplify the + code. + 2019-09-11 Nathan Sidwell * tree.h (MARK_TS_TYPE_NON_COMMON): New. diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 4e77063..9368bdd 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -851,8 +851,7 @@ ;; Return 1 if OP is a constant but not a valid add_operand. (define_predicate "non_add_cint_operand" (and (match_code "const_int") - (match_test "!satisfies_constraint_I (op) - && !satisfies_constraint_L (op)"))) + (not (match_operand 0 "add_operand")))) ;; Return 1 if the operand is a constant that can be used as the operand ;; of an AND, OR or XOR. -- cgit v1.1 From 84e33251331478d41b1c05768ccf0d060ce5b242 Mon Sep 17 00:00:00 2001 From: "Steven G. Kargl" Date: Wed, 11 Sep 2019 18:27:17 +0000 Subject: re PR fortran/91642 (ICE: Bad IO basetype (transfer_expr, at fortran/trans-io.c:2507)) 2019-09-11 Steven G. Kargl PR fortran/91642 * io.c (gfc_match_inquire): null() cannot be in an iolength inquire list. 2019-09-11 Steven G. Kargl PR fortran/91642 * gfortran.dg/pr91642.f90: New test. From-SVN: r275655 --- gcc/fortran/ChangeLog | 6 ++++++ gcc/fortran/io.c | 11 +++++++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gfortran.dg/pr91642.f90 | 19 +++++++++++++++++++ 4 files changed, 41 insertions(+) create mode 100644 gcc/testsuite/gfortran.dg/pr91642.f90 (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 9c787f7..b3770ce 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,9 @@ +2019-09-11 Steven G. Kargl + + PR fortran/91642 + * io.c (gfc_match_inquire): null() cannot be in an iolength inquire + list. + 2019-09-05 Harald Anlauf PR fortran/91496 diff --git a/gcc/fortran/io.c b/gcc/fortran/io.c index d57b747..bb64560 100644 --- a/gcc/fortran/io.c +++ b/gcc/fortran/io.c @@ -4641,6 +4641,17 @@ gfc_match_inquire (void) if (m == MATCH_NO) goto syntax; + for (gfc_code *c = code; c; c = c->next) + if (c->expr1 && c->expr1->expr_type == EXPR_FUNCTION + && c->expr1->symtree && c->expr1->symtree->n.sym->attr.function + && !c->expr1->symtree->n.sym->attr.external + && strcmp (c->expr1->symtree->name, "null") == 0) + { + gfc_error ("NULL() near %L cannot appear in INQUIRE statement", + &c->expr1->where); + goto cleanup; + } + new_st.op = EXEC_IOLENGTH; new_st.expr1 = inquire->iolength; new_st.ext.inquire = inquire; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index aa3127c..6c316ee 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-11 Steven G. Kargl + + PR fortran/91642 + * gfortran.dg/pr91642.f90: New test. + 2019-09-11 Jakub Jelinek PR rtl-optimization/89435 diff --git a/gcc/testsuite/gfortran.dg/pr91642.f90 b/gcc/testsuite/gfortran.dg/pr91642.f90 new file mode 100644 index 0000000..b3cc40f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr91642.f90 @@ -0,0 +1,19 @@ +! { dg-do compile } +! PR fortran/91642 +! Code contributed by Gerhard Steinmetz +program p + integer i + integer :: iol + integer, external :: null + i = 0 + inquire (iolength=iol) null() + if (iol == 4) stop 1 +end + +subroutine q + integer i + integer :: iol + i = 0 + inquire (iolength=iol) i, null() ! { dg-error "cannot appear in INQUIRE" } + if (iol == 4) stop 2 +end -- cgit v1.1 From 22aa73bda49dc609c235b80b0e98d95ce8d50405 Mon Sep 17 00:00:00 2001 From: "Steven G. Kargl" Date: Wed, 11 Sep 2019 18:37:31 +0000 Subject: re PR fortran/91553 (ICE in gfc_real2complex, at fortran/arith.c:2208) 2019-09-11 Steven G. Kargl PR fortran/91553 * simplify.c (gfc_convert_constant): During conversion check if the constant is enclosed in parenthesis, and simplify expression. 2019-09-11 Steven G. Kargl PR fortran/91553 * gfortran.dg/pr91553.f90: New test. From-SVN: r275657 --- gcc/fortran/ChangeLog | 6 ++++++ gcc/fortran/simplify.c | 6 ++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gfortran.dg/pr91553.f90 | 8 ++++++++ 4 files changed, 25 insertions(+) create mode 100644 gcc/testsuite/gfortran.dg/pr91553.f90 (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index b3770ce..1702199 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,5 +1,11 @@ 2019-09-11 Steven G. Kargl + PR fortran/91553 + * simplify.c (gfc_convert_constant): During conversion check if the + constant is enclosed in parenthesis, and simplify expression. + +2019-09-11 Steven G. Kargl + PR fortran/91642 * io.c (gfc_match_inquire): null() cannot be in an iolength inquire list. diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c index 7fc18d5..023eedb 100644 --- a/gcc/fortran/simplify.c +++ b/gcc/fortran/simplify.c @@ -8503,6 +8503,12 @@ gfc_convert_constant (gfc_expr *e, bt type, int kind) { if (c->expr->expr_type == EXPR_ARRAY) tmp = gfc_convert_constant (c->expr, type, kind); + else if (c->expr->expr_type == EXPR_OP + && c->expr->value.op.op == INTRINSIC_PARENTHESES) + { + gfc_simplify_expr (c->expr, 1); + tmp = f (c->expr, kind); + } else tmp = f (c->expr, kind); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6c316ee..546da4e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2019-09-11 Steven G. Kargl + PR fortran/91553 + * gfortran.dg/pr91553.f90: New test. + +2019-09-11 Steven G. Kargl + PR fortran/91642 * gfortran.dg/pr91642.f90: New test. diff --git a/gcc/testsuite/gfortran.dg/pr91553.f90 b/gcc/testsuite/gfortran.dg/pr91553.f90 new file mode 100644 index 0000000..2d0b018 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr91553.f90 @@ -0,0 +1,8 @@ +! { dg-do run } +! Code contributed by Gerhard Steinmetz +program p + complex z(1) + z = (1.0, 2.0) * [real :: (3.0 + 4.0)] + if (real(z(1)) /= 7.) stop 1 + if (aimag(z(1)) /= 14.) stop 2 +end -- cgit v1.1 From 94aebf7e4d23793946949973582541dceeeb54b4 Mon Sep 17 00:00:00 2001 From: Sandra Loosemore Date: Wed, 11 Sep 2019 16:53:46 -0400 Subject: re PR middle-end/83889 (new failures on some arm targets after r256644) 2019-09-11 Sandra Loosemore PR testsuite/83889 gcc/testsuite/ * gcc.dg/vect/pr81740-2.c: Remove explicit dg-do run. * gcc.dg/vect/pr88598-1.c: Likewise. * gcc.dg/vect/pr88598-2.c: Likewise. * gcc.dg/vect/pr88598-3.c: Likewise. * gcc.dg/vect/pr88598-4.c: Likewise. * gcc.dg/vect/pr88598-5.c: Likewise. * gcc.dg/vect/pr88598-6.c: Likewise. * gcc.dg/vect/pr89440.c: Likewise. * gcc.dg/vect/pr90018.c: Likewise. * gcc.dg/vect/pr91293-1.c: Likewise. * gcc.dg/vect/pr91293-2.c: Likewise. * gcc.dg/vect/pr91293-3.c: Likewise. From-SVN: r275667 --- gcc/testsuite/ChangeLog | 16 ++++++++++++++++ gcc/testsuite/gcc.dg/vect/pr81740-1.c | 1 - gcc/testsuite/gcc.dg/vect/pr81740-2.c | 1 - gcc/testsuite/gcc.dg/vect/pr88598-1.c | 1 - gcc/testsuite/gcc.dg/vect/pr88598-2.c | 1 - gcc/testsuite/gcc.dg/vect/pr88598-3.c | 1 - gcc/testsuite/gcc.dg/vect/pr88598-4.c | 1 - gcc/testsuite/gcc.dg/vect/pr88598-5.c | 1 - gcc/testsuite/gcc.dg/vect/pr88598-6.c | 1 - gcc/testsuite/gcc.dg/vect/pr89440.c | 1 - gcc/testsuite/gcc.dg/vect/pr90018.c | 1 - gcc/testsuite/gcc.dg/vect/pr91293-1.c | 1 - gcc/testsuite/gcc.dg/vect/pr91293-2.c | 1 - gcc/testsuite/gcc.dg/vect/pr91293-3.c | 1 - 14 files changed, 16 insertions(+), 13 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 546da4e..1a62746 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,19 @@ +2019-09-11 Sandra Loosemore + + PR testsuite/83889 + * gcc.dg/vect/pr81740-2.c: Remove explicit dg-do run. + * gcc.dg/vect/pr88598-1.c: Likewise. + * gcc.dg/vect/pr88598-2.c: Likewise. + * gcc.dg/vect/pr88598-3.c: Likewise. + * gcc.dg/vect/pr88598-4.c: Likewise. + * gcc.dg/vect/pr88598-5.c: Likewise. + * gcc.dg/vect/pr88598-6.c: Likewise. + * gcc.dg/vect/pr89440.c: Likewise. + * gcc.dg/vect/pr90018.c: Likewise. + * gcc.dg/vect/pr91293-1.c: Likewise. + * gcc.dg/vect/pr91293-2.c: Likewise. + * gcc.dg/vect/pr91293-3.c: Likewise. + 2019-09-11 Steven G. Kargl PR fortran/91553 diff --git a/gcc/testsuite/gcc.dg/vect/pr81740-1.c b/gcc/testsuite/gcc.dg/vect/pr81740-1.c index d2226fc..f6fd43c 100644 --- a/gcc/testsuite/gcc.dg/vect/pr81740-1.c +++ b/gcc/testsuite/gcc.dg/vect/pr81740-1.c @@ -1,4 +1,3 @@ -/* { dg-do run } */ /* { dg-require-effective-target vect_int } */ #include "tree-vect.h" diff --git a/gcc/testsuite/gcc.dg/vect/pr81740-2.c b/gcc/testsuite/gcc.dg/vect/pr81740-2.c index 6bb8371..1e0d664 100644 --- a/gcc/testsuite/gcc.dg/vect/pr81740-2.c +++ b/gcc/testsuite/gcc.dg/vect/pr81740-2.c @@ -1,4 +1,3 @@ -/* { dg-do run } */ /* { dg-require-effective-target vect_int } */ /* { dg-require-effective-target vect_hw_misalign } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr88598-1.c b/gcc/testsuite/gcc.dg/vect/pr88598-1.c index 1d119ee..e25c6c0 100644 --- a/gcc/testsuite/gcc.dg/vect/pr88598-1.c +++ b/gcc/testsuite/gcc.dg/vect/pr88598-1.c @@ -1,4 +1,3 @@ -/* { dg-do run } */ /* { dg-additional-options "-fdump-tree-optimized" } */ #include "tree-vect.h" diff --git a/gcc/testsuite/gcc.dg/vect/pr88598-2.c b/gcc/testsuite/gcc.dg/vect/pr88598-2.c index 837cd5d..f4c41bd 100644 --- a/gcc/testsuite/gcc.dg/vect/pr88598-2.c +++ b/gcc/testsuite/gcc.dg/vect/pr88598-2.c @@ -1,4 +1,3 @@ -/* { dg-do run } */ /* { dg-additional-options "-fdump-tree-optimized" } */ #include "tree-vect.h" diff --git a/gcc/testsuite/gcc.dg/vect/pr88598-3.c b/gcc/testsuite/gcc.dg/vect/pr88598-3.c index ee034ec..0fc23bf 100644 --- a/gcc/testsuite/gcc.dg/vect/pr88598-3.c +++ b/gcc/testsuite/gcc.dg/vect/pr88598-3.c @@ -1,4 +1,3 @@ -/* { dg-do run } */ /* { dg-additional-options "-ffast-math -fdump-tree-optimized" } */ #include "tree-vect.h" diff --git a/gcc/testsuite/gcc.dg/vect/pr88598-4.c b/gcc/testsuite/gcc.dg/vect/pr88598-4.c index b5cf08d..08923b9 100644 --- a/gcc/testsuite/gcc.dg/vect/pr88598-4.c +++ b/gcc/testsuite/gcc.dg/vect/pr88598-4.c @@ -1,4 +1,3 @@ -/* { dg-do run } */ /* { dg-additional-options "-fdump-tree-optimized" } */ #include "tree-vect.h" diff --git a/gcc/testsuite/gcc.dg/vect/pr88598-5.c b/gcc/testsuite/gcc.dg/vect/pr88598-5.c index b3b9843..929b40b 100644 --- a/gcc/testsuite/gcc.dg/vect/pr88598-5.c +++ b/gcc/testsuite/gcc.dg/vect/pr88598-5.c @@ -1,4 +1,3 @@ -/* { dg-do run } */ /* { dg-additional-options "-fdump-tree-optimized" } */ #include "tree-vect.h" diff --git a/gcc/testsuite/gcc.dg/vect/pr88598-6.c b/gcc/testsuite/gcc.dg/vect/pr88598-6.c index f04e32d..2d6e0d7 100644 --- a/gcc/testsuite/gcc.dg/vect/pr88598-6.c +++ b/gcc/testsuite/gcc.dg/vect/pr88598-6.c @@ -1,4 +1,3 @@ -/* { dg-do run } */ /* { dg-additional-options "-ffast-math -fdump-tree-optimized" } */ #include "tree-vect.h" diff --git a/gcc/testsuite/gcc.dg/vect/pr89440.c b/gcc/testsuite/gcc.dg/vect/pr89440.c index 668f48e..d84527e 100644 --- a/gcc/testsuite/gcc.dg/vect/pr89440.c +++ b/gcc/testsuite/gcc.dg/vect/pr89440.c @@ -1,4 +1,3 @@ -/* { dg-do run } */ /* { dg-additional-options "-ffast-math" } */ #include "tree-vect.h" diff --git a/gcc/testsuite/gcc.dg/vect/pr90018.c b/gcc/testsuite/gcc.dg/vect/pr90018.c index d98b4c8..52640f5 100644 --- a/gcc/testsuite/gcc.dg/vect/pr90018.c +++ b/gcc/testsuite/gcc.dg/vect/pr90018.c @@ -1,4 +1,3 @@ -/* { dg-do run } */ /* { dg-require-effective-target vect_double } */ #include "tree-vect.h" diff --git a/gcc/testsuite/gcc.dg/vect/pr91293-1.c b/gcc/testsuite/gcc.dg/vect/pr91293-1.c index dc321f5..e05b5b9 100644 --- a/gcc/testsuite/gcc.dg/vect/pr91293-1.c +++ b/gcc/testsuite/gcc.dg/vect/pr91293-1.c @@ -1,4 +1,3 @@ -/* { dg-do run } */ /* { dg-additional-options "-msse4.1" { target { sse4_runtime } } } */ long long a; diff --git a/gcc/testsuite/gcc.dg/vect/pr91293-2.c b/gcc/testsuite/gcc.dg/vect/pr91293-2.c index b9354bb..d01e6ff 100644 --- a/gcc/testsuite/gcc.dg/vect/pr91293-2.c +++ b/gcc/testsuite/gcc.dg/vect/pr91293-2.c @@ -1,4 +1,3 @@ -/* { dg-do run } */ /* { dg-additional-options "-msse4.1" { target { sse4_runtime } } } */ long long a; diff --git a/gcc/testsuite/gcc.dg/vect/pr91293-3.c b/gcc/testsuite/gcc.dg/vect/pr91293-3.c index c35bc34..64490f4 100644 --- a/gcc/testsuite/gcc.dg/vect/pr91293-3.c +++ b/gcc/testsuite/gcc.dg/vect/pr91293-3.c @@ -1,4 +1,3 @@ -/* { dg-do run } */ /* { dg-additional-options "-msse4.1" { target { sse4_runtime } } } */ long long a; -- cgit v1.1 From 8c58d9d837098d692d313a7116ed7d4a9e271287 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Thu, 12 Sep 2019 00:16:18 +0000 Subject: Daily bump. From-SVN: r275680 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 0766c00..fabe17c 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20190911 +20190912 -- cgit v1.1 From 58cc98767aa1d8136d36467b892dc4adaf427acc Mon Sep 17 00:00:00 2001 From: Yuliang Wang Date: Thu, 12 Sep 2019 09:59:58 +0000 Subject: Vectorise multiply high with scaling operations (PR 89386) 2019-09-12 Yuliang Wang gcc/ PR tree-optimization/89386 * config/aarch64/aarch64-sve2.md (mull) (shrnb, shrnt): New SVE2 patterns. (mulhs3): New pattern for MULHRS. * config/aarch64/iterators.md (UNSPEC_SMULLB, UNSPEC_SMULLT) (UNSPEC_UMULLB, UNSPEC_UMULLT, UNSPEC_SHRNB, UNSPEC_SHRNT) (UNSPEC_RSHRNB, UNSPEC_RSHRNT, UNSPEC_SMULHS, UNSPEC_SMULHRS) UNSPEC_UMULHS, UNSPEC_UMULHRS): New unspecs. (MULLBT, SHRNB, SHRNT, MULHRS): New int iterators. (su, r): Handle the unspecs above. (bt): New int attribute. * internal-fn.def (IFN_MULHS, IFN_MULHRS): New internal functions. * internal-fn.c (first_commutative_argument): Commutativity info for above. * optabs.def (smulhs_optab, smulhrs_optab, umulhs_optab) (umulhrs_optab): New optabs. * doc/md.texi (smulhs$var{m3}, umulhs$var{m3}) (smulhrs$var{m3}, umulhrs$var{m3}): Documentation for the above. * tree-vect-patterns.c (vect_recog_mulhs_pattern): New pattern function. (vect_vect_recog_func_ptrs): Add it. * testsuite/gcc.target/aarch64/sve2/mulhrs_1.c: New test. * testsuite/gcc.dg/vect/vect-mulhrs-1.c: As above. * testsuite/gcc.dg/vect/vect-mulhrs-2.c: As above. * testsuite/gcc.dg/vect/vect-mulhrs-3.c: As above. * testsuite/gcc.dg/vect/vect-mulhrs-4.c: As above. * doc/sourcebuild.texi (vect_mulhrs_hi): Document new target selector. * testsuite/lib/target-supports.exp (check_effective_target_vect_mulhrs_hi): Return true for AArch64 with SVE2. From-SVN: r275682 --- gcc/ChangeLog | 33 +++++ gcc/config/aarch64/aarch64-sve2.md | 60 ++++++++ gcc/config/aarch64/iterators.md | 35 ++++- gcc/doc/md.texi | 27 ++++ gcc/doc/sourcebuild.texi | 4 + gcc/internal-fn.c | 2 + gcc/internal-fn.def | 5 + gcc/optabs.def | 4 + gcc/testsuite/gcc.dg/vect/vect-mulhrs-1.c | 49 +++++++ gcc/testsuite/gcc.dg/vect/vect-mulhrs-2.c | 9 ++ gcc/testsuite/gcc.dg/vect/vect-mulhrs-3.c | 9 ++ gcc/testsuite/gcc.dg/vect/vect-mulhrs-4.c | 10 ++ gcc/testsuite/gcc.target/aarch64/sve2/mulhrs_1.c | 63 +++++++++ gcc/testsuite/lib/target-supports.exp | 9 ++ gcc/tree-vect-patterns.c | 170 +++++++++++++++++++++++ 15 files changed, 488 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/vect/vect-mulhrs-1.c create mode 100644 gcc/testsuite/gcc.dg/vect/vect-mulhrs-2.c create mode 100644 gcc/testsuite/gcc.dg/vect/vect-mulhrs-3.c create mode 100644 gcc/testsuite/gcc.dg/vect/vect-mulhrs-4.c create mode 100644 gcc/testsuite/gcc.target/aarch64/sve2/mulhrs_1.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7f7f651..7aba409 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,36 @@ +2019-09-12 Yuliang Wang + + PR tree-optimization/89386 + * config/aarch64/aarch64-sve2.md (mull) + (shrnb, shrnt): New SVE2 patterns. + (mulhs3): New pattern for MULHRS. + * config/aarch64/iterators.md (UNSPEC_SMULLB, UNSPEC_SMULLT) + (UNSPEC_UMULLB, UNSPEC_UMULLT, UNSPEC_SHRNB, UNSPEC_SHRNT) + (UNSPEC_RSHRNB, UNSPEC_RSHRNT, UNSPEC_SMULHS, UNSPEC_SMULHRS) + UNSPEC_UMULHS, UNSPEC_UMULHRS): New unspecs. + (MULLBT, SHRNB, SHRNT, MULHRS): New int iterators. + (su, r): Handle the unspecs above. + (bt): New int attribute. + * internal-fn.def (IFN_MULHS, IFN_MULHRS): New internal functions. + * internal-fn.c (first_commutative_argument): Commutativity info for + above. + * optabs.def (smulhs_optab, smulhrs_optab, umulhs_optab) + (umulhrs_optab): New optabs. + * doc/md.texi (smulhs$var{m3}, umulhs$var{m3}) + (smulhrs$var{m3}, umulhrs$var{m3}): Documentation for the above. + * tree-vect-patterns.c (vect_recog_mulhs_pattern): New pattern + function. + (vect_vect_recog_func_ptrs): Add it. + * testsuite/gcc.target/aarch64/sve2/mulhrs_1.c: New test. + * testsuite/gcc.dg/vect/vect-mulhrs-1.c: As above. + * testsuite/gcc.dg/vect/vect-mulhrs-2.c: As above. + * testsuite/gcc.dg/vect/vect-mulhrs-3.c: As above. + * testsuite/gcc.dg/vect/vect-mulhrs-4.c: As above. + * doc/sourcebuild.texi (vect_mulhrs_hi): Document new target selector. + * testsuite/lib/target-supports.exp + (check_effective_target_vect_mulhrs_hi): Return true for AArch64 + with SVE2. + 2019-09-11 Michael Meissner * config/rs6000/predicates.md (non_add_cint_operand): Simplify the diff --git a/gcc/config/aarch64/aarch64-sve2.md b/gcc/config/aarch64/aarch64-sve2.md index 2334e5a..ee9acdc 100644 --- a/gcc/config/aarch64/aarch64-sve2.md +++ b/gcc/config/aarch64/aarch64-sve2.md @@ -63,3 +63,63 @@ movprfx\t%0, %2\;h\t%0., %1/m, %0., %3." [(set_attr "movprfx" "*,yes")] ) + +;; Multiply long top / bottom. +(define_insn "mull" + [(set (match_operand: 0 "register_operand" "=w") + (unspec: [(match_operand:SVE_BHSI 1 "register_operand" "w") + (match_operand:SVE_BHSI 2 "register_operand" "w")] + MULLBT))] + "TARGET_SVE2" + "mull\t%0., %1., %2." +) + +;; (Rounding) Right shift narrow bottom. +(define_insn "shrnb" + [(set (match_operand:SVE_BHSI 0 "register_operand" "=w") + (unspec:SVE_BHSI + [(match_operand: 1 "register_operand" "w") + (match_operand 2 "aarch64_simd_shift_imm_offset_" "")] + SHRNB))] + "TARGET_SVE2" + "shrnb\t%0., %1., #%2" +) + +;; (Rounding) Right shift narrow top. +(define_insn "shrnt" + [(set (match_operand:SVE_BHSI 0 "register_operand" "=w") + (unspec:SVE_BHSI + [(match_operand:SVE_BHSI 1 "register_operand" "0") + (match_operand: 2 "register_operand" "w") + (match_operand 3 "aarch64_simd_shift_imm_offset_" "i")] + SHRNT))] + "TARGET_SVE2" + "shrnt\t%0., %2., #%3" +) + +;; Unpredicated integer multiply-high-with-(round-and-)scale. +(define_expand "mulhs3" + [(set (match_operand:SVE_BHSI 0 "register_operand") + (unspec:SVE_BHSI + [(match_dup 3) + (unspec:SVE_BHSI [(match_operand:SVE_BHSI 1 "register_operand") + (match_operand:SVE_BHSI 2 "register_operand")] + MULHRS)] + UNSPEC_PRED_X))] + "TARGET_SVE2" + { + operands[3] = aarch64_ptrue_reg (mode); + + rtx prod_b = gen_reg_rtx (mode); + rtx prod_t = gen_reg_rtx (mode); + emit_insn (gen_mullb (prod_b, operands[1], operands[2])); + emit_insn (gen_mullt (prod_t, operands[1], operands[2])); + + rtx shift = GEN_INT (GET_MODE_UNIT_BITSIZE (mode) - 1); + emit_insn (gen_shrnb (operands[0], prod_b, shift)); + emit_insn (gen_shrnt (operands[0], operands[0], prod_t, shift)); + + DONE; + } +) + diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index 49d227f..d23f0fc 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -378,6 +378,10 @@ UNSPEC_RSUBHN2 ; Used in aarch64-simd.md. UNSPEC_SQDMULH ; Used in aarch64-simd.md. UNSPEC_SQRDMULH ; Used in aarch64-simd.md. + UNSPEC_SMULLB ; Used in aarch64-sve2.md. + UNSPEC_SMULLT ; Used in aarch64-sve2.md. + UNSPEC_UMULLB ; Used in aarch64-sve2.md. + UNSPEC_UMULLT ; Used in aarch64-sve2.md. UNSPEC_PMUL ; Used in aarch64-simd.md. UNSPEC_FMULX ; Used in aarch64-simd.md. UNSPEC_USQADD ; Used in aarch64-simd.md. @@ -400,6 +404,10 @@ UNSPEC_UQSHRN ; Used in aarch64-simd.md. UNSPEC_SQRSHRN ; Used in aarch64-simd.md. UNSPEC_UQRSHRN ; Used in aarch64-simd.md. + UNSPEC_SHRNB ; Used in aarch64-sve2.md. + UNSPEC_SHRNT ; Used in aarch64-sve2.md. + UNSPEC_RSHRNB ; Used in aarch64-sve2.md. + UNSPEC_RSHRNT ; Used in aarch64-sve2.md. UNSPEC_SSHL ; Used in aarch64-simd.md. UNSPEC_USHL ; Used in aarch64-simd.md. UNSPEC_SRSHL ; Used in aarch64-simd.md. @@ -523,6 +531,10 @@ UNSPEC_FCMLA90 ; Used in aarch64-simd.md. UNSPEC_FCMLA180 ; Used in aarch64-simd.md. UNSPEC_FCMLA270 ; Used in aarch64-simd.md. + UNSPEC_SMULHS ; Used in aarch64-sve2.md. + UNSPEC_SMULHRS ; Used in aarch64-sve2.md. + UNSPEC_UMULHS ; Used in aarch64-sve2.md. + UNSPEC_UMULHRS ; Used in aarch64-sve2.md. ]) ;; ------------------------------------------------------------------ @@ -1588,6 +1600,13 @@ (define_int_iterator RHADD [UNSPEC_SRHADD UNSPEC_URHADD]) +(define_int_iterator MULLBT [UNSPEC_SMULLB UNSPEC_UMULLB + UNSPEC_SMULLT UNSPEC_UMULLT]) + +(define_int_iterator SHRNB [UNSPEC_SHRNB UNSPEC_RSHRNB]) + +(define_int_iterator SHRNT [UNSPEC_SHRNT UNSPEC_RSHRNT]) + (define_int_iterator DOTPROD [UNSPEC_SDOT UNSPEC_UDOT]) (define_int_iterator ADDSUBHN [UNSPEC_ADDHN UNSPEC_RADDHN @@ -1607,6 +1626,9 @@ (define_int_iterator VQDMULH [UNSPEC_SQDMULH UNSPEC_SQRDMULH]) +(define_int_iterator MULHRS [UNSPEC_SMULHS UNSPEC_UMULHS + UNSPEC_SMULHRS UNSPEC_UMULHRS]) + (define_int_iterator USSUQADD [UNSPEC_SUQADD UNSPEC_USQADD]) (define_int_iterator SUQMOVN [UNSPEC_SQXTN UNSPEC_UQXTN]) @@ -1872,7 +1894,11 @@ (UNSPEC_COND_FCVTZS "s") (UNSPEC_COND_FCVTZU "u") (UNSPEC_COND_SCVTF "s") - (UNSPEC_COND_UCVTF "u")]) + (UNSPEC_COND_UCVTF "u") + (UNSPEC_SMULLB "s") (UNSPEC_UMULLB "u") + (UNSPEC_SMULLT "s") (UNSPEC_UMULLT "u") + (UNSPEC_SMULHS "s") (UNSPEC_UMULHS "u") + (UNSPEC_SMULHRS "s") (UNSPEC_UMULHRS "u")]) (define_int_attr sur [(UNSPEC_SHADD "s") (UNSPEC_UHADD "u") (UNSPEC_SRHADD "sr") (UNSPEC_URHADD "ur") @@ -1910,6 +1936,10 @@ (UNSPEC_SQRSHRN "r") (UNSPEC_UQRSHRN "r") (UNSPEC_SQSHL "") (UNSPEC_UQSHL "") (UNSPEC_SQRSHL "r")(UNSPEC_UQRSHL "r") + (UNSPEC_SHRNB "") (UNSPEC_SHRNT "") + (UNSPEC_RSHRNB "r") (UNSPEC_RSHRNT "r") + (UNSPEC_SMULHS "") (UNSPEC_UMULHS "") + (UNSPEC_SMULHRS "r") (UNSPEC_UMULHRS "r") ]) (define_int_attr lr [(UNSPEC_SSLI "l") (UNSPEC_USLI "l") @@ -1922,6 +1952,9 @@ (UNSPEC_SHADD "") (UNSPEC_UHADD "u") (UNSPEC_SRHADD "") (UNSPEC_URHADD "u")]) +(define_int_attr bt [(UNSPEC_SMULLB "b") (UNSPEC_UMULLB "b") + (UNSPEC_SMULLT "t") (UNSPEC_UMULLT "t")]) + (define_int_attr addsub [(UNSPEC_SHADD "add") (UNSPEC_UHADD "add") (UNSPEC_SRHADD "add") diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index fa4ae14..f35fd2b 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -5387,6 +5387,33 @@ operand 1. Add operand 1 to operand 2 and place the widened result in operand 0. (This is used express accumulation of elements into an accumulator of a wider mode.) +@cindex @code{smulhs@var{m3}} instruction pattern +@item @samp{smulhs@var{m3}} +@cindex @code{umulhs@var{m3}} instruction pattern +@itemx @samp{umulhs@var{m3}} +Signed/unsigned multiply high with scale. This is equivalent to the C code: +@smallexample +narrow op0, op1, op2; +@dots{} +op0 = (narrow) (((wide) op1 * (wide) op2) >> (N / 2 - 1)); +@end smallexample +where the sign of @samp{narrow} determines whether this is a signed +or unsigned operation, and @var{N} is the size of @samp{wide} in bits. + +@cindex @code{smulhrs@var{m3}} instruction pattern +@item @samp{smulhrs@var{m3}} +@cindex @code{umulhrs@var{m3}} instruction pattern +@itemx @samp{umulhrs@var{m3}} +Signed/unsigned multiply high with round and scale. This is +equivalent to the C code: +@smallexample +narrow op0, op1, op2; +@dots{} +op0 = (narrow) (((((wide) op1 * (wide) op2) >> (N / 2 - 2)) + 1) >> 1); +@end smallexample +where the sign of @samp{narrow} determines whether this is a signed +or unsigned operation, and @var{N} is the size of @samp{wide} in bits. + @cindex @code{vec_shl_insert_@var{m}} instruction pattern @item @samp{vec_shl_insert_@var{m}} Shift the elements in vector input operand 1 left one element (i.e.@: diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi index e4180cc..4ace224 100644 --- a/gcc/doc/sourcebuild.texi +++ b/gcc/doc/sourcebuild.texi @@ -1442,6 +1442,10 @@ vector alignment. Target supports both signed and unsigned averaging operations on vectors of bytes. +@item vect_mulhrs_hi +Target supports both signed and unsigned multiply-high-with-round-and-scale +operations on vectors of half-words. + @item vect_condition Target supports vector conditional operations. diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c index ad86b9a..549d6f1 100644 --- a/gcc/internal-fn.c +++ b/gcc/internal-fn.c @@ -3210,6 +3210,8 @@ first_commutative_argument (internal_fn fn) case IFN_FNMS: case IFN_AVG_FLOOR: case IFN_AVG_CEIL: + case IFN_MULHS: + case IFN_MULHRS: case IFN_FMIN: case IFN_FMAX: return 0; diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def index b5a6ca3..49f5797 100644 --- a/gcc/internal-fn.def +++ b/gcc/internal-fn.def @@ -149,6 +149,11 @@ DEF_INTERNAL_SIGNED_OPTAB_FN (AVG_FLOOR, ECF_CONST | ECF_NOTHROW, first, DEF_INTERNAL_SIGNED_OPTAB_FN (AVG_CEIL, ECF_CONST | ECF_NOTHROW, first, savg_ceil, uavg_ceil, binary) +DEF_INTERNAL_SIGNED_OPTAB_FN (MULHS, ECF_CONST | ECF_NOTHROW, first, + smulhs, umulhs, binary) +DEF_INTERNAL_SIGNED_OPTAB_FN (MULHRS, ECF_CONST | ECF_NOTHROW, first, + smulhrs, umulhrs, binary) + DEF_INTERNAL_OPTAB_FN (COND_ADD, ECF_CONST, cond_add, cond_binary) DEF_INTERNAL_OPTAB_FN (COND_SUB, ECF_CONST, cond_sub, cond_binary) DEF_INTERNAL_OPTAB_FN (COND_MUL, ECF_CONST, cond_smul, cond_binary) diff --git a/gcc/optabs.def b/gcc/optabs.def index 0860b38..3086968 100644 --- a/gcc/optabs.def +++ b/gcc/optabs.def @@ -343,6 +343,10 @@ OPTAB_D (udot_prod_optab, "udot_prod$I$a") OPTAB_D (usum_widen_optab, "widen_usum$I$a3") OPTAB_D (usad_optab, "usad$I$a") OPTAB_D (ssad_optab, "ssad$I$a") +OPTAB_D (smulhs_optab, "smulhs$a3") +OPTAB_D (smulhrs_optab, "smulhrs$a3") +OPTAB_D (umulhs_optab, "umulhs$a3") +OPTAB_D (umulhrs_optab, "umulhrs$a3") OPTAB_D (vec_pack_sfix_trunc_optab, "vec_pack_sfix_trunc_$a") OPTAB_D (vec_pack_ssat_optab, "vec_pack_ssat_$a") OPTAB_D (vec_pack_trunc_optab, "vec_pack_trunc_$a") diff --git a/gcc/testsuite/gcc.dg/vect/vect-mulhrs-1.c b/gcc/testsuite/gcc.dg/vect/vect-mulhrs-1.c new file mode 100644 index 0000000..8e46ff6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-mulhrs-1.c @@ -0,0 +1,49 @@ +/* { dg-require-effective-target vect_int } */ + +#include "tree-vect.h" +#ifndef SIGNEDNESS +#define SIGNEDNESS signed +#endif +#ifndef BIAS +#define BIAS 0 +#endif + +#define HRS(x) ((((x) >> (15 - BIAS)) + BIAS) >> BIAS) + +void __attribute__ ((noipa)) +f (SIGNEDNESS short *restrict a, SIGNEDNESS short *restrict b, + SIGNEDNESS short *restrict c, __INTPTR_TYPE__ n) +{ + for (__INTPTR_TYPE__ i = 0; i < n; ++i) + a[i] = HRS((SIGNEDNESS int) b[i] * (SIGNEDNESS int) c[i]); +} + +#define N 50 +#define BASE1 ((SIGNEDNESS int) -1 < 0 ? -126 : 4) +#define BASE2 ((SIGNEDNESS int) -1 < 0 ? -101 : 26) +#define CONST1 0x01AB +#define CONST2 0x01CD + +int +main (void) +{ + check_vect (); + + SIGNEDNESS short a[N], b[N], c[N]; + for (int i = 0; i < N; ++i) + { + b[i] = BASE1 + i * CONST1; + c[i] = BASE2 + i * CONST2; + asm volatile ("" ::: "memory"); + } + f (a, b, c, N); + for (int i = 0; i < N; ++i) + if (a[i] != HRS(BASE1 * BASE2 + i * i * (CONST1 * CONST2) + + i * (BASE1 * CONST2 + BASE2 * CONST1))) + __builtin_abort (); + return 0; +} + +/* { dg-final { scan-tree-dump "vect_recog_mulhs_pattern: detected" "vect" } } */ +/* { dg-final { scan-tree-dump {\.MULHS} "vect" { target vect_mulhrs_hi } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_mulhrs_hi } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-mulhrs-2.c b/gcc/testsuite/gcc.dg/vect/vect-mulhrs-2.c new file mode 100644 index 0000000..a16e71c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-mulhrs-2.c @@ -0,0 +1,9 @@ +/* { dg-require-effective-target vect_int } */ + +#define SIGNEDNESS unsigned + +#include "vect-mulhrs-1.c" + +/* { dg-final { scan-tree-dump "vect_recog_mulhs_pattern: detected" "vect" } } */ +/* { dg-final { scan-tree-dump {\.MULHS} "vect" { target vect_mulhrs_hi } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_mulhrs_hi } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-mulhrs-3.c b/gcc/testsuite/gcc.dg/vect/vect-mulhrs-3.c new file mode 100644 index 0000000..e7d44d7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-mulhrs-3.c @@ -0,0 +1,9 @@ +/* { dg-require-effective-target vect_int } */ + +#define BIAS 1 + +#include "vect-mulhrs-1.c" + +/* { dg-final { scan-tree-dump "vect_recog_mulhs_pattern: detected" "vect" } } */ +/* { dg-final { scan-tree-dump {\.MULHRS} "vect" { target vect_mulhrs_hi } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_mulhrs_hi } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-mulhrs-4.c b/gcc/testsuite/gcc.dg/vect/vect-mulhrs-4.c new file mode 100644 index 0000000..e121763 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-mulhrs-4.c @@ -0,0 +1,10 @@ +/* { dg-require-effective-target vect_int } */ + +#define SIGNEDNESS unsigned +#define BIAS 1 + +#include "vect-mulhrs-1.c" + +/* { dg-final { scan-tree-dump "vect_recog_mulhs_pattern: detected" "vect" } } */ +/* { dg-final { scan-tree-dump {\.MULHRS} "vect" { target vect_mulhrs_hi } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_mulhrs_hi } } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/mulhrs_1.c b/gcc/testsuite/gcc.target/aarch64/sve2/mulhrs_1.c new file mode 100644 index 0000000..7970d68 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve2/mulhrs_1.c @@ -0,0 +1,63 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details --save-temps" } */ + +#include + +#define MULTHI(TYPE, BIGGER, RND) \ +TYPE __attribute__ ((noinline, noclone)) \ +mulhs_##TYPE##_##RND (TYPE *restrict x, \ + TYPE *restrict y, TYPE *restrict z, int n) \ +{ \ + for (int i = 0; i < n; i++) \ + { \ + z[i] = ((((BIGGER)x[i] * (BIGGER)y[i]) >> \ + (sizeof(BIGGER)*8/2-2)) + RND) >> 1; \ + } \ +} + +MULTHI (int8_t, int16_t, 0) +MULTHI (int16_t, int32_t, 0) +MULTHI (int32_t, int64_t, 0) + +MULTHI (uint8_t, uint16_t, 0) +MULTHI (uint16_t, uint32_t, 0) +MULTHI (uint32_t, uint64_t, 0) + +MULTHI (int8_t, int16_t, 1) +MULTHI (int16_t, int32_t, 1) +MULTHI (int32_t, int64_t, 1) + +MULTHI (uint8_t, uint16_t, 1) +MULTHI (uint16_t, uint32_t, 1) +MULTHI (uint32_t, uint64_t, 1) + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 12 "vect" } } */ + +/* { dg-final { scan-assembler-times {\tsmullb\tz[0-9]+\.h, z[0-9]+\.b, z[0-9]+\.b\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tsmullt\tz[0-9]+\.h, z[0-9]+\.b, z[0-9]+\.b\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tsmullb\tz[0-9]+\.s, z[0-9]+\.h, z[0-9]+\.h\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tsmullt\tz[0-9]+\.s, z[0-9]+\.h, z[0-9]+\.h\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tsmullb\tz[0-9]+\.d, z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tsmullt\tz[0-9]+\.d, z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */ + +/* { dg-final { scan-assembler-times {\tshrnb\tz[0-9]+\.b, z[0-9]+\.h, #7\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tshrnt\tz[0-9]+\.b, z[0-9]+\.h, #7\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tshrnb\tz[0-9]+\.h, z[0-9]+\.s, #15\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tshrnt\tz[0-9]+\.h, z[0-9]+\.s, #15\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tshrnb\tz[0-9]+\.s, z[0-9]+\.d, #31\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tshrnt\tz[0-9]+\.s, z[0-9]+\.d, #31\n} 2 } } */ + +/* { dg-final { scan-assembler-times {\tumullb\tz[0-9]+\.h, z[0-9]+\.b, z[0-9]+\.b\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tumullt\tz[0-9]+\.h, z[0-9]+\.b, z[0-9]+\.b\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tumullb\tz[0-9]+\.s, z[0-9]+\.h, z[0-9]+\.h\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tumullt\tz[0-9]+\.s, z[0-9]+\.h, z[0-9]+\.h\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tumullb\tz[0-9]+\.d, z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tumullt\tz[0-9]+\.d, z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */ + +/* { dg-final { scan-assembler-times {\trshrnb\tz[0-9]+\.b, z[0-9]+\.h, #7\n} 2 } } */ +/* { dg-final { scan-assembler-times {\trshrnt\tz[0-9]+\.b, z[0-9]+\.h, #7\n} 2 } } */ +/* { dg-final { scan-assembler-times {\trshrnb\tz[0-9]+\.h, z[0-9]+\.s, #15\n} 2 } } */ +/* { dg-final { scan-assembler-times {\trshrnt\tz[0-9]+\.h, z[0-9]+\.s, #15\n} 2 } } */ +/* { dg-final { scan-assembler-times {\trshrnb\tz[0-9]+\.s, z[0-9]+\.d, #31\n} 2 } } */ +/* { dg-final { scan-assembler-times {\trshrnt\tz[0-9]+\.s, z[0-9]+\.d, #31\n} 2 } } */ + diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 4f7d6cb..f05a093 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -6175,6 +6175,15 @@ proc check_effective_target_vect_avg_qi {} { && ![check_effective_target_aarch64_sve1_only] }] } +# Return 1 if the target plus current options supports both signed +# and unsigned multiply-high-with-round-and-scale operations +# on vectors of half-words. + +proc check_effective_target_vect_mulhrs_hi {} { + return [expr { [istarget aarch64*-*-*] + && [check_effective_target_aarch64_sve2] }] +} + # Return 1 if the target plus current options supports a vector # demotion (packing) of shorts (to chars) and ints (to shorts) # using modulo arithmetic, 0 otherwise. diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index ccb2e1e..2f86f9e 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -1723,6 +1723,175 @@ vect_recog_over_widening_pattern (stmt_vec_info last_stmt_info, tree *type_out) return pattern_stmt; } +/* Recognize the following patterns: + + ATYPE a; // narrower than TYPE + BTYPE b; // narrower than TYPE + + 1) Multiply high with scaling + TYPE res = ((TYPE) a * (TYPE) b) >> c; + 2) ... or also with rounding + TYPE res = (((TYPE) a * (TYPE) b) >> d + 1) >> 1; + + where only the bottom half of res is used. */ + +static gimple * +vect_recog_mulhs_pattern (stmt_vec_info last_stmt_info, tree *type_out) +{ + /* Check for a right shift. */ + gassign *last_stmt = dyn_cast (last_stmt_info->stmt); + if (!last_stmt + || gimple_assign_rhs_code (last_stmt) != RSHIFT_EXPR) + return NULL; + vec_info *vinfo = last_stmt_info->vinfo; + + /* Check that the shift result is wider than the users of the + result need (i.e. that narrowing would be a natural choice). */ + tree lhs_type = TREE_TYPE (gimple_assign_lhs (last_stmt)); + unsigned int target_precision + = vect_element_precision (last_stmt_info->min_output_precision); + if (!INTEGRAL_TYPE_P (lhs_type) + || target_precision >= TYPE_PRECISION (lhs_type)) + return NULL; + + /* Look through any change in sign on the outer shift input. */ + vect_unpromoted_value unprom_rshift_input; + tree rshift_input = vect_look_through_possible_promotion + (vinfo, gimple_assign_rhs1 (last_stmt), &unprom_rshift_input); + if (!rshift_input + || TYPE_PRECISION (TREE_TYPE (rshift_input)) + != TYPE_PRECISION (lhs_type)) + return NULL; + + /* Get the definition of the shift input. */ + stmt_vec_info rshift_input_stmt_info + = vect_get_internal_def (vinfo, rshift_input); + if (!rshift_input_stmt_info) + return NULL; + gassign *rshift_input_stmt + = dyn_cast (rshift_input_stmt_info->stmt); + if (!rshift_input_stmt) + return NULL; + + stmt_vec_info mulh_stmt_info; + tree scale_term; + internal_fn ifn; + unsigned int expect_offset; + + /* Check for the presence of the rounding term. */ + if (gimple_assign_rhs_code (rshift_input_stmt) == PLUS_EXPR) + { + /* Check that the outer shift was by 1. */ + if (!integer_onep (gimple_assign_rhs2 (last_stmt))) + return NULL; + + /* Check that the second operand of the PLUS_EXPR is 1. */ + if (!integer_onep (gimple_assign_rhs2 (rshift_input_stmt))) + return NULL; + + /* Look through any change in sign on the addition input. */ + vect_unpromoted_value unprom_plus_input; + tree plus_input = vect_look_through_possible_promotion + (vinfo, gimple_assign_rhs1 (rshift_input_stmt), &unprom_plus_input); + if (!plus_input + || TYPE_PRECISION (TREE_TYPE (plus_input)) + != TYPE_PRECISION (TREE_TYPE (rshift_input))) + return NULL; + + /* Get the definition of the multiply-high-scale part. */ + stmt_vec_info plus_input_stmt_info + = vect_get_internal_def (vinfo, plus_input); + if (!plus_input_stmt_info) + return NULL; + gassign *plus_input_stmt + = dyn_cast (plus_input_stmt_info->stmt); + if (!plus_input_stmt + || gimple_assign_rhs_code (plus_input_stmt) != RSHIFT_EXPR) + return NULL; + + /* Look through any change in sign on the scaling input. */ + vect_unpromoted_value unprom_scale_input; + tree scale_input = vect_look_through_possible_promotion + (vinfo, gimple_assign_rhs1 (plus_input_stmt), &unprom_scale_input); + if (!scale_input + || TYPE_PRECISION (TREE_TYPE (scale_input)) + != TYPE_PRECISION (TREE_TYPE (plus_input))) + return NULL; + + /* Get the definition of the multiply-high part. */ + mulh_stmt_info = vect_get_internal_def (vinfo, scale_input); + if (!mulh_stmt_info) + return NULL; + + /* Get the scaling term. */ + scale_term = gimple_assign_rhs2 (plus_input_stmt); + + expect_offset = target_precision + 2; + ifn = IFN_MULHRS; + } + else + { + mulh_stmt_info = rshift_input_stmt_info; + scale_term = gimple_assign_rhs2 (last_stmt); + + expect_offset = target_precision + 1; + ifn = IFN_MULHS; + } + + /* Check that the scaling factor is correct. */ + if (TREE_CODE (scale_term) != INTEGER_CST + || wi::to_widest (scale_term) + expect_offset + != TYPE_PRECISION (lhs_type)) + return NULL; + + /* Check whether the scaling input term can be seen as two widened + inputs multiplied together. */ + vect_unpromoted_value unprom_mult[2]; + tree new_type; + unsigned int nops + = vect_widened_op_tree (mulh_stmt_info, MULT_EXPR, WIDEN_MULT_EXPR, + false, 2, unprom_mult, &new_type); + if (nops != 2) + return NULL; + + vect_pattern_detected ("vect_recog_mulhs_pattern", last_stmt); + + /* Adjust output precision. */ + if (TYPE_PRECISION (new_type) < target_precision) + new_type = build_nonstandard_integer_type + (target_precision, TYPE_UNSIGNED (new_type)); + + /* Check for target support. */ + tree new_vectype = get_vectype_for_scalar_type (new_type); + if (!new_vectype + || !direct_internal_fn_supported_p + (ifn, new_vectype, OPTIMIZE_FOR_SPEED)) + return NULL; + + /* The IR requires a valid vector type for the cast result, even though + it's likely to be discarded. */ + *type_out = get_vectype_for_scalar_type (lhs_type); + if (!*type_out) + return NULL; + + /* Generate the IFN_MULHRS call. */ + tree new_var = vect_recog_temp_ssa_var (new_type, NULL); + tree new_ops[2]; + vect_convert_inputs (last_stmt_info, 2, new_ops, new_type, + unprom_mult, new_vectype); + gcall *mulhrs_stmt + = gimple_build_call_internal (ifn, 2, new_ops[0], new_ops[1]); + gimple_call_set_lhs (mulhrs_stmt, new_var); + gimple_set_location (mulhrs_stmt, gimple_location (last_stmt)); + + if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE, vect_location, + "created pattern stmt: %G", mulhrs_stmt); + + return vect_convert_output (last_stmt_info, lhs_type, + mulhrs_stmt, new_vectype); +} + /* Recognize the patterns: ATYPE a; // narrower than TYPE @@ -4713,6 +4882,7 @@ static vect_recog_func vect_vect_recog_func_ptrs[] = { /* Must come after over_widening, which narrows the shift as much as possible beforehand. */ { vect_recog_average_pattern, "average" }, + { vect_recog_mulhs_pattern, "mult_high" }, { vect_recog_cast_forwprop_pattern, "cast_forwprop" }, { vect_recog_widen_mult_pattern, "widen_mult" }, { vect_recog_dot_prod_pattern, "dot_prod" }, -- cgit v1.1 From bdc91a3299f955ed6b862adf0f2fea6d5496bc31 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 12 Sep 2019 12:48:43 +0000 Subject: re PR tree-optimization/91750 (Induction vectorization introduces signed overflows) 2019-09-12 Richard Biener PR tree-optimization/91750 * tree-vect-loop.c (vectorizable_induction): Compute IV increments in the type of the evolution. * gcc.dg/vect/pr91750.c: New testcase. From-SVN: r275685 --- gcc/ChangeLog | 6 +++ gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.dg/vect/pr91750.c | 15 ++++++ gcc/tree-vect-loop.c | 92 ++++++++++++++++++++----------------- 4 files changed, 77 insertions(+), 41 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/pr91750.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7aba409..e91cba1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-09-12 Richard Biener + + PR tree-optimization/91750 + * tree-vect-loop.c (vectorizable_induction): Compute IV increments + in the type of the evolution. + 2019-09-12 Yuliang Wang PR tree-optimization/89386 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1a62746..8d82d65 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-12 Richard Biener + + PR tree-optimization/91750 + * gcc.dg/vect/pr91750.c: New testcase. + 2019-09-11 Sandra Loosemore PR testsuite/83889 diff --git a/gcc/testsuite/gcc.dg/vect/pr91750.c b/gcc/testsuite/gcc.dg/vect/pr91750.c new file mode 100644 index 0000000..fe914b2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr91750.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +int val[1024]; +void +foo (int n) +{ + int i; + for (int j = 0, i = n; j < 1024; ++j, i=(unsigned)i+1) + val[j] = i; +} + +/* Make sure the induction IV uses an unsigned increment. */ +/* { dg-final { scan-tree-dump "vector\\\(\[0-9\]*\\\) unsigned int" "vect" } } */ +/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */ diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index 8324492..d8546ff 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -7605,6 +7605,7 @@ vectorizable_induction (stmt_vec_info stmt_info, step_expr = STMT_VINFO_LOOP_PHI_EVOLUTION_PART (stmt_info); gcc_assert (step_expr != NULL_TREE); + tree step_vectype = get_same_sized_vectype (TREE_TYPE (step_expr), vectype); pe = loop_preheader_edge (iv_loop); init_expr = PHI_ARG_DEF_FROM_EDGE (phi, @@ -7613,8 +7614,8 @@ vectorizable_induction (stmt_vec_info stmt_info, stmts = NULL; if (!nested_in_vect_loop) { - /* Convert the initial value to the desired type. */ - tree new_type = TREE_TYPE (vectype); + /* Convert the initial value to the IV update type. */ + tree new_type = TREE_TYPE (step_expr); init_expr = gimple_convert (&stmts, new_type, init_expr); /* If we are using the loop mask to "peel" for alignment then we need @@ -7634,9 +7635,6 @@ vectorizable_induction (stmt_vec_info stmt_info, } } - /* Convert the step to the desired type. */ - step_expr = gimple_convert (&stmts, TREE_TYPE (vectype), step_expr); - if (stmts) { new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts); @@ -7669,8 +7667,8 @@ vectorizable_induction (stmt_vec_info stmt_info, if (! CONSTANT_CLASS_P (new_name)) new_name = vect_init_vector (stmt_info, new_name, TREE_TYPE (step_expr), NULL); - new_vec = build_vector_from_val (vectype, new_name); - vec_step = vect_init_vector (stmt_info, new_vec, vectype, NULL); + new_vec = build_vector_from_val (step_vectype, new_name); + vec_step = vect_init_vector (stmt_info, new_vec, step_vectype, NULL); /* Now generate the IVs. */ unsigned group_size = SLP_TREE_SCALAR_STMTS (slp_node).length (); @@ -7683,7 +7681,7 @@ vectorizable_induction (stmt_vec_info stmt_info, unsigned ivn; for (ivn = 0; ivn < nivs; ++ivn) { - tree_vector_builder elts (vectype, const_nunits, 1); + tree_vector_builder elts (step_vectype, const_nunits, 1); stmts = NULL; for (unsigned eltn = 0; eltn < const_nunits; ++eltn) { @@ -7694,6 +7692,7 @@ vectorizable_induction (stmt_vec_info stmt_info, elts.quick_push (elt); } vec_init = gimple_build_vector (&stmts, &elts); + vec_init = gimple_convert (&stmts, vectype, vec_init); if (stmts) { new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts); @@ -7708,10 +7707,13 @@ vectorizable_induction (stmt_vec_info stmt_info, induc_def = PHI_RESULT (induction_phi); /* Create the iv update inside the loop */ - vec_def = make_ssa_name (vec_dest); - new_stmt = gimple_build_assign (vec_def, PLUS_EXPR, induc_def, vec_step); - gsi_insert_before (&si, new_stmt, GSI_SAME_STMT); - loop_vinfo->add_stmt (new_stmt); + gimple_seq stmts = NULL; + vec_def = gimple_convert (&stmts, step_vectype, induc_def); + vec_def = gimple_build (&stmts, + PLUS_EXPR, step_vectype, vec_def, vec_step); + vec_def = gimple_convert (&stmts, vectype, vec_def); + loop_vinfo->add_stmt (SSA_NAME_DEF_STMT (vec_def)); + gsi_insert_seq_before (&si, stmts, GSI_SAME_STMT); /* Set the arguments of the phi node: */ add_phi_arg (induction_phi, vec_init, pe, UNKNOWN_LOCATION); @@ -7739,8 +7741,8 @@ vectorizable_induction (stmt_vec_info stmt_info, if (! CONSTANT_CLASS_P (new_name)) new_name = vect_init_vector (stmt_info, new_name, TREE_TYPE (step_expr), NULL); - new_vec = build_vector_from_val (vectype, new_name); - vec_step = vect_init_vector (stmt_info, new_vec, vectype, NULL); + new_vec = build_vector_from_val (step_vectype, new_name); + vec_step = vect_init_vector (stmt_info, new_vec, step_vectype, NULL); for (; ivn < nvects; ++ivn) { gimple *iv = SLP_TREE_VEC_STMTS (slp_node)[ivn - nivs]->stmt; @@ -7749,18 +7751,20 @@ vectorizable_induction (stmt_vec_info stmt_info, def = gimple_phi_result (iv); else def = gimple_assign_lhs (iv); - new_stmt = gimple_build_assign (make_ssa_name (vectype), - PLUS_EXPR, - def, vec_step); + gimple_seq stmts = NULL; + def = gimple_convert (&stmts, step_vectype, def); + def = gimple_build (&stmts, + PLUS_EXPR, step_vectype, def, vec_step); + def = gimple_convert (&stmts, vectype, def); if (gimple_code (iv) == GIMPLE_PHI) - gsi_insert_before (&si, new_stmt, GSI_SAME_STMT); + gsi_insert_seq_before (&si, stmts, GSI_SAME_STMT); else { gimple_stmt_iterator tgsi = gsi_for_stmt (iv); - gsi_insert_after (&tgsi, new_stmt, GSI_CONTINUE_LINKING); + gsi_insert_seq_after (&tgsi, stmts, GSI_CONTINUE_LINKING); } SLP_TREE_VEC_STMTS (slp_node).quick_push - (loop_vinfo->add_stmt (new_stmt)); + (loop_vinfo->add_stmt (SSA_NAME_DEF_STMT (def))); } } @@ -7796,12 +7800,12 @@ vectorizable_induction (stmt_vec_info stmt_info, /* iv_loop is the loop to be vectorized. Create: vec_init = [X, X+S, X+2*S, X+3*S] (S = step_expr, X = init_expr) */ stmts = NULL; - new_name = gimple_convert (&stmts, TREE_TYPE (vectype), init_expr); + new_name = gimple_convert (&stmts, TREE_TYPE (step_expr), init_expr); unsigned HOST_WIDE_INT const_nunits; if (nunits.is_constant (&const_nunits)) { - tree_vector_builder elts (vectype, const_nunits, 1); + tree_vector_builder elts (step_vectype, const_nunits, 1); elts.quick_push (new_name); for (i = 1; i < const_nunits; i++) { @@ -7816,7 +7820,7 @@ vectorizable_induction (stmt_vec_info stmt_info, } else if (INTEGRAL_TYPE_P (TREE_TYPE (step_expr))) /* Build the initial value directly from a VEC_SERIES_EXPR. */ - vec_init = gimple_build (&stmts, VEC_SERIES_EXPR, vectype, + vec_init = gimple_build (&stmts, VEC_SERIES_EXPR, step_vectype, new_name, step_expr); else { @@ -7825,17 +7829,18 @@ vectorizable_induction (stmt_vec_info stmt_info, + (vectype) [0, 1, 2, ...] * [step, step, step, ...]. */ gcc_assert (SCALAR_FLOAT_TYPE_P (TREE_TYPE (step_expr))); gcc_assert (flag_associative_math); - tree index = build_index_vector (vectype, 0, 1); - tree base_vec = gimple_build_vector_from_val (&stmts, vectype, + tree index = build_index_vector (step_vectype, 0, 1); + tree base_vec = gimple_build_vector_from_val (&stmts, step_vectype, new_name); - tree step_vec = gimple_build_vector_from_val (&stmts, vectype, + tree step_vec = gimple_build_vector_from_val (&stmts, step_vectype, step_expr); - vec_init = gimple_build (&stmts, FLOAT_EXPR, vectype, index); - vec_init = gimple_build (&stmts, MULT_EXPR, vectype, + vec_init = gimple_build (&stmts, FLOAT_EXPR, step_vectype, index); + vec_init = gimple_build (&stmts, MULT_EXPR, step_vectype, vec_init, step_vec); - vec_init = gimple_build (&stmts, PLUS_EXPR, vectype, + vec_init = gimple_build (&stmts, PLUS_EXPR, step_vectype, vec_init, base_vec); } + vec_init = gimple_convert (&stmts, vectype, vec_init); if (stmts) { @@ -7874,8 +7879,8 @@ vectorizable_induction (stmt_vec_info stmt_info, t = unshare_expr (new_name); gcc_assert (CONSTANT_CLASS_P (new_name) || TREE_CODE (new_name) == SSA_NAME); - new_vec = build_vector_from_val (vectype, t); - vec_step = vect_init_vector (stmt_info, new_vec, vectype, NULL); + new_vec = build_vector_from_val (step_vectype, t); + vec_step = vect_init_vector (stmt_info, new_vec, step_vectype, NULL); /* Create the following def-use cycle: @@ -7896,9 +7901,12 @@ vectorizable_induction (stmt_vec_info stmt_info, induc_def = PHI_RESULT (induction_phi); /* Create the iv update inside the loop */ - vec_def = make_ssa_name (vec_dest); - new_stmt = gimple_build_assign (vec_def, PLUS_EXPR, induc_def, vec_step); - gsi_insert_before (&si, new_stmt, GSI_SAME_STMT); + stmts = NULL; + vec_def = gimple_convert (&stmts, step_vectype, induc_def); + vec_def = gimple_build (&stmts, PLUS_EXPR, step_vectype, vec_def, vec_step); + vec_def = gimple_convert (&stmts, vectype, vec_def); + gsi_insert_seq_before (&si, stmts, GSI_SAME_STMT); + new_stmt = SSA_NAME_DEF_STMT (vec_def); stmt_vec_info new_stmt_info = loop_vinfo->add_stmt (new_stmt); /* Set the arguments of the phi node: */ @@ -7940,20 +7948,22 @@ vectorizable_induction (stmt_vec_info stmt_info, t = unshare_expr (new_name); gcc_assert (CONSTANT_CLASS_P (new_name) || TREE_CODE (new_name) == SSA_NAME); - new_vec = build_vector_from_val (vectype, t); - vec_step = vect_init_vector (stmt_info, new_vec, vectype, NULL); + new_vec = build_vector_from_val (step_vectype, t); + vec_step = vect_init_vector (stmt_info, new_vec, step_vectype, NULL); vec_def = induc_def; prev_stmt_vinfo = induction_phi_info; for (i = 1; i < ncopies; i++) { /* vec_i = vec_prev + vec_step */ - new_stmt = gimple_build_assign (vec_dest, PLUS_EXPR, - vec_def, vec_step); - vec_def = make_ssa_name (vec_dest, new_stmt); - gimple_assign_set_lhs (new_stmt, vec_def); + gimple_seq stmts = NULL; + vec_def = gimple_convert (&stmts, step_vectype, vec_def); + vec_def = gimple_build (&stmts, + PLUS_EXPR, step_vectype, vec_def, vec_step); + vec_def = gimple_convert (&stmts, vectype, vec_def); - gsi_insert_before (&si, new_stmt, GSI_SAME_STMT); + gsi_insert_seq_before (&si, stmts, GSI_SAME_STMT); + new_stmt = SSA_NAME_DEF_STMT (vec_def); new_stmt_info = loop_vinfo->add_stmt (new_stmt); STMT_VINFO_RELATED_STMT (prev_stmt_vinfo) = new_stmt_info; prev_stmt_vinfo = new_stmt_info; -- cgit v1.1 From d6ecb707cc5a58816d27908a7aa324c4b0bc67bb Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Thu, 12 Sep 2019 21:18:25 +0200 Subject: re PR tree-optimization/89386 (Generation of vectorized MULHRS (Multiply High with Round and Scale) instruction) PR tree-optimization/89386 * config/i386/sse.md (smulhrs3): New expander. (smulhrsv4hi3): Ditto. testsuite/ChangeLog: PR tree-optimization/89386 * gcc.target/i386/pr89386.c: New test. * gcc.target/i386/pr89386-1.c: Ditto. From-SVN: r275689 --- gcc/ChangeLog | 15 +++++------- gcc/config/i386/sse.md | 40 +++++++++++++++++++++++++++++++ gcc/testsuite/ChangeLog | 19 +++++++++++++++ gcc/testsuite/gcc.target/i386/pr89386-1.c | 16 +++++++++++++ gcc/testsuite/gcc.target/i386/pr89386.c | 16 +++++++++++++ 5 files changed, 97 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr89386-1.c create mode 100644 gcc/testsuite/gcc.target/i386/pr89386.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e91cba1..d368dc6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-09-12 Uroš Bizjak + + PR tree-optimization/89386 + * config/i386/sse.md (smulhrs3): New expander. + (smulhrsv4hi3): Ditto. + 2019-09-12 Richard Biener PR tree-optimization/91750 @@ -27,15 +33,6 @@ * tree-vect-patterns.c (vect_recog_mulhs_pattern): New pattern function. (vect_vect_recog_func_ptrs): Add it. - * testsuite/gcc.target/aarch64/sve2/mulhrs_1.c: New test. - * testsuite/gcc.dg/vect/vect-mulhrs-1.c: As above. - * testsuite/gcc.dg/vect/vect-mulhrs-2.c: As above. - * testsuite/gcc.dg/vect/vect-mulhrs-3.c: As above. - * testsuite/gcc.dg/vect/vect-mulhrs-4.c: As above. - * doc/sourcebuild.texi (vect_mulhrs_hi): Document new target selector. - * testsuite/lib/target-supports.exp - (check_effective_target_vect_mulhrs_hi): Return true for AArch64 - with SVE2. 2019-09-11 Michael Meissner diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 621b4db..c7f539f 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -16475,6 +16475,26 @@ ix86_fixup_binary_operands_no_copy (MULT, mode, operands); }) +(define_expand "smulhrs3" + [(set (match_operand:VI2_AVX2 0 "register_operand") + (truncate:VI2_AVX2 + (lshiftrt: + (plus: + (lshiftrt: + (mult: + (sign_extend: + (match_operand:VI2_AVX2 1 "nonimmediate_operand")) + (sign_extend: + (match_operand:VI2_AVX2 2 "nonimmediate_operand"))) + (const_int 14)) + (match_dup 3)) + (const_int 1))))] + "TARGET_SSSE3" +{ + operands[3] = CONST1_RTX(mode); + ix86_fixup_binary_operands_no_copy (MULT, mode, operands); +}) + (define_insn "*_pmulhrsw3" [(set (match_operand:VI2_AVX2 0 "register_operand" "=x,x,v") (truncate:VI2_AVX2 @@ -16502,6 +16522,26 @@ (set_attr "prefix" "orig,maybe_evex,evex") (set_attr "mode" "")]) +(define_expand "smulhrsv4hi3" + [(set (match_operand:V4HI 0 "register_operand") + (truncate:V4HI + (lshiftrt:V4SI + (plus:V4SI + (lshiftrt:V4SI + (mult:V4SI + (sign_extend:V4SI + (match_operand:V4HI 1 "register_operand")) + (sign_extend:V4SI + (match_operand:V4HI 2 "register_operand"))) + (const_int 14)) + (match_dup 3)) + (const_int 1))))] + "TARGET_MMX_WITH_SSE && TARGET_SSSE3" +{ + operands[3] = CONST1_RTX(V4HImode); + ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands); +}) + (define_expand "ssse3_pmulhrswv4hi3" [(set (match_operand:V4HI 0 "register_operand") (truncate:V4HI diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8d82d65..cd80562 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,8 +1,27 @@ +2019-09-12 Uroš Bizjak + + PR tree-optimization/89386 + * gcc.target/i386/pr89386.c: New test. + * gcc.target/i386/pr89386-1.c: Ditto. + 2019-09-12 Richard Biener PR tree-optimization/91750 * gcc.dg/vect/pr91750.c: New testcase. +2019-09-12 Yuliang Wang + + PR tree-optimization/89386 + * testsuite/gcc.target/aarch64/sve2/mulhrs_1.c: New test. + * testsuite/gcc.dg/vect/vect-mulhrs-1.c: As above. + * testsuite/gcc.dg/vect/vect-mulhrs-2.c: As above. + * testsuite/gcc.dg/vect/vect-mulhrs-3.c: As above. + * testsuite/gcc.dg/vect/vect-mulhrs-4.c: As above. + * doc/sourcebuild.texi (vect_mulhrs_hi): Document new target selector. + * testsuite/lib/target-supports.exp + (check_effective_target_vect_mulhrs_hi): Return true for AArch64 + with SVE2. + 2019-09-11 Sandra Loosemore PR testsuite/83889 diff --git a/gcc/testsuite/gcc.target/i386/pr89386-1.c b/gcc/testsuite/gcc.target/i386/pr89386-1.c new file mode 100644 index 0000000..a2d708b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr89386-1.c @@ -0,0 +1,16 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-mssse3 -O2 -ftree-vectorize" } */ + +#define N 4 + +short a[N], b[N], c[N]; + +int foo (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = ((((int) b[i] * (int) c[i]) >> 14) + 1) >> 1; +} + +/* { dg-final { scan-assembler "pmulhrsw" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr89386.c b/gcc/testsuite/gcc.target/i386/pr89386.c new file mode 100644 index 0000000..b308787 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr89386.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-mssse3 -O2 -ftree-vectorize" } */ + +#define N 1024 + +short a[N], b[N], c[N]; + +int foo (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = ((((int) b[i] * (int) c[i]) >> 14) + 1) >> 1; +} + +/* { dg-final { scan-assembler "pmulhrsw" } } */ -- cgit v1.1 From 656297e1fec9a127ff742df16958ee279ccacec5 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 12 Sep 2019 23:22:53 +0000 Subject: libgo: update to Go1.13 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/194698 From-SVN: r275691 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 8098eb0..f950ecd 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -0950e905939f88c1421f8667ac4dc9e14528471c +ceb1e4f5614b4772eed44f9cf57780e52f44753e The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From e5b3c74bf0686faf3932249a9756c6d3145a1531 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Fri, 13 Sep 2019 00:16:19 +0000 Subject: Daily bump. From-SVN: r275695 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index fabe17c..8c87078 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20190912 +20190913 -- cgit v1.1 From e4dc7c6572d50dd9de2331521b8e8ac39d905527 Mon Sep 17 00:00:00 2001 From: Paul Thomas Date: Fri, 13 Sep 2019 05:41:01 +0000 Subject: re PR fortran/91717 (ICE on concatenating deferred-length character and character literal) 2019-09-13 Paul Thomas PR fortran/91717 * dependency.c (gfc_dep_resolver): Flag identical components and exit with return value 1 if set and no array refs. 2019-09-13 Paul Thomas PR fortran/91717 * gfortran.dg/dependency_55.f90 : New test. From-SVN: r275696 --- gcc/fortran/ChangeLog | 6 ++++++ gcc/fortran/dependency.c | 7 +++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gfortran.dg/dependency_55.f90 | 18 ++++++++++++++++++ 4 files changed, 36 insertions(+) create mode 100644 gcc/testsuite/gfortran.dg/dependency_55.f90 (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 1702199..bf721c7 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,9 @@ +2019-09-13 Paul Thomas + + PR fortran/91717 + * dependency.c (gfc_dep_resolver): Flag identical components + and exit with return value 1 if set and no array refs. + 2019-09-11 Steven G. Kargl PR fortran/91553 diff --git a/gcc/fortran/dependency.c b/gcc/fortran/dependency.c index da4a37c..5114870 100644 --- a/gcc/fortran/dependency.c +++ b/gcc/fortran/dependency.c @@ -2096,6 +2096,7 @@ gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse, int m; gfc_dependency fin_dep; gfc_dependency this_dep; + bool same_component = false; this_dep = GFC_DEP_ERROR; fin_dep = GFC_DEP_ERROR; @@ -2115,6 +2116,8 @@ gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse, components. */ if (lref->u.c.component != rref->u.c.component) return 0; + + same_component = true; break; case REF_SUBSTRING: @@ -2280,6 +2283,10 @@ gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse, if (lref || rref) return 1; + /* This can result from concatenation of assumed length string components. */ + if (same_component && fin_dep == GFC_DEP_ERROR) + return 1; + /* If we haven't seen any array refs then something went wrong. */ gcc_assert (fin_dep != GFC_DEP_ERROR); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cd80562..ab1d7bc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-13 Paul Thomas + + PR fortran/91717 + * gfortran.dg/dependency_55.f90 : New test. + 2019-09-12 Uroš Bizjak PR tree-optimization/89386 diff --git a/gcc/testsuite/gfortran.dg/dependency_55.f90 b/gcc/testsuite/gfortran.dg/dependency_55.f90 new file mode 100644 index 0000000..53898b3 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/dependency_55.f90 @@ -0,0 +1,18 @@ +! { dg-do run } +! +! Test the fix for PR91717 in which the concatenation operation ICEd. +! +! Contributed by Damian Rouson +! + type core + character (len=:), allocatable :: msg + end type + + type(core) :: my_core + + my_core%msg = "" + my_core%msg = my_core%msg//"my message is: " + my_core%msg = my_core%msg//"Hello!" + + if (my_core%msg .ne. "my message is: Hello!") stop 1 +end -- cgit v1.1 From 22cd031212e2376221435db5e9c6a298f24d7046 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Fri, 13 Sep 2019 11:33:18 +0000 Subject: re PR fortran/91716 (ICE in output_constant, at varasm.c:5026) 2019-09-13 Bernd Edlinger PR fortran/91716 * trans-array.c (gfc_conv_array_initializer): Always assign the array type of the field to the string constant. testsuite: 2019-09-13 Bernd Edlinger PR fortran/91716 * gfortran.dg/pr91716.f90: New test. From-SVN: r275698 --- gcc/fortran/ChangeLog | 6 ++++++ gcc/fortran/trans-array.c | 11 +++++++---- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gfortran.dg/pr91716.f90 | 8 ++++++++ 4 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/pr91716.f90 (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index bf721c7..a396418 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,9 @@ +2019-09-13 Bernd Edlinger + + PR fortran/91716 + * trans-array.c (gfc_conv_array_initializer): Always assign the + array type of the field to the string constant. + 2019-09-13 Paul Thomas PR fortran/91717 diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index da70301..8881fd9 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -6108,17 +6108,20 @@ gfc_conv_array_initializer (tree type, gfc_expr * expr) tree atype = type; while (TREE_CODE (TREE_TYPE (atype)) == ARRAY_TYPE) atype = TREE_TYPE (atype); - if (TREE_CODE (TREE_TYPE (atype)) == INTEGER_TYPE - && tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (se.expr))) - > tree_to_uhwi (TYPE_SIZE_UNIT (atype))) + gcc_checking_assert (TREE_CODE (TREE_TYPE (atype)) + == INTEGER_TYPE); + gcc_checking_assert (TREE_TYPE (TREE_TYPE (se.expr)) + == TREE_TYPE (atype)); + if (tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (se.expr))) + > tree_to_uhwi (TYPE_SIZE_UNIT (atype))) { unsigned HOST_WIDE_INT size = tree_to_uhwi (TYPE_SIZE_UNIT (atype)); const char *p = TREE_STRING_POINTER (se.expr); se.expr = build_string (size, p); - TREE_TYPE (se.expr) = atype; } + TREE_TYPE (se.expr) = atype; } break; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ab1d7bc..62766c2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-13 Bernd Edlinger + + PR fortran/91716 + * gfortran.dg/pr91716.f90: New test. + 2019-09-13 Paul Thomas PR fortran/91717 diff --git a/gcc/testsuite/gfortran.dg/pr91716.f90 b/gcc/testsuite/gfortran.dg/pr91716.f90 new file mode 100644 index 0000000..d5de358 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr91716.f90 @@ -0,0 +1,8 @@ +! { dg-do compile } +! PR fortran/91716 +! Code contributed by Gerhard Steinmetz +module m + type t + character :: c(2) = [character(-1) :: 'a', 'b'] + end type +end -- cgit v1.1 From 9a235e7e85aec64b023b6725c5a2f3fc3a122d3b Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 13 Sep 2019 13:45:35 +0000 Subject: * doc/invoke.texi (Optimize Options): Fix typo. From-SVN: r275699 --- gcc/ChangeLog | 4 ++++ gcc/doc/invoke.texi | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d368dc6..57a6a67 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2019-09-13 Ian Lance Taylor + + * doc/invoke.texi (Optimize Options): Fix typo. + 2019-09-12 Uroš Bizjak PR tree-optimization/89386 diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 6e91a66..fe5cf35 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -10343,7 +10343,7 @@ To enable debug info generation you need to supply @option{-g} at compile-time. If any of the input files at link time were built with debug info generation enabled the link will enable debug info generation as well. Any elaborate debug info settings -like the dwarf level @option{-gdwarf-5} need to be explicitely repeated +like the dwarf level @option{-gdwarf-5} need to be explicitly repeated at the linker command line and mixing different settings in different translation units is discouraged. -- cgit v1.1 From 57cccc860e501be56096a2863ae571175cb87960 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 13 Sep 2019 17:07:20 +0000 Subject: libgo: don't use \? in grep pattern It's not supported by Solaris grep. Just use * instead; it matches more but it shouldn't matter. Fixes https://gcc.gnu.org/PR91764 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/195238 From-SVN: r275700 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index f950ecd..522d408 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -ceb1e4f5614b4772eed44f9cf57780e52f44753e +5af62eda697da21155091cf5375ed9edb4639b67 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From 237413747601e3f11c22277991b08c84adc302de Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Fri, 13 Sep 2019 17:22:04 +0000 Subject: re PR middle-end/91708 ([ARM] Bootstrap fails in gen_movsi, at config/arm/arm.md:5258) 2019-09-13 Bernd Edlinger PR middle-end/91708 * cse.c (cse_insn): Do not replace anything with a MEM. From-SVN: r275701 --- gcc/ChangeLog | 6 ++++++ gcc/cse.c | 23 ++++++----------------- 2 files changed, 12 insertions(+), 17 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 57a6a67..9bfc0e4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-09-13 Bernd Edlinger + + PR middle-end/91708 + * cse.c (cse_insn): Do not replace anything with a + MEM. + 2019-09-13 Ian Lance Taylor * doc/invoke.texi (Optimize Options): Fix typo. diff --git a/gcc/cse.c b/gcc/cse.c index 098671c..32b6790 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -5238,23 +5238,6 @@ cse_insn (rtx_insn *insn) src_elt_cost = MAX_COST; } - /* Avoid creation of overlapping memory moves. */ - if (MEM_P (trial) && MEM_P (dest) && !rtx_equal_p (trial, dest)) - { - rtx src, dest; - - /* BLKmode moves are not handled by cse anyway. */ - if (GET_MODE (trial) == BLKmode) - break; - - src = canon_rtx (trial); - dest = canon_rtx (SET_DEST (sets[i].rtl)); - - if (!MEM_P (src) || !MEM_P (dest) - || !nonoverlapping_memrefs_p (src, dest, false)) - break; - } - /* Try to optimize (set (reg:M N) (const_int A)) (set (reg:M2 O) (const_int B)) @@ -5385,6 +5368,12 @@ cse_insn (rtx_insn *insn) /* Do nothing for this case. */ ; + /* Do not replace anything with a MEM, except the replacement + is a no-op. This allows this loop to terminate. */ + else if (MEM_P (trial) && !rtx_equal_p (trial, SET_SRC(sets[i].rtl))) + /* Do nothing for this case. */ + ; + /* Look for a substitution that makes a valid insn. */ else if (validate_unshare_change (insn, &SET_SRC (sets[i].rtl), trial, 0)) -- cgit v1.1 From a6fa2e83e958802036ad9ed558bee1988299e0e7 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Fri, 13 Sep 2019 17:43:12 +0000 Subject: gnatmake: Accept the `--sysroot=' GCC driver option According to `gnatmake' documentation: "Any uppercase or multi-character switch that is not a 'gnatmake' switch is passed to 'gcc' (e.g., '-O', '-gnato,' etc.)" however the `--sysroot=' switch is actually rejected: gnatmake: invalid switch: --sysroot=... likely because it is one of the very few GCC driver options that have a leading double dash and therefore we don't have a blanket fall-through for such switches that would satisfy what our documentation claims. The option is actually shared between the compiler and the linker, so pass the switch to both build stages if requested, removing GNAT testsuite issues like: gnatmake: invalid switch: --sysroot=.../sysroot compiler exited with status 1 Executing on host: .../gcc/gnatclean -c -q -n ./abstract_with_anonymous_result (timeout = 300) spawn -ignore SIGHUP .../gcc/gnatclean -c -q -n ./abstract_with_anonymous_result PASS: gnat.dg/abstract_with_anonymous_result.adb (test for excess errors) UNRESOLVED: gnat.dg/abstract_with_anonymous_result.adb compilation failed to produce executable in a test environment where `--with-build-sysroot=.../sysroot' has been used to build a cross-compiler. Passing to the compilation stage only would lead to errors like: .../bin/riscv64-linux-gnu-ld: cannot find crt1.o: No such file or directory .../bin/riscv64-linux-gnu-ld: cannot find -lc collect2: error: ld returned 1 exit status gnatlink: error when calling .../gcc/xgcc gnatmake: *** link failed. compiler exited with status 1 Executing on host: .../gcc/gnatclean -c -q -n ./abstract_with_anonymous_result (timeout = 300) spawn -ignore SIGHUP .../gcc/gnatclean -c -q -n ./abstract_with_anonymous_result ./abstract_with_anonymous_result.ali ./abstract_with_anonymous_result.o FAIL: gnat.dg/abstract_with_anonymous_result.adb (test for excess errors) Excess errors: .../bin/riscv64-linux-gnu-ld: cannot find crt1.o: No such file or directory .../bin/riscv64-linux-gnu-ld: cannot find -lc gnatlink: error when calling .../gcc/xgcc UNRESOLVED: gnat.dg/abstract_with_anonymous_result.adb compilation failed to produce executable instead. gcc/ada/ * make.adb (Scan_Make_Arg): Also accept `--sysroot=' for the compiler and the linker. From-SVN: r275702 --- gcc/ada/ChangeLog | 5 +++++ gcc/ada/make.adb | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 410828e..e3e274a 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,8 @@ +2019-09-13 Maciej W. Rozycki + + * make.adb (Scan_Make_Arg): Also accept `--sysroot=' for the + compiler and the linker. + 2019-08-30 Eric Botcazou * gcc-interface/decl.c (maybe_saturate_size): New function. diff --git a/gcc/ada/make.adb b/gcc/ada/make.adb index 805addb..3c9df7e 100644 --- a/gcc/ada/make.adb +++ b/gcc/ada/make.adb @@ -4516,7 +4516,9 @@ package body Make is end; end if; - elsif Argv'Length >= 8 and then Argv (1 .. 8) = "--param=" then + elsif (Argv'Length >= 8 and then Argv (1 .. 8) = "--param=") + or else (Argv'Length >= 10 and then Argv (1 .. 10) = "--sysroot=") + then Add_Switch (Argv, Compiler); Add_Switch (Argv, Linker); -- cgit v1.1 From 81e87db49d7919327d709c4b608990be7ab3b862 Mon Sep 17 00:00:00 2001 From: "Steven G. Kargl" Date: Fri, 13 Sep 2019 20:19:40 +0000 Subject: re PR fortran/91566 (ICE in gfc_constructor_copy, at fortran/constructor.c:103) 2019-09-13 Steven G. Kargl PR fortran/91566 * simplify.c (gfc_simplify_merge): Need to simplify expression after insertation of parenthesis. 2019-09-13 Steven G. Kargl PR fortran/91566 * gfortran.dg/pr91566.f90: From-SVN: r275704 --- gcc/fortran/ChangeLog | 6 ++++++ gcc/fortran/simplify.c | 9 +++++++-- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gfortran.dg/pr91566.f90 | 14 ++++++++++++++ 4 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/pr91566.f90 (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index a396418..6f2ba75 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,9 @@ +2019-09-13 Steven G. Kargl + + PR fortran/91566 + * simplify.c (gfc_simplify_merge): Need to simplify expression + after insertation of parenthesis. + 2019-09-13 Bernd Edlinger PR fortran/91716 diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c index 023eedb..3d2fc0d 100644 --- a/gcc/fortran/simplify.c +++ b/gcc/fortran/simplify.c @@ -4780,8 +4780,13 @@ gfc_simplify_merge (gfc_expr *tsource, gfc_expr *fsource, gfc_expr *mask) gfc_constructor *tsource_ctor, *fsource_ctor, *mask_ctor; if (mask->expr_type == EXPR_CONSTANT) - return gfc_get_parentheses (gfc_copy_expr (mask->value.logical - ? tsource : fsource)); + { + result = gfc_copy_expr (mask->value.logical ? tsource : fsource); + /* Parenthesis is needed to get lower bounds of 1. */ + result = gfc_get_parentheses (result); + gfc_simplify_expr (result, 1); + return result; + } if (!mask->rank || !is_constant_array_expr (mask) || !is_constant_array_expr (tsource) || !is_constant_array_expr (fsource)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 62766c2..8bb7e7a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-13 Steven G. Kargl + + PR fortran/91566 + * gfortran.dg/pr91566.f90: + 2019-09-13 Bernd Edlinger PR fortran/91716 diff --git a/gcc/testsuite/gfortran.dg/pr91566.f90 b/gcc/testsuite/gfortran.dg/pr91566.f90 new file mode 100644 index 0000000..fdb35b4 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr91566.f90 @@ -0,0 +1,14 @@ +! { dg-do compile } +! Code contributed by Gerhard Steinmetz +program p + call q + call r +end program p + +subroutine q + print *, -merge([3,4], 0, [.false.,.true.]) +end + +subroutine r + print *, 2 + merge([3,4], 0, [.false.,.true.]) +end -- cgit v1.1 From f3898644854c846c3d28d6b2300bf40283d88c94 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sat, 14 Sep 2019 00:16:25 +0000 Subject: Daily bump. From-SVN: r275709 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 8c87078..fce7d42 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20190913 +20190914 -- cgit v1.1 From 603a4ad49978d2a967a1996ac626531200553715 Mon Sep 17 00:00:00 2001 From: Kewen Lin Date: Sat, 14 Sep 2019 09:01:21 +0000 Subject: Consider doloop IV in IVOPTs For the targets supporting low-overhead loops, IVOPTs has to take care of the loops which will probably be transformed in RTL doloop optimization, to try to make selected IV candidate set optimal. The process of doloop support includes: 1) Analyze the current loop will be transformed to doloop or not, find and mark its compare type IV use as doloop use (iv_group field doloop_p), and set flag doloop_use_p of ivopts_data to notify subsequent processings on doloop. See analyze_and_mark_doloop_use and its callees for the details. The target hook predict_doloop_p can be used for target specific checks. 2) Add one doloop dedicated IV cand {(may_be_zero ? 1 : (niter + 1)), +, -1}, set flag doloop_p of iv_cand, step cost is set as zero and no extra cost like biv. For cost determination between doloop IV cand and IV use, the target hooks doloop_cost_for_generic and doloop_cost_for_address are provided to add on extra costs for generic type and address type IV use. Zero cost is assigned to the pair between doloop IV cand and doloop IV use, and bound zero is set for IV elimination. 3) With the cost setting in step 2), the current cost model based IV selection algorithm will process as usual, pick up doloop dedicated IV if profitable. gcc/ChangeLog 2019-09-14 Kewen Lin PR middle-end/80791 * config/rs6000/rs6000.c (TARGET_HAVE_COUNT_REG_DECR_P): New macro. (TARGET_DOLOOP_COST_FOR_GENERIC): Likewise. (TARGET_DOLOOP_COST_FOR_ADDRESS): Likewise. * target.def (have_count_reg_decr_p): New hook. (doloop_cost_for_generic): Likewise. (doloop_cost_for_address): Likewise. * doc/tm.texi.in (TARGET_HAVE_COUNT_REG_DECR_P): Likewise. (TARGET_DOLOOP_COST_FOR_GENERIC): Likewise. (TARGET_DOLOOP_COST_FOR_ADDRESS): Likewise. * doc/tm.texi: Regenerate. * tree-ssa-loop-ivopts.c (comp_cost::operator+=): Consider infinite cost addend. (record_group): Init doloop_p. (add_candidate_1): Add optional argument doloop, change the handlings accordingly. (add_candidate): Likewise. (generic_predict_doloop_p): Update attribute. (force_expr_to_var_cost): Add costing for expressions COND_EXPR/LT_EXPR/ LE_EXPR/GT_EXPR/GE_EXPR/EQ_EXPR/NE_EXPR/UNORDERED_EXPR/ORDERED_EXPR/ UNLT_EXPR/UNLE_EXPR/UNGT_EXPR/UNGE_EXPR/UNEQ_EXPR/LTGT_EXPR/MAX_EXPR/ MIN_EXPR. (get_computation_cost): Update for doloop IV cand extra cost. (determine_group_iv_cost_cond): Update for doloop IV cand. (determine_iv_cost): Likewise. (ivopts_estimate_reg_pressure): Likewise. (may_eliminate_iv): Update handlings for doloop IV cand. (add_iv_candidate_for_doloop): New function. (find_iv_candidates): Call function add_iv_candidate_for_doloop. (iv_ca_set_no_cp): Update for doloop IV cand. (iv_ca_set_cp): Likewise. (iv_ca_dump): Dump register cost. (find_doloop_use): New function. (analyze_and_mark_doloop_use): Likewise. (tree_ssa_iv_optimize_loop): Call function analyze_and_mark_doloop_use. gcc/testsuite/ChangeLog 2019-09-14 Kewen Lin PR middle-end/80791 * gcc.dg/tree-ssa/ivopts-3.c: Adjust for doloop change. * gcc.dg/tree-ssa/ivopts-lt.c: Likewise. * gcc.dg/tree-ssa/pr32044.c: Likewise. From-SVN: r275713 --- gcc/ChangeLog | 38 ++++ gcc/config/rs6000/rs6000.c | 10 ++ gcc/doc/tm.texi | 30 ++++ gcc/doc/tm.texi.in | 6 + gcc/target.def | 33 ++++ gcc/testsuite/ChangeLog | 7 + gcc/testsuite/gcc.dg/tree-ssa/ivopts-3.c | 4 +- gcc/testsuite/gcc.dg/tree-ssa/ivopts-lt.c | 7 +- gcc/testsuite/gcc.dg/tree-ssa/pr32044.c | 4 + gcc/tree-ssa-loop-ivopts.c | 287 +++++++++++++++++++++++++++--- 10 files changed, 400 insertions(+), 26 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9bfc0e4..41cf926 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,41 @@ +2019-09-14 Kewen Lin + + PR middle-end/80791 + * config/rs6000/rs6000.c (TARGET_HAVE_COUNT_REG_DECR_P): New macro. + (TARGET_DOLOOP_COST_FOR_GENERIC): Likewise. + (TARGET_DOLOOP_COST_FOR_ADDRESS): Likewise. + * target.def (have_count_reg_decr_p): New hook. + (doloop_cost_for_generic): Likewise. + (doloop_cost_for_address): Likewise. + * doc/tm.texi.in (TARGET_HAVE_COUNT_REG_DECR_P): Likewise. + (TARGET_DOLOOP_COST_FOR_GENERIC): Likewise. + (TARGET_DOLOOP_COST_FOR_ADDRESS): Likewise. + * doc/tm.texi: Regenerate. + * tree-ssa-loop-ivopts.c (comp_cost::operator+=): Consider infinite cost + addend. + (record_group): Init doloop_p. + (add_candidate_1): Add optional argument doloop, change the handlings + accordingly. + (add_candidate): Likewise. + (generic_predict_doloop_p): Update attribute. + (force_expr_to_var_cost): Add costing for expressions COND_EXPR/LT_EXPR/ + LE_EXPR/GT_EXPR/GE_EXPR/EQ_EXPR/NE_EXPR/UNORDERED_EXPR/ORDERED_EXPR/ + UNLT_EXPR/UNLE_EXPR/UNGT_EXPR/UNGE_EXPR/UNEQ_EXPR/LTGT_EXPR/MAX_EXPR/ + MIN_EXPR. + (get_computation_cost): Update for doloop IV cand extra cost. + (determine_group_iv_cost_cond): Update for doloop IV cand. + (determine_iv_cost): Likewise. + (ivopts_estimate_reg_pressure): Likewise. + (may_eliminate_iv): Update handlings for doloop IV cand. + (add_iv_candidate_for_doloop): New function. + (find_iv_candidates): Call function add_iv_candidate_for_doloop. + (iv_ca_set_no_cp): Update for doloop IV cand. + (iv_ca_set_cp): Likewise. + (iv_ca_dump): Dump register cost. + (find_doloop_use): New function. + (analyze_and_mark_doloop_use): Likewise. + (tree_ssa_iv_optimize_loop): Call function analyze_and_mark_doloop_use. + 2019-09-13 Bernd Edlinger PR middle-end/91708 diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 217548c..c2834bd 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1651,6 +1651,16 @@ static const struct attribute_spec rs6000_attribute_table[] = #undef TARGET_PREDICT_DOLOOP_P #define TARGET_PREDICT_DOLOOP_P rs6000_predict_doloop_p +#undef TARGET_HAVE_COUNT_REG_DECR_P +#define TARGET_HAVE_COUNT_REG_DECR_P true + +/* 1000000000 is infinite cost in IVOPTs. */ +#undef TARGET_DOLOOP_COST_FOR_GENERIC +#define TARGET_DOLOOP_COST_FOR_GENERIC 1000000000 + +#undef TARGET_DOLOOP_COST_FOR_ADDRESS +#define TARGET_DOLOOP_COST_FOR_ADDRESS 1000000000 + #undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV #define TARGET_ATOMIC_ASSIGN_EXPAND_FENV rs6000_atomic_assign_expand_fenv diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 159ccd2..0250cf5 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -11615,6 +11615,36 @@ loops, and will help ivopts to make some decisions. The default version of this hook returns false. @end deftypefn +@deftypevr {Target Hook} bool TARGET_HAVE_COUNT_REG_DECR_P +Return true if the target supports hardware count register for decrement +and branch. +The default value is false. +@end deftypevr + +@deftypevr {Target Hook} int64_t TARGET_DOLOOP_COST_FOR_GENERIC +One IV candidate dedicated for doloop is introduced in IVOPTs, we can +calculate the computation cost of adopting it to any generic IV use by +function get_computation_cost as before. But for targets which have +hardware count register support for decrement and branch, it may have to +move IV value from hardware count register to general purpose register +while doloop IV candidate is used for generic IV uses. It probably takes +expensive penalty. This hook allows target owners to define the cost for +this especially for generic IV uses. +The default value is zero. +@end deftypevr + +@deftypevr {Target Hook} int64_t TARGET_DOLOOP_COST_FOR_ADDRESS +One IV candidate dedicated for doloop is introduced in IVOPTs, we can +calculate the computation cost of adopting it to any address IV use by +function get_computation_cost as before. But for targets which have +hardware count register support for decrement and branch, it may have to +move IV value from hardware count register to general purpose register +while doloop IV candidate is used for address IV uses. It probably takes +expensive penalty. This hook allows target owners to define the cost for +this escpecially for address IV uses. +The default value is zero. +@end deftypevr + @deftypefn {Target Hook} bool TARGET_CAN_USE_DOLOOP_P (const widest_int @var{&iterations}, const widest_int @var{&iterations_max}, unsigned int @var{loop_depth}, bool @var{entered_at_top}) Return true if it is possible to use low-overhead loops (@code{doloop_end} and @code{doloop_begin}) for a particular loop. @var{iterations} gives the diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 91a2d2b..0b77dd8 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -7950,6 +7950,12 @@ to by @var{ce_info}. @hook TARGET_PREDICT_DOLOOP_P +@hook TARGET_HAVE_COUNT_REG_DECR_P + +@hook TARGET_DOLOOP_COST_FOR_GENERIC + +@hook TARGET_DOLOOP_COST_FOR_ADDRESS + @hook TARGET_CAN_USE_DOLOOP_P @hook TARGET_INVALID_WITHIN_DOLOOP diff --git a/gcc/target.def b/gcc/target.def index 825c1e6..0160913 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -4225,6 +4225,39 @@ The default version of this hook returns false.", bool, (class loop *loop), default_predict_doloop_p) +DEFHOOKPOD +(have_count_reg_decr_p, + "Return true if the target supports hardware count register for decrement\n\ +and branch.\n\ +The default value is false.", + bool, false) + +DEFHOOKPOD +(doloop_cost_for_generic, + "One IV candidate dedicated for doloop is introduced in IVOPTs, we can\n\ +calculate the computation cost of adopting it to any generic IV use by\n\ +function get_computation_cost as before. But for targets which have\n\ +hardware count register support for decrement and branch, it may have to\n\ +move IV value from hardware count register to general purpose register\n\ +while doloop IV candidate is used for generic IV uses. It probably takes\n\ +expensive penalty. This hook allows target owners to define the cost for\n\ +this especially for generic IV uses.\n\ +The default value is zero.", + int64_t, 0) + +DEFHOOKPOD +(doloop_cost_for_address, + "One IV candidate dedicated for doloop is introduced in IVOPTs, we can\n\ +calculate the computation cost of adopting it to any address IV use by\n\ +function get_computation_cost as before. But for targets which have\n\ +hardware count register support for decrement and branch, it may have to\n\ +move IV value from hardware count register to general purpose register\n\ +while doloop IV candidate is used for address IV uses. It probably takes\n\ +expensive penalty. This hook allows target owners to define the cost for\n\ +this escpecially for address IV uses.\n\ +The default value is zero.", + int64_t, 0) + DEFHOOK (can_use_doloop_p, "Return true if it is possible to use low-overhead loops (@code{doloop_end}\n\ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8bb7e7a..c950a0d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2019-09-14 Kewen Lin + + PR middle-end/80791 + * gcc.dg/tree-ssa/ivopts-3.c: Adjust for doloop change. + * gcc.dg/tree-ssa/ivopts-lt.c: Likewise. + * gcc.dg/tree-ssa/pr32044.c: Likewise. + 2019-09-13 Steven G. Kargl PR fortran/91566 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ivopts-3.c b/gcc/testsuite/gcc.dg/tree-ssa/ivopts-3.c index 214e6a7..ce4b1d0 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ivopts-3.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ivopts-3.c @@ -10,4 +10,6 @@ int main (void) f2 (); } -/* { dg-final { scan-tree-dump-times "!= 0" 5 "ivopts" } } */ +/* { dg-final { scan-tree-dump-times "!= 0" 5 "ivopts" { target { ! powerpc*-*-* } } } } */ +/* More debug information emitted for doloop on powerpc. */ +/* { dg-final { scan-tree-dump-times "!= 0" 6 "ivopts" { target { powerpc*-*-* } } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ivopts-lt.c b/gcc/testsuite/gcc.dg/tree-ssa/ivopts-lt.c index 7d5859b..71d7f67 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ivopts-lt.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ivopts-lt.c @@ -17,6 +17,7 @@ f1 (char *p, uintptr_t i, uintptr_t n) while (i < n); } -/* { dg-final { scan-tree-dump-times "PHI" 1 "ivopts" } } */ -/* { dg-final { scan-tree-dump-times "PHI = 45) diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index 43ba429..4ab6d6f 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -64,7 +64,30 @@ along with GCC; see the file COPYING3. If not see All of this is done loop by loop. Doing it globally is theoretically possible, it might give a better performance and it might enable us to decide costs more precisely, but getting all the interactions right - would be complicated. */ + would be complicated. + + For the targets supporting low-overhead loops, IVOPTs has to take care of + the loops which will probably be transformed in RTL doloop optimization, + to try to make selected IV candidate set optimal. The process of doloop + support includes: + + 1) Analyze the current loop will be transformed to doloop or not, find and + mark its compare type IV use as doloop use (iv_group field doloop_p), and + set flag doloop_use_p of ivopts_data to notify subsequent processings on + doloop. See analyze_and_mark_doloop_use and its callees for the details. + The target hook predict_doloop_p can be used for target specific checks. + + 2) Add one doloop dedicated IV cand {(may_be_zero ? 1 : (niter + 1)), +, -1}, + set flag doloop_p of iv_cand, step cost is set as zero and no extra cost + like biv. For cost determination between doloop IV cand and IV use, the + target hooks doloop_cost_for_generic and doloop_cost_for_address are + provided to add on extra costs for generic type and address type IV use. + Zero cost is assigned to the pair between doloop IV cand and doloop IV + use, and bound zero is set for IV elimination. + + 3) With the cost setting in step 2), the current cost model based IV + selection algorithm will process as usual, pick up doloop dedicated IV if + profitable. */ #include "config.h" #include "system.h" @@ -276,6 +299,9 @@ comp_cost::operator+= (comp_cost cost) comp_cost comp_cost::operator+= (HOST_WIDE_INT c) { + if (c >= INFTY) + this->cost = INFTY; + if (infinite_cost_p ()) return *this; @@ -401,6 +427,8 @@ struct iv_group class cost_pair *cost_map; /* The selected candidate for the group. */ struct iv_cand *selected; + /* To indicate this is a doloop use group. */ + bool doloop_p; /* Uses in the group. */ vec vuses; }; @@ -441,6 +469,7 @@ struct iv_cand be hoisted out of loop. */ struct iv *orig_iv; /* The original iv if this cand is added from biv with smaller type. */ + bool doloop_p; /* Whether this is a doloop candidate. */ }; /* Hashtable entry for common candidate derived from iv uses. */ @@ -618,6 +647,9 @@ struct ivopts_data /* Whether the loop body can only be exited via single exit. */ bool loop_single_exit_p; + + /* Whether the loop has doloop comparison use. */ + bool doloop_use_p; }; /* An assignment of iv candidates to uses. */ @@ -1542,6 +1574,7 @@ record_group (struct ivopts_data *data, enum use_type type) group->type = type; group->related_cands = BITMAP_ALLOC (NULL); group->vuses.create (1); + group->doloop_p = false; data->vgroups.safe_push (group); return group; @@ -3033,10 +3066,10 @@ get_loop_invariant_expr (struct ivopts_data *data, tree inv_expr) replacement of the final value of the iv by a direct computation. */ static struct iv_cand * -add_candidate_1 (struct ivopts_data *data, - tree base, tree step, bool important, enum iv_position pos, - struct iv_use *use, gimple *incremented_at, - struct iv *orig_iv = NULL) +add_candidate_1 (struct ivopts_data *data, tree base, tree step, bool important, + enum iv_position pos, struct iv_use *use, + gimple *incremented_at, struct iv *orig_iv = NULL, + bool doloop = false) { unsigned i; struct iv_cand *cand = NULL; @@ -3095,11 +3128,15 @@ add_candidate_1 (struct ivopts_data *data, cand->pos = pos; if (pos != IP_ORIGINAL) { - cand->var_before = create_tmp_var_raw (TREE_TYPE (base), "ivtmp"); + if (doloop) + cand->var_before = create_tmp_var_raw (TREE_TYPE (base), "doloop"); + else + cand->var_before = create_tmp_var_raw (TREE_TYPE (base), "ivtmp"); cand->var_after = cand->var_before; } cand->important = important; cand->incremented_at = incremented_at; + cand->doloop_p = doloop; data->vcands.safe_push (cand); if (!poly_int_tree_p (step)) @@ -3132,6 +3169,7 @@ add_candidate_1 (struct ivopts_data *data, } cand->important |= important; + cand->doloop_p |= doloop; /* Relate candidate to the group for which it is added. */ if (use) @@ -3225,14 +3263,16 @@ add_autoinc_candidates (struct ivopts_data *data, tree base, tree step, the end of loop. */ static void -add_candidate (struct ivopts_data *data, - tree base, tree step, bool important, struct iv_use *use, - struct iv *orig_iv = NULL) +add_candidate (struct ivopts_data *data, tree base, tree step, bool important, + struct iv_use *use, struct iv *orig_iv = NULL, + bool doloop = false) { if (ip_normal_pos (data->current_loop)) - add_candidate_1 (data, base, step, important, - IP_NORMAL, use, NULL, orig_iv); - if (ip_end_pos (data->current_loop) + add_candidate_1 (data, base, step, important, IP_NORMAL, use, NULL, orig_iv, + doloop); + /* Exclude doloop candidate here since it requires decrement then comparison + and jump, the IP_END position doesn't match. */ + if (!doloop && ip_end_pos (data->current_loop) && allow_ip_end_pos_p (data->current_loop)) add_candidate_1 (data, base, step, important, IP_END, use, NULL, orig_iv); } @@ -3760,7 +3800,7 @@ prepare_decl_rtl (tree *expr_p, int *ws, void *data) Some RTL specific checks seems unable to be checked in gimple, if any new checks or easy checks _are_ missing here, please add them. */ -static bool ATTRIBUTE_UNUSED +static bool generic_predict_doloop_p (struct ivopts_data *data) { class loop *loop = data->current_loop; @@ -4213,6 +4253,36 @@ force_expr_to_var_cost (tree expr, bool speed) STRIP_NOPS (op0); op1 = NULL_TREE; break; + /* See add_iv_candidate_for_doloop, for doloop may_be_zero case, we + introduce COND_EXPR for IV base, need to support better cost estimation + for this COND_EXPR and tcc_comparison. */ + case COND_EXPR: + op0 = TREE_OPERAND (expr, 1); + STRIP_NOPS (op0); + op1 = TREE_OPERAND (expr, 2); + STRIP_NOPS (op1); + break; + case LT_EXPR: + case LE_EXPR: + case GT_EXPR: + case GE_EXPR: + case EQ_EXPR: + case NE_EXPR: + case UNORDERED_EXPR: + case ORDERED_EXPR: + case UNLT_EXPR: + case UNLE_EXPR: + case UNGT_EXPR: + case UNGE_EXPR: + case UNEQ_EXPR: + case LTGT_EXPR: + case MAX_EXPR: + case MIN_EXPR: + op0 = TREE_OPERAND (expr, 0); + STRIP_NOPS (op0); + op1 = TREE_OPERAND (expr, 1); + STRIP_NOPS (op1); + break; default: /* Just an arbitrary value, FIXME. */ @@ -4294,6 +4364,35 @@ force_expr_to_var_cost (tree expr, bool speed) case RSHIFT_EXPR: cost = comp_cost (add_cost (speed, mode), 0); break; + case COND_EXPR: + op0 = TREE_OPERAND (expr, 0); + STRIP_NOPS (op0); + if (op0 == NULL_TREE || TREE_CODE (op0) == SSA_NAME + || CONSTANT_CLASS_P (op0)) + cost = no_cost; + else + cost = force_expr_to_var_cost (op0, speed); + break; + case LT_EXPR: + case LE_EXPR: + case GT_EXPR: + case GE_EXPR: + case EQ_EXPR: + case NE_EXPR: + case UNORDERED_EXPR: + case ORDERED_EXPR: + case UNLT_EXPR: + case UNLE_EXPR: + case UNGT_EXPR: + case UNGE_EXPR: + case UNEQ_EXPR: + case LTGT_EXPR: + case MAX_EXPR: + case MIN_EXPR: + /* Simply use add cost for now, FIXME if there is some more accurate cost + evaluation way. */ + cost = comp_cost (add_cost (speed, mode), 0); + break; default: gcc_unreachable (); @@ -4670,7 +4769,10 @@ get_computation_cost (struct ivopts_data *data, struct iv_use *use, { cost = get_address_cost (data, use, cand, &aff_inv, &aff_var, ratio, inv_vars, inv_expr, can_autoinc, speed); - return get_scaled_computation_cost_at (data, at, cost); + cost = get_scaled_computation_cost_at (data, at, cost); + /* For doloop IV cand, add on the extra cost. */ + cost += cand->doloop_p ? targetm.doloop_cost_for_address : 0; + return cost; } bool simple_inv = (aff_combination_const_p (&aff_inv) @@ -4720,7 +4822,13 @@ get_computation_cost (struct ivopts_data *data, struct iv_use *use, if (comp_inv && !integer_zerop (comp_inv)) cost += add_cost (speed, TYPE_MODE (utype)); - return get_scaled_computation_cost_at (data, at, cost); + cost = get_scaled_computation_cost_at (data, at, cost); + + /* For doloop IV cand, add on the extra cost. */ + if (cand->doloop_p && use->type == USE_NONLINEAR_EXPR) + cost += targetm.doloop_cost_for_generic; + + return cost; } /* Determines cost of computing the use in GROUP with CAND in a generic @@ -5178,6 +5286,15 @@ may_eliminate_iv (struct ivopts_data *data, } } + /* For doloop IV cand, the bound would be zero. It's safe whether + may_be_zero set or not. */ + if (cand->doloop_p) + { + *bound = build_int_cst (TREE_TYPE (cand->iv->base), 0); + *comp = iv_elimination_compare (data, use); + return true; + } + cand_value_at (loop, cand, use->stmt, desc->niter, &bnd); *bound = fold_convert (TREE_TYPE (cand->iv->base), @@ -5300,6 +5417,9 @@ determine_group_iv_cost_cond (struct ivopts_data *data, inv_vars = inv_vars_elim; inv_vars_elim = NULL; inv_expr = inv_expr_elim; + /* For doloop candidate/use pair, adjust to zero cost. */ + if (group->doloop_p && cand->doloop_p && elim_cost.cost > no_cost.cost) + cost = no_cost; } else { @@ -5426,6 +5546,42 @@ relate_compare_use_with_all_cands (struct ivopts_data *data) } } +/* Add one doloop dedicated IV candidate: + - Base is (may_be_zero ? 1 : (niter + 1)). + - Step is -1. */ + +static void +add_iv_candidate_for_doloop (struct ivopts_data *data) +{ + tree_niter_desc *niter_desc = niter_for_single_dom_exit (data); + gcc_assert (niter_desc && niter_desc->assumptions); + + tree niter = niter_desc->niter; + tree ntype = TREE_TYPE (niter); + gcc_assert (TREE_CODE (ntype) == INTEGER_TYPE); + + tree may_be_zero = niter_desc->may_be_zero; + if (may_be_zero && integer_zerop (may_be_zero)) + may_be_zero = NULL_TREE; + if (may_be_zero) + { + if (COMPARISON_CLASS_P (may_be_zero)) + { + niter = fold_build3 (COND_EXPR, ntype, may_be_zero, + build_int_cst (ntype, 0), + rewrite_to_non_trapping_overflow (niter)); + } + /* Don't try to obtain the iteration count expression when may_be_zero is + integer_nonzerop (actually iteration count is one) or else. */ + else + return; + } + + tree base = fold_build2 (PLUS_EXPR, ntype, unshare_expr (niter), + build_int_cst (ntype, 1)); + add_candidate (data, base, build_int_cst (ntype, -1), true, NULL, NULL, true); +} + /* Finds the candidates for the induction variables. */ static void @@ -5434,6 +5590,10 @@ find_iv_candidates (struct ivopts_data *data) /* Add commonly used ivs. */ add_standard_iv_candidates (data); + /* Add doloop dedicated ivs. */ + if (data->doloop_use_p) + add_iv_candidate_for_doloop (data); + /* Add old induction variables. */ add_iv_candidate_for_bivs (data); @@ -5614,16 +5774,21 @@ determine_iv_cost (struct ivopts_data *data, struct iv_cand *cand) or a const set. */ if (cost_base.cost == 0) cost_base.cost = COSTS_N_INSNS (1); - cost_step = add_cost (data->speed, TYPE_MODE (TREE_TYPE (base))); - + /* Doloop decrement should be considered as zero cost. */ + if (cand->doloop_p) + cost_step = 0; + else + cost_step = add_cost (data->speed, TYPE_MODE (TREE_TYPE (base))); cost = cost_step + adjust_setup_cost (data, cost_base.cost); /* Prefer the original ivs unless we may gain something by replacing it. The reason is to make debugging simpler; so this is not relevant for artificial ivs created by other optimization passes. */ - if (cand->pos != IP_ORIGINAL - || !SSA_NAME_VAR (cand->var_before) - || DECL_ARTIFICIAL (SSA_NAME_VAR (cand->var_before))) + if ((cand->pos != IP_ORIGINAL + || !SSA_NAME_VAR (cand->var_before) + || DECL_ARTIFICIAL (SSA_NAME_VAR (cand->var_before))) + /* Prefer doloop as well. */ + && !cand->doloop_p) cost++; /* Prefer not to insert statements into latch unless there are some @@ -5868,7 +6033,8 @@ iv_ca_set_no_cp (struct ivopts_data *data, class iv_ca *ivs, if (ivs->n_cand_uses[cid] == 0) { bitmap_clear_bit (ivs->cands, cid); - ivs->n_cands--; + if (!cp->cand->doloop_p || !targetm.have_count_reg_decr_p) + ivs->n_cands--; ivs->cand_cost -= cp->cand->cost; iv_ca_set_remove_invs (ivs, cp->cand->inv_vars, ivs->n_inv_var_uses); iv_ca_set_remove_invs (ivs, cp->cand->inv_exprs, ivs->n_inv_expr_uses); @@ -5925,7 +6091,8 @@ iv_ca_set_cp (struct ivopts_data *data, class iv_ca *ivs, if (ivs->n_cand_uses[cid] == 1) { bitmap_set_bit (ivs->cands, cid); - ivs->n_cands++; + if (!cp->cand->doloop_p || !targetm.have_count_reg_decr_p) + ivs->n_cands++; ivs->cand_cost += cp->cand->cost; iv_ca_set_add_invs (ivs, cp->cand->inv_vars, ivs->n_inv_var_uses); iv_ca_set_add_invs (ivs, cp->cand->inv_exprs, ivs->n_inv_expr_uses); @@ -6170,6 +6337,8 @@ iv_ca_dump (struct ivopts_data *data, FILE *file, class iv_ca *ivs) fprintf (file, " cost: %" PRId64 " (complexity %d)\n", cost.cost, cost.complexity); + fprintf (file, " reg_cost: %d\n", + ivopts_estimate_reg_pressure (data, ivs->n_invs, ivs->n_cands)); fprintf (file, " cand_cost: %" PRId64 "\n cand_group_cost: " "%" PRId64 " (complexity %d)\n", ivs->cand_cost, ivs->cand_use_cost.cost, ivs->cand_use_cost.complexity); @@ -7608,6 +7777,77 @@ determine_scaling_factor (struct ivopts_data *data, basic_block *body) } } +/* Find doloop comparison use and set its doloop_p on if found. */ + +static bool +find_doloop_use (struct ivopts_data *data) +{ + struct loop *loop = data->current_loop; + + for (unsigned i = 0; i < data->vgroups.length (); i++) + { + struct iv_group *group = data->vgroups[i]; + if (group->type == USE_COMPARE) + { + gcc_assert (group->vuses.length () == 1); + struct iv_use *use = group->vuses[0]; + gimple *stmt = use->stmt; + if (gimple_code (stmt) == GIMPLE_COND) + { + basic_block bb = gimple_bb (stmt); + edge true_edge, false_edge; + extract_true_false_edges_from_block (bb, &true_edge, &false_edge); + /* This comparison is used for loop latch. Require latch is empty + for now. */ + if ((loop->latch == true_edge->dest + || loop->latch == false_edge->dest) + && empty_block_p (loop->latch)) + { + group->doloop_p = true; + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Doloop cmp iv use: "); + print_gimple_stmt (dump_file, stmt, TDF_DETAILS); + } + return true; + } + } + } + } + + return false; +} + +/* For the targets which support doloop, to predict whether later RTL doloop + transformation will perform on this loop, further detect the doloop use and + mark the flag doloop_use_p if predicted. */ + +void +analyze_and_mark_doloop_use (struct ivopts_data *data) +{ + data->doloop_use_p = false; + + if (!flag_branch_on_count_reg) + return; + + if (!generic_predict_doloop_p (data)) + return; + + if (find_doloop_use (data)) + { + data->doloop_use_p = true; + if (dump_file && (dump_flags & TDF_DETAILS)) + { + struct loop *loop = data->current_loop; + fprintf (dump_file, + "Predict loop %d can perform" + " doloop optimization later.\n", + loop->num); + flow_loop_dump (loop, dump_file, NULL, 1); + } + } +} + /* Optimizes the LOOP. Returns true if anything changed. */ static bool @@ -7662,6 +7902,9 @@ tree_ssa_iv_optimize_loop (struct ivopts_data *data, class loop *loop, /* Determine cost scaling factor for basic blocks in loop. */ determine_scaling_factor (data, body); + /* Analyze doloop possibility and mark the doloop use if predicted. */ + analyze_and_mark_doloop_use (data); + /* Finds candidates for the induction variables (item 2). */ find_iv_candidates (data); -- cgit v1.1 From 62dca3d53ee985e5fd69eb5e2611a8d157ea7bdc Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Sat, 14 Sep 2019 14:45:46 -0400 Subject: Formatting and comment syntax adjustments. From-SVN: r275717 --- gcc/cp/class.c | 2 +- gcc/cp/cp-tree.h | 36 ++++++++++++++++++------------------ gcc/cp/decl.c | 4 ++-- gcc/cp/parser.c | 14 ++++++++------ 4 files changed, 29 insertions(+), 27 deletions(-) (limited to 'gcc') diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 20cfd10..a8332ab 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -4605,7 +4605,7 @@ build_clone (tree fn, tree name) } else { - // Clone constraints. + /* Clone constraints. */ if (flag_concepts) if (tree ci = get_constraints (fn)) set_constraints (clone, copy_node (ci)); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 95e5eda..793847d 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1470,7 +1470,7 @@ check_nonnull (T* p) return p; } -// Returns true iff T is non-null and represents constraint info. +/* Returns true iff T is non-null and represents constraint info. */ inline tree_constraint_info * check_constraint_info (tree t) { @@ -1479,35 +1479,35 @@ check_constraint_info (tree t) return NULL; } -// Access the expression describing the template constraints. This may be -// null if no constraints were introduced in the template parameter list, -// a requirements clause after the template parameter list, or constraints -// through a constrained-type-specifier. +/* Access the expression describing the template constraints. This may be + null if no constraints were introduced in the template parameter list, + a requirements clause after the template parameter list, or constraints + through a constrained-type-specifier. */ #define CI_TEMPLATE_REQS(NODE) \ - check_constraint_info (check_nonnull(NODE))->template_reqs + check_constraint_info (check_nonnull (NODE))->template_reqs -// Access the expression describing the trailing constraints. This is non-null -// for any implicit instantiation of a constrained declaration. For a -// templated declaration it is non-null only when a trailing requires-clause -// was specified. +/* Access the expression describing the trailing constraints. This is non-null + for any implicit instantiation of a constrained declaration. For a + templated declaration it is non-null only when a trailing requires-clause + was specified. */ #define CI_DECLARATOR_REQS(NODE) \ - check_constraint_info (check_nonnull(NODE))->declarator_reqs + check_constraint_info (check_nonnull (NODE))->declarator_reqs -// The computed associated constraint expression for a declaration. +/* The computed associated constraint expression for a declaration. */ #define CI_ASSOCIATED_CONSTRAINTS(NODE) \ - check_constraint_info (check_nonnull(NODE))->associated_constr + check_constraint_info (check_nonnull (NODE))->associated_constr -// Access the logical constraints on the template parameters introduced -// at a given template parameter list level indicated by NODE. +/* Access the constraint-expression introduced by the requires-clause + associate the template parameter list NODE. */ #define TEMPLATE_PARMS_CONSTRAINTS(NODE) \ TREE_TYPE (TREE_LIST_CHECK (NODE)) -// Access the logical constraints on the template parameter declaration -// indicated by NODE. +/* Access the logical constraints on the template parameter declaration + indicated by NODE. */ #define TEMPLATE_PARM_CONSTRAINTS(NODE) \ TREE_TYPE (TREE_LIST_CHECK (NODE)) -/* Non-zero if the noexcept is present in a compound requirement. */ +/* Non-zero if the noexcept is present in a compound requirement. */ #define COMPOUND_REQ_NOEXCEPT_P(NODE) \ TREE_LANG_FLAG_0 (TREE_CHECK (NODE, COMPOUND_REQ)) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 9218eef..e0d6732 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -8949,10 +8949,10 @@ grokfndecl (tree ctype, if (location == UNKNOWN_LOCATION) location = input_location; - // Was the concept specifier present? + /* Was the concept specifier present? */ bool concept_p = inlinep & 4; - // Concept declarations must have a corresponding definition. + /* Concept declarations must have a corresponding definition. */ if (concept_p && !funcdef_flag) { error_at (location, "concept %qD has no definition", declarator); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 254a77b..b2fb150 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -19734,7 +19734,7 @@ cp_parser_alias_declaration (cp_parser* parser) if (decl == error_mark_node) return decl; - // Attach constraints to the alias declaration. + /* Attach constraints to the alias declaration. */ if (flag_concepts && current_template_parms) { tree reqs = TEMPLATE_PARMS_CONSTRAINTS (current_template_parms); @@ -22551,12 +22551,14 @@ cp_parser_parameter_declaration (cp_parser *parser, && !LAMBDA_TYPE_P (current_class_type)) default_argument = cp_parser_cache_defarg (parser, /*nsdmi=*/false); - // A constrained-type-specifier may declare a type template-parameter. + /* A constrained-type-specifier may declare a type + template-parameter. */ else if (declares_constrained_type_template_parameter (type)) default_argument = cp_parser_default_type_template_argument (parser); - // A constrained-type-specifier may declare a template-template-parameter. + /* A constrained-type-specifier may declare a + template-template-parameter. */ else if (declares_constrained_template_template_parameter (type)) default_argument = cp_parser_default_template_template_argument (parser); @@ -28475,9 +28477,9 @@ cp_parser_single_declaration (cp_parser* parser, if (cp_parser_declares_only_class_p (parser) || (declares_class_or_enum & 2)) { - // If this is a declaration, but not a definition, associate - // any constraints with the type declaration. Constraints - // are associated with definitions in cp_parser_class_specifier. + /* If this is a declaration, but not a definition, associate + any constraints with the type declaration. Constraints + are associated with definitions in cp_parser_class_specifier. */ if (declares_class_or_enum == 1) associate_classtype_constraints (decl_specifiers.type); -- cgit v1.1 From df19f4717db02943c2ddee1e9f632581537f6c78 Mon Sep 17 00:00:00 2001 From: Sandra Loosemore Date: Sat, 14 Sep 2019 15:00:15 -0400 Subject: re PR middle-end/83889 (new failures on some arm targets after r256644) 2019-09-14 Sandra Loosemore PR testsuite/83889 gcc/testsuite/ * g++.dg/vect/pr87914.cc: Remove explicit dg-do run. From-SVN: r275718 --- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/vect/pr87914.cc | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c950a0d..45ab4ea 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-14 Sandra Loosemore + + PR testsuite/83889 + * g++.dg/vect/pr87914.cc: Remove explicit dg-do run. + 2019-09-14 Kewen Lin PR middle-end/80791 diff --git a/gcc/testsuite/g++.dg/vect/pr87914.cc b/gcc/testsuite/g++.dg/vect/pr87914.cc index 12fbba3..c692ffa 100644 --- a/gcc/testsuite/g++.dg/vect/pr87914.cc +++ b/gcc/testsuite/g++.dg/vect/pr87914.cc @@ -1,4 +1,3 @@ -// { dg-do run } // { dg-additional-options "-fopenmp-simd" } // { dg-additional-options "-mavx2" { target { avx2_runtime } } } -- cgit v1.1 From e0b9e5f9e3c90a55e643ea850cf828e3e6480fb5 Mon Sep 17 00:00:00 2001 From: Thomas Koenig Date: Sat, 14 Sep 2019 20:40:55 +0000 Subject: re PR fortran/91557 (Bogus warning about unused dummy argument _formal_*) 2019-09-14 Thomas Koenig PR fortran/91557 PR fortran/91556 * frontend-passes.c (check_externals_procedure): Reformat argument list. Use gfc_compare_actual_formal instead of gfc_procedure_use. * gfortran.h (gfc_symbol): Add flag error. * interface.c (gfc_compare_interfaces): Reformat. (argument_rank_mismatch): Add where_formal argument. If it is present, note that the error is between different calls. (compare_parameter): Change warnings that previously dependended on -Wargument-mismatch to unconditional. Issue an error / warning on type mismatch only once. Pass where_formal to argument_rank_mismatch for artificial variables. (compare_actual_formal): Change warnings that previously dependeded on -Wargument-mismatch to unconditional. (gfc_check_typebound_override): Likewise. (gfc_get_formal_from_actual_arglist): Set declared_at for artificial symbol. * invoke.texi: Extend description of -fallow-argument-mismatch. Delete -Wargument-mismatch. * lang.opt: Change -Wargument-mismatch to do-nothing option. * resolve.c (resolve_structure_cons): Change warnings that previously depended on -Wargument-mismatch to unconditional. * trans-decl.c (generate_local_decl): Do not warn if the symbol is artificial. 2019-09-14 Thomas Koenig PR fortran/91557 PR fortran/91556 * gfortran.dg/argument_checking_20.f90: New test. * gfortran.dg/argument_checking_21.f90: New test. * gfortran.dg/argument_checking_22.f90: New test. * gfortran.dg/argument_checking_23.f90: New test. * gfortran.dg/warn_unused_dummy_argument_5.f90: New test. * gfortran.dg/bessel_3.f90: Add pattern for type mismatch. * gfortran.dg/g77/20010519-1.f: Adjust dg-warning messages to new handling. * gfortran.dg/pr24823.f: Likewise. * gfortran.dg/pr39937.f: Likewise. From-SVN: r275719 --- gcc/fortran/ChangeLog | 27 +++++ gcc/fortran/frontend-passes.c | 5 +- gcc/fortran/gfortran.h | 3 + gcc/fortran/interface.c | 120 ++++++++++++++------- gcc/fortran/invoke.texi | 22 ++-- gcc/fortran/lang.opt | 4 +- gcc/fortran/resolve.c | 6 +- gcc/fortran/trans-decl.c | 8 +- gcc/testsuite/ChangeLog | 15 +++ gcc/testsuite/gfortran.dg/argument_checking_20.f90 | 11 ++ gcc/testsuite/gfortran.dg/argument_checking_21.f90 | 12 +++ gcc/testsuite/gfortran.dg/argument_checking_22.f90 | 15 +++ gcc/testsuite/gfortran.dg/argument_checking_23.f90 | 16 +++ gcc/testsuite/gfortran.dg/bessel_3.f90 | 4 +- gcc/testsuite/gfortran.dg/g77/20010519-1.f | 8 +- gcc/testsuite/gfortran.dg/pr24823.f | 6 +- gcc/testsuite/gfortran.dg/pr39937.f | 6 +- .../gfortran.dg/warn_unused_dummy_argument_5.f90 | 16 +++ 18 files changed, 232 insertions(+), 72 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/argument_checking_20.f90 create mode 100644 gcc/testsuite/gfortran.dg/argument_checking_21.f90 create mode 100644 gcc/testsuite/gfortran.dg/argument_checking_22.f90 create mode 100644 gcc/testsuite/gfortran.dg/argument_checking_23.f90 create mode 100644 gcc/testsuite/gfortran.dg/warn_unused_dummy_argument_5.f90 (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 6f2ba75..56a107d 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,30 @@ +2019-09-14 Thomas Koenig + + PR fortran/91557 + PR fortran/91556 + * frontend-passes.c (check_externals_procedure): Reformat argument + list. Use gfc_compare_actual_formal instead of gfc_procedure_use. + * gfortran.h (gfc_symbol): Add flag error. + * interface.c (gfc_compare_interfaces): Reformat. + (argument_rank_mismatch): Add where_formal argument. If it is + present, note that the error is between different calls. + (compare_parameter): Change warnings that previously dependended + on -Wargument-mismatch to unconditional. Issue an error / warning + on type mismatch only once. Pass where_formal to + argument_rank_mismatch for artificial variables. + (compare_actual_formal): Change warnings that previously + dependeded on -Wargument-mismatch to unconditional. + (gfc_check_typebound_override): Likewise. + (gfc_get_formal_from_actual_arglist): Set declared_at for + artificial symbol. + * invoke.texi: Extend description of -fallow-argument-mismatch. + Delete -Wargument-mismatch. + * lang.opt: Change -Wargument-mismatch to do-nothing option. + * resolve.c (resolve_structure_cons): Change warnings that + previously depended on -Wargument-mismatch to unconditional. + * trans-decl.c (generate_local_decl): Do not warn if the symbol is + artificial. + 2019-09-13 Steven G. Kargl PR fortran/91566 diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c index 86debab..b095d5f 100644 --- a/gcc/fortran/frontend-passes.c +++ b/gcc/fortran/frontend-passes.c @@ -5373,7 +5373,8 @@ gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn, /* Common tests for argument checking for both functions and subroutines. */ static int -check_externals_procedure (gfc_symbol *sym, locus *loc, gfc_actual_arglist *actual) +check_externals_procedure (gfc_symbol *sym, locus *loc, + gfc_actual_arglist *actual) { gfc_gsymbol *gsym; gfc_symbol *def_sym = NULL; @@ -5396,7 +5397,7 @@ check_externals_procedure (gfc_symbol *sym, locus *loc, gfc_actual_arglist *actu if (def_sym) { - gfc_procedure_use (def_sym, &actual, loc); + gfc_compare_actual_formal (&actual, def_sym->formal, 0, 0, 0, loc); return 0; } diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 80e31ee..6f7717d 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -1610,6 +1610,9 @@ typedef struct gfc_symbol /* Set if this is a module function or subroutine with the abreviated declaration in a submodule. */ unsigned abr_modproc_decl:1; + /* Set if a previous error or warning has occurred and no other + should be reported. */ + unsigned error:1; int refs; struct gfc_namespace *ns; /* namespace containing this symbol */ diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c index 43d7cd5..08e4f06 100644 --- a/gcc/fortran/interface.c +++ b/gcc/fortran/interface.c @@ -1807,9 +1807,9 @@ gfc_compare_interfaces (gfc_symbol *s1, gfc_symbol *s2, const char *name2, if (!compare_rank (f2->sym, f1->sym)) { if (errmsg != NULL) - snprintf (errmsg, err_len, "Rank mismatch in argument '%s' " - "(%i/%i)", f1->sym->name, symbol_rank (f1->sym), - symbol_rank (f2->sym)); + snprintf (errmsg, err_len, "Rank mismatch in argument " + "'%s' (%i/%i)", f1->sym->name, + symbol_rank (f1->sym), symbol_rank (f2->sym)); return false; } if ((gfc_option.allow_std & GFC_STD_F2008) @@ -2189,22 +2189,42 @@ compare_pointer (gfc_symbol *formal, gfc_expr *actual) static void argument_rank_mismatch (const char *name, locus *where, - int rank1, int rank2) + int rank1, int rank2, locus *where_formal) { /* TS 29113, C407b. */ - if (rank2 == -1) - gfc_error ("The assumed-rank array at %L requires that the dummy argument" - " %qs has assumed-rank", where, name); - else if (rank1 == 0) - gfc_error_opt (OPT_Wargument_mismatch, "Rank mismatch in argument %qs " - "at %L (scalar and rank-%d)", name, where, rank2); - else if (rank2 == 0) - gfc_error_opt (OPT_Wargument_mismatch, "Rank mismatch in argument %qs " - "at %L (rank-%d and scalar)", name, where, rank1); + if (where_formal == NULL) + { + if (rank2 == -1) + gfc_error ("The assumed-rank array at %L requires that the dummy " + "argument %qs has assumed-rank", where, name); + else if (rank1 == 0) + gfc_error_opt (0, "Rank mismatch in argument %qs " + "at %L (scalar and rank-%d)", name, where, rank2); + else if (rank2 == 0) + gfc_error_opt (0, "Rank mismatch in argument %qs " + "at %L (rank-%d and scalar)", name, where, rank1); + else + gfc_error_opt (0, "Rank mismatch in argument %qs " + "at %L (rank-%d and rank-%d)", name, where, rank1, + rank2); + } else - gfc_error_opt (OPT_Wargument_mismatch, "Rank mismatch in argument %qs " - "at %L (rank-%d and rank-%d)", name, where, rank1, rank2); + { + gcc_assert (rank2 != -1); + if (rank1 == 0) + gfc_error_opt (0, "Rank mismatch between actual argument at %L " + "and actual argument at %L (scalar and rank-%d)", + where, where_formal, rank2); + else if (rank2 == 0) + gfc_error_opt (0, "Rank mismatch between actual argument at %L " + "and actual argument at %L (rank-%d and scalar)", + where, where_formal, rank1); + else + gfc_error_opt (0, "Rank mismatch between actual argument at %L " + "and actual argument at %L (rank-%d and rank-%d", where, + where_formal, rank1, rank2); + } } @@ -2253,8 +2273,7 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual, sizeof(err), NULL, NULL)) { if (where) - gfc_error_opt (OPT_Wargument_mismatch, - "Interface mismatch in dummy procedure %qs at %L:" + gfc_error_opt (0, "Interface mismatch in dummy procedure %qs at %L:" " %s", formal->name, &actual->where, err); return false; } @@ -2281,8 +2300,7 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual, err, sizeof(err), NULL, NULL)) { if (where) - gfc_error_opt (OPT_Wargument_mismatch, - "Interface mismatch in dummy procedure %qs at %L:" + gfc_error_opt (0, "Interface mismatch in dummy procedure %qs at %L:" " %s", formal->name, &actual->where, err); return false; } @@ -2312,10 +2330,24 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual, CLASS_DATA (actual)->ts.u.derived))) { if (where) - gfc_error_opt (OPT_Wargument_mismatch, - "Type mismatch in argument %qs at %L; passed %s to %s", - formal->name, where, gfc_typename (&actual->ts), - gfc_typename (&formal->ts)); + { + if (formal->attr.artificial) + { + if (!flag_allow_argument_mismatch || !formal->error) + gfc_error_opt (0, "Type mismatch between actual argument at %L " + "and actual argument at %L (%s/%s).", + &actual->where, + &formal->declared_at, + gfc_typename (&actual->ts), + gfc_typename (&formal->ts)); + + formal->error = 1; + } + else + gfc_error_opt (0, "Type mismatch in argument %qs at %L; passed %s " + "to %s", formal->name, where, gfc_typename (&actual->ts), + gfc_typename (&formal->ts)); + } return false; } @@ -2512,8 +2544,17 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual, && gfc_is_coindexed (actual))) { if (where) - argument_rank_mismatch (formal->name, &actual->where, - symbol_rank (formal), actual->rank); + { + locus *where_formal; + if (formal->attr.artificial) + where_formal = &formal->declared_at; + else + where_formal = NULL; + + argument_rank_mismatch (formal->name, &actual->where, + symbol_rank (formal), actual->rank, + where_formal); + } return false; } else if (actual->rank != 0 && (is_elemental || formal->attr.dimension)) @@ -2584,8 +2625,17 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual, if (ref == NULL && actual->expr_type != EXPR_NULL) { if (where) - argument_rank_mismatch (formal->name, &actual->where, - symbol_rank (formal), actual->rank); + { + locus *where_formal; + if (formal->attr.artificial) + where_formal = &formal->declared_at; + else + where_formal = NULL; + + argument_rank_mismatch (formal->name, &actual->where, + symbol_rank (formal), actual->rank, + where_formal); + } return false; } @@ -3062,16 +3112,14 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, f->sym->ts.u.cl->length->value.integer) != 0)) { if (where && (f->sym->attr.pointer || f->sym->attr.allocatable)) - gfc_warning (OPT_Wargument_mismatch, - "Character length mismatch (%ld/%ld) between actual " + gfc_warning (0, "Character length mismatch (%ld/%ld) between actual " "argument and pointer or allocatable dummy argument " "%qs at %L", mpz_get_si (a->expr->ts.u.cl->length->value.integer), mpz_get_si (f->sym->ts.u.cl->length->value.integer), f->sym->name, &a->expr->where); else if (where) - gfc_warning (OPT_Wargument_mismatch, - "Character length mismatch (%ld/%ld) between actual " + gfc_warning (0, "Character length mismatch (%ld/%ld) between actual " "argument and assumed-shape dummy argument %qs " "at %L", mpz_get_si (a->expr->ts.u.cl->length->value.integer), @@ -3102,8 +3150,7 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, && f->sym->attr.flavor != FL_PROCEDURE) { if (a->expr->ts.type == BT_CHARACTER && !f->sym->as && where) - gfc_warning (OPT_Wargument_mismatch, - "Character length of actual argument shorter " + gfc_warning (0, "Character length of actual argument shorter " "than of dummy argument %qs (%lu/%lu) at %L", f->sym->name, actual_size, formal_size, &a->expr->where); @@ -3111,8 +3158,7 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, { /* Emit a warning for -std=legacy and an error otherwise. */ if (gfc_option.warn_std == 0) - gfc_warning (OPT_Wargument_mismatch, - "Actual argument contains too few " + gfc_warning (0, "Actual argument contains too few " "elements for dummy argument %qs (%lu/%lu) " "at %L", f->sym->name, actual_size, formal_size, &a->expr->where); @@ -4706,8 +4752,7 @@ gfc_check_typebound_override (gfc_symtree* proc, gfc_symtree* old) if (!gfc_check_dummy_characteristics (proc_formal->sym, old_formal->sym, check_type, err, sizeof(err))) { - gfc_error_opt (OPT_Wargument_mismatch, - "Argument mismatch for the overriding procedure " + gfc_error_opt (0, "Argument mismatch for the overriding procedure " "%qs at %L: %s", proc->name, &where, err); return false; } @@ -5184,6 +5229,7 @@ gfc_get_formal_from_actual_arglist (gfc_symbol *sym, } } s->attr.dummy = 1; + s->declared_at = a->expr->where; s->attr.intent = INTENT_UNKNOWN; (*f)->sym = s; } diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi index ed8cefb..fa60eff 100644 --- a/gcc/fortran/invoke.texi +++ b/gcc/fortran/invoke.texi @@ -145,7 +145,7 @@ by type. Explanations are in the following sections. @item Error and Warning Options @xref{Error and Warning Options,,Options to request or suppress errors and warnings}. -@gccoptlist{-Waliasing -Wall -Wampersand -Wargument-mismatch -Warray-bounds @gol +@gccoptlist{-Waliasing -Wall -Wampersand -Warray-bounds @gol -Wc-binding-type -Wcharacter-truncation -Wconversion @gol -Wdo-subscript -Wfunction-elimination -Wimplicit-interface @gol -Wimplicit-procedure -Wintrinsic-shadow -Wuse-without-only @gol @@ -236,8 +236,15 @@ intrinsic will be called except when it is explicitly declared @code{EXTERNAL}. Some code contains calls to external procedures whith mismatches between the calls and the procedure definition, or with mismatches between different calls. Such code is non-conforming, and will usually -be flagged with an error. This options degrades the error to a -warning. This option is implied by @option{-std=legacy}. +be flagged wi1th an error. This options degrades the error to a +warning, which can only be disabled by disabling all warnings vial +@option{-w}. Only a single occurrence per argument is flagged by this +warning. @option{-fallow-argument-mismatch} is implied by +@option{-std=legacy}. + +Using this option is @emph{strongly} discouraged. It is possible to +provide standard-conforming code which allows different types of +arguments by using an explicit interface and @code{TYPE(*)}. @item -fallow-invalid-boz @opindex @code{allow-invalid-boz} @@ -907,15 +914,6 @@ character constant, GNU Fortran assumes continuation at the first non-comment, non-whitespace character after the ampersand that initiated the continuation. -@item -Wargument-mismatch -@opindex @code{Wargument-mismatch} -@cindex warnings, argument mismatch -@cindex warnings, parameter mismatch -@cindex warnings, interface mismatch -Warn about type, rank, and other mismatches between formal parameters and actual -arguments to functions and subroutines. These warnings are recommended and -thus enabled by default. - @item -Warray-temporaries @opindex @code{Warray-temporaries} @cindex warnings, array temporaries diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt index 1b3364b..2cfc76d 100644 --- a/gcc/fortran/lang.opt +++ b/gcc/fortran/lang.opt @@ -210,8 +210,8 @@ Fortran Warning Var(warn_array_temporaries) Warn about creation of array temporaries. Wargument-mismatch -Fortran Warning Var(warn_argument_mismatch) Init(1) -Warn about type and rank mismatches between arguments and parameters. +Fortran WarnRemoved +Does nothing. Preserved for backward compatibility. Wc-binding-type Fortran Var(warn_c_binding_type) Warning LangEnabledBy(Fortran,Wall) diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index 383ba44..c4260bb 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -1429,8 +1429,7 @@ resolve_structure_cons (gfc_expr *expr, int init) if (s2 && !gfc_compare_interfaces (comp->ts.interface, s2, name, 0, 1, err, sizeof (err), NULL, NULL)) { - gfc_error_opt (OPT_Wargument_mismatch, - "Interface mismatch for procedure-pointer " + gfc_error_opt (0, "Interface mismatch for procedure-pointer " "component %qs in structure constructor at %L:" " %s", comp->name, &cons->expr->where, err); return false; @@ -2609,8 +2608,7 @@ resolve_global_procedure (gfc_symbol *sym, locus *where, int sub) if (!gfc_compare_interfaces (sym, def_sym, sym->name, 0, 1, reason, sizeof(reason), NULL, NULL)) { - gfc_error_opt (OPT_Wargument_mismatch, - "Interface mismatch in global procedure %qs at %L:" + gfc_error_opt (0, "Interface mismatch in global procedure %qs at %L:" " %s", sym->name, &sym->declared_at, reason); goto done; } diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index 3c6ab60..c2c5d9d 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -5881,9 +5881,11 @@ generate_local_decl (gfc_symbol * sym) } else if (warn_unused_dummy_argument) { - gfc_warning (OPT_Wunused_dummy_argument, - "Unused dummy argument %qs at %L", sym->name, - &sym->declared_at); + if (!sym->attr.artificial) + gfc_warning (OPT_Wunused_dummy_argument, + "Unused dummy argument %qs at %L", sym->name, + &sym->declared_at); + if (sym->backend_decl != NULL_TREE) TREE_NO_WARNING(sym->backend_decl) = 1; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 45ab4ea..bfc9e8a3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,18 @@ +2019-09-14 Thomas Koenig + + PR fortran/91557 + PR fortran/91556 + * gfortran.dg/argument_checking_20.f90: New test. + * gfortran.dg/argument_checking_21.f90: New test. + * gfortran.dg/argument_checking_22.f90: New test. + * gfortran.dg/argument_checking_23.f90: New test. + * gfortran.dg/warn_unused_dummy_argument_5.f90: New test. + * gfortran.dg/bessel_3.f90: Add pattern for type mismatch. + * gfortran.dg/g77/20010519-1.f: Adjust dg-warning messages to new + handling. + * gfortran.dg/pr24823.f: Likewise. + * gfortran.dg/pr39937.f: Likewise. + 2019-09-14 Sandra Loosemore PR testsuite/83889 diff --git a/gcc/testsuite/gfortran.dg/argument_checking_20.f90 b/gcc/testsuite/gfortran.dg/argument_checking_20.f90 new file mode 100644 index 0000000..12788cc --- /dev/null +++ b/gcc/testsuite/gfortran.dg/argument_checking_20.f90 @@ -0,0 +1,11 @@ +! { dg-do compile } +program main + real :: a(10), b(10,10) +! This should be caugt + call foo(1.0) ! { dg-error "Rank mismatch" } + call foo(b) ! { dg-error "Rank mismatch" } +! This is OK + call bar(a) + call bar(b) + +end program main diff --git a/gcc/testsuite/gfortran.dg/argument_checking_21.f90 b/gcc/testsuite/gfortran.dg/argument_checking_21.f90 new file mode 100644 index 0000000..d4f2ddf --- /dev/null +++ b/gcc/testsuite/gfortran.dg/argument_checking_21.f90 @@ -0,0 +1,12 @@ +! { dg-do compile } +! { dg-options "-fallow-argument-mismatch" } +program main + real :: a(10), b(10,10) +! This should be caugt + call foo(1.0) ! { dg-warning "Rank mismatch" } + call foo(b) ! { dg-warning "Rank mismatch" } +! This is OK + call bar(a) + call bar(b) + +end program main diff --git a/gcc/testsuite/gfortran.dg/argument_checking_22.f90 b/gcc/testsuite/gfortran.dg/argument_checking_22.f90 new file mode 100644 index 0000000..783b53f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/argument_checking_22.f90 @@ -0,0 +1,15 @@ +! { dg-do compile } +! PR 91556 - check that multiple errors are emitted for type mismatch +! (and that the check is also done in contained procedures). + +program main + real :: a + call foo(a) ! { dg-error "Type mismatch" } +contains + subroutine bar + integer :: b + complex :: c + call foo(b) ! { dg-error "Type mismatch" } + call foo(c) ! { dg-error "Type mismatch" } + end subroutine bar +end program main diff --git a/gcc/testsuite/gfortran.dg/argument_checking_23.f90 b/gcc/testsuite/gfortran.dg/argument_checking_23.f90 new file mode 100644 index 0000000..74f72e3 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/argument_checking_23.f90 @@ -0,0 +1,16 @@ +! { dg-do compile } +! { dg-options "-fallow-argument-mismatch" } +! PR 91556 - check that only a single warning iw emitted for type +! mismatch (and that the check is also done in contained procedures). + +program main + real :: a + call foo(a) ! { dg-warning "Type mismatch" } +contains + subroutine bar + integer :: b + complex :: c + call foo(b) ! { dg-warning "Type mismatch" } + call foo(c) + end subroutine bar +end program main diff --git a/gcc/testsuite/gfortran.dg/bessel_3.f90 b/gcc/testsuite/gfortran.dg/bessel_3.f90 index 05610ae..8817725 100644 --- a/gcc/testsuite/gfortran.dg/bessel_3.f90 +++ b/gcc/testsuite/gfortran.dg/bessel_3.f90 @@ -8,11 +8,11 @@ IMPLICIT NONE print *, SIN (1.0) print *, BESSEL_J0(1.0) ! { dg-error "has no IMPLICIT type" }) print *, BESSEL_J1(1.0) ! { dg-error "has no IMPLICIT type" } -print *, BESSEL_JN(1,1.0) ! { dg-error "has no IMPLICIT type" } +print *, BESSEL_JN(1,1.0) ! { dg-error "has no IMPLICIT type|Type mismatch" } print *, BESSEL_JN(1,2,1.0) ! { dg-error "has no IMPLICIT type|Type mismatch" } print *, BESSEL_Y0(1.0) ! { dg-error "has no IMPLICIT type" } print *, BESSEL_Y1(1.0) ! { dg-error "has no IMPLICIT type" } -print *, BESSEL_YN(1,1.0) ! { dg-error "has no IMPLICIT type" } +print *, BESSEL_YN(1,1.0) ! { dg-error "has no IMPLICIT type|Type mismatch" } print *, BESSEL_YN(1,2,1.0) ! { dg-error "has no IMPLICIT type|Type mismatch" } end diff --git a/gcc/testsuite/gfortran.dg/g77/20010519-1.f b/gcc/testsuite/gfortran.dg/g77/20010519-1.f index 4cefb95..8a59906 100644 --- a/gcc/testsuite/gfortran.dg/g77/20010519-1.f +++ b/gcc/testsuite/gfortran.dg/g77/20010519-1.f @@ -773,7 +773,7 @@ C NTR=6 OLDPRN=PRNLEV PRNLEV=1 - CALL ORTHNM(1,6,NTR,HEAP(TRAROT),NAT3,.FALSE.,TOLER) + CALL ORTHNM(1,6,NTR,HEAP(TRAROT),NAT3,.FALSE.,TOLER) ! { dg-warning "Type mismatch" } PRNLEV=OLDPRN IF(IUNRMD .LT. 0) THEN C @@ -1126,7 +1126,7 @@ C NFCUT=NFRET OLDPRN=PRNLEV PRNLEV=1 - CALL ORTHNM(1,NFRET,NFCUT,DDV,NAT3,LPURG,TOLER) ! { dg-warning "Type mismatch" } + CALL ORTHNM(1,NFRET,NFCUT,DDV,NAT3,LPURG,TOLER) PRNLEV=OLDPRN NFRET=NFCUT IF(PRNLEV.GE.2) WRITE(OUTU,568) NFRET @@ -1174,7 +1174,7 @@ C TO DO-THE-DIAGONALISATIONS NFSAV=NFCUT1 OLDPRN=PRNLEV PRNLEV=1 - CALL ORTHNM(1,NFCUT1,NFCUT,DDV,NAT3,LPURG,TOLER) ! { dg-warning "Type mismatch" } + CALL ORTHNM(1,NFCUT1,NFCUT,DDV,NAT3,LPURG,TOLER) PRNLEV=OLDPRN CALL CPARAY(HEAP(DDVBAS),DDV,NAT3,1,NFCUT,1) NFRET=NDIM+NFCUT @@ -1224,7 +1224,7 @@ C CALL ADZERD(DDV,1,NFCUT1,NAT3,IS1,IS2,IS3,IS4) OLDPRN=PRNLEV PRNLEV=1 - CALL ORTHNM(1,NFCUT1,NFCUT,DDV,NAT3,LPURG,TOLER) ! { dg-warning "Type mismatch" } + CALL ORTHNM(1,NFCUT1,NFCUT,DDV,NAT3,LPURG,TOLER) PRNLEV=OLDPRN CALL CPARAY(HEAP(DDVBAS),DDV,NAT3,1,NFCUT,1) C diff --git a/gcc/testsuite/gfortran.dg/pr24823.f b/gcc/testsuite/gfortran.dg/pr24823.f index bb63c41..c6f638f 100644 --- a/gcc/testsuite/gfortran.dg/pr24823.f +++ b/gcc/testsuite/gfortran.dg/pr24823.f @@ -50,9 +50,9 @@ IF( I.LT.1 ) THEN IF( ISYM.EQ.0 ) THEN A( J-I+1, I ) = DCONJG( ZLATM2( M, N, I, J, KL, - $ DR, IPVTNG, IWORK, SPARSE ) ) + $ DR, IPVTNG, IWORK, SPARSE ) ) ! { dg-warning "Type mismatch" } ELSE - A( J-I+1, I ) = ZLATM2( M, N, I, J, KL, KU, ! { dg-warning "Type mismatch" } + A( J-I+1, I ) = ZLATM2( M, N, I, J, KL, KU, ! { dg-warning "Type mismatch" } $ IPVTNG, IWORK, SPARSE ) END IF END IF @@ -61,7 +61,7 @@ IF( ISYM.EQ.0 ) THEN END IF END IF - A( I-J+KUU+1, J ) = ZLATM2( M, N, I, J, KL, KU, ! { dg-warning "Type mismatch" } + A( I-J+KUU+1, J ) = ZLATM2( M, N, I, J, KL, KU, $ DR, IPVTNG, IWORK, SPARSE ) END IF END IF diff --git a/gcc/testsuite/gfortran.dg/pr39937.f b/gcc/testsuite/gfortran.dg/pr39937.f index 1ab22ee..17d3eb4 100644 --- a/gcc/testsuite/gfortran.dg/pr39937.f +++ b/gcc/testsuite/gfortran.dg/pr39937.f @@ -6,7 +6,7 @@ C { dg-options "-std=legacy" } $ WORK( * ) DOUBLE PRECISION X( 2, 2 ) CALL DLALN2( .FALSE., 1, 1, SMIN, ONE, T( J, J ), - $ ZERO, X, 2, SCALE, XNORM, IERR ) + $ ZERO, X, 2, SCALE, XNORM, IERR ) ! { dg-warning "Type mismatch" } CALL DSCAL( KI, SCALE, WORK( 1+N ), 1 ) DO 90 J = KI - 2, 1, -1 IF( J.GT.JNXT ) @@ -19,8 +19,8 @@ C { dg-options "-std=legacy" } END IF END IF CALL DLALN2( .FALSE., 2, 2, SMIN, ONE, - $ T( J-1, J-1 ), LDT, ONE, ONE, - $ XNORM, IERR ) ! { dg-warning "Type mismatch" } + $ T( J-1, J-1 ), LDT, ONE, ONE, ! { dg-warning "Type mismatch" } + $ XNORM, IERR ) CALL DAXPY( J-2, -X( 1, 1 ), T( 1, J-1 ), 1, $ WORK( 1+N ), 1 ) CALL DAXPY( J-2, -X( 2, 2 ), T( 1, J ), 1, diff --git a/gcc/testsuite/gfortran.dg/warn_unused_dummy_argument_5.f90 b/gcc/testsuite/gfortran.dg/warn_unused_dummy_argument_5.f90 new file mode 100644 index 0000000..fa93f1d --- /dev/null +++ b/gcc/testsuite/gfortran.dg/warn_unused_dummy_argument_5.f90 @@ -0,0 +1,16 @@ +! { dg-do compile } +! { dg-additional-options "-Wunused-dummy-argument" } +! PR 91557 - this used to generate a bogus warning +! Test case by Gerhard Steinmetz +program p + integer :: a, b + a = 1 + call g +contains + subroutine g + integer :: x, y + call h (x, y) + if ( a > 0 ) y = y - 1 + b = y - x + 1 + end +end -- cgit v1.1 From a0264d2cdd27a9a3e48e79c355092c423cc09072 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sun, 15 Sep 2019 00:16:23 +0000 Subject: Daily bump. From-SVN: r275723 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index fce7d42..c958b3a 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20190914 +20190915 -- cgit v1.1 From f5b72b67cf7c667a1c21ffeee1a7e6716650c55d Mon Sep 17 00:00:00 2001 From: Thomas Koenig Date: Sun, 15 Sep 2019 08:43:42 +0000 Subject: re PR fortran/91556 (Problems with better interface checking) 2019-09-15 Thomas Koenig PR fortran/91556 * gfortran.dg/warn_argument_mismatch_1.f90: Remove. From-SVN: r275726 --- gcc/testsuite/ChangeLog | 5 ++++ .../gfortran.dg/warn_argument_mismatch_1.f90 | 34 ---------------------- 2 files changed, 5 insertions(+), 34 deletions(-) delete mode 100644 gcc/testsuite/gfortran.dg/warn_argument_mismatch_1.f90 (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bfc9e8a3..1ec4fb9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-15 Thomas Koenig + + PR fortran/91556 + * gfortran.dg/warn_argument_mismatch_1.f90: Remove. + 2019-09-14 Thomas Koenig PR fortran/91557 diff --git a/gcc/testsuite/gfortran.dg/warn_argument_mismatch_1.f90 b/gcc/testsuite/gfortran.dg/warn_argument_mismatch_1.f90 deleted file mode 100644 index 19097a7..0000000 --- a/gcc/testsuite/gfortran.dg/warn_argument_mismatch_1.f90 +++ /dev/null @@ -1,34 +0,0 @@ -! { dg-do compile } -! { dg-options "-std=legacy -Wno-argument-mismatch" } -! -! No warnings should be output here with -Wno-argument-mismatch. -! - -subroutine s1(x) - implicit none - integer, intent(in) :: x - print *, x -end subroutine - -subroutine s2(x) - implicit none - integer, intent(in) :: x(1) - print *, x -end subroutine - -subroutine s3(x) - implicit none - integer, intent(in) :: x(2) - print *, x -end subroutine - -implicit none -integer :: x, y(1) -real :: r - -call s1(r) -call s1(y) -call s2(x) -call s3(y) - -end -- cgit v1.1 From da903a1610ba94d9309ab3438bd8a6391a7e77fb Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Sun, 15 Sep 2019 12:24:14 +0000 Subject: [C++ PATCH] simplify clone predicate https://gcc.gnu.org/ml/gcc-patches/2019-09/msg00904.html * cp-tree.h (DECL_CLONED_FUNCTION_P): Reimplement using IDENTIFIER_CDTOR_P, correct documentation. (DECL_CLONED_FUNCTION): Directly access field. (decl_cloned_function_p): Delete. * class.c (decl_cloned_function_p): Delete. * pt.c (instantiate_template_1): Check DECL_CHAIN is a decl. From-SVN: r275727 --- gcc/cp/ChangeLog | 9 +++++++++ gcc/cp/class.c | 37 ------------------------------------- gcc/cp/cp-tree.h | 11 +++++++---- gcc/cp/pt.c | 5 +++-- 4 files changed, 19 insertions(+), 43 deletions(-) (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8f266a2..bca3075 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2019-09-15 Nathan Sidwell + + * cp-tree.h (DECL_CLONED_FUNCTION_P): Reimplement using + IDENTIFIER_CDTOR_P, correct documentation. + (DECL_CLONED_FUNCTION): Directly access field. + (decl_cloned_function_p): Delete. + * class.c (decl_cloned_function_p): Delete. + * pt.c (instantiate_template_1): Check DECL_CHAIN is a decl. + 2019-09-11 Nathan Sidwell * c-objcp-common.c (cp-objcp-common.c): Alphababetize and diff --git a/gcc/cp/class.c b/gcc/cp/class.c index a8332ab..59a3d1a 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -4701,43 +4701,6 @@ build_clone (tree fn, tree name) return clone; } -/* Implementation of DECL_CLONED_FUNCTION and DECL_CLONED_FUNCTION_P, do - not invoke this function directly. - - For a non-thunk function, returns the address of the slot for storing - the function it is a clone of. Otherwise returns NULL_TREE. - - If JUST_TESTING, looks through TEMPLATE_DECL and returns NULL if - cloned_function is unset. This is to support the separate - DECL_CLONED_FUNCTION and DECL_CLONED_FUNCTION_P modes; using the latter - on a template makes sense, but not the former. */ - -tree * -decl_cloned_function_p (const_tree decl, bool just_testing) -{ - tree *ptr; - if (just_testing) - decl = STRIP_TEMPLATE (decl); - - if (TREE_CODE (decl) != FUNCTION_DECL - || !DECL_LANG_SPECIFIC (decl) - || DECL_LANG_SPECIFIC (decl)->u.fn.thunk_p) - { -#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007) - if (!just_testing) - lang_check_failed (__FILE__, __LINE__, __FUNCTION__); - else -#endif - return NULL; - } - - ptr = &DECL_LANG_SPECIFIC (decl)->u.fn.u5.cloned_function; - if (just_testing && *ptr == NULL_TREE) - return NULL; - else - return ptr; -} - /* Produce declarations for all appropriate clones of FN. If UPDATE_METHODS is true, the clones are added to the CLASSTYPE_MEMBER_VEC. */ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 793847d..6d217fc 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -2874,13 +2874,17 @@ struct GTY(()) lang_decl { (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (NODE) \ || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (NODE)) -/* Nonzero if NODE (a FUNCTION_DECL) is a cloned constructor or +/* Nonzero if NODE (a _DECL) is a cloned constructor or destructor. */ -#define DECL_CLONED_FUNCTION_P(NODE) (!!decl_cloned_function_p (NODE, true)) +#define DECL_CLONED_FUNCTION_P(NODE) \ + (DECL_NAME (NODE) \ + && IDENTIFIER_CDTOR_P (DECL_NAME (NODE)) \ + && !DECL_MAYBE_IN_CHARGE_CDTOR_P (NODE)) /* If DECL_CLONED_FUNCTION_P holds, this is the function that was cloned. */ -#define DECL_CLONED_FUNCTION(NODE) (*decl_cloned_function_p (NODE, false)) +#define DECL_CLONED_FUNCTION(NODE) \ + (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (NODE))->u.fn.u5.cloned_function) /* Perform an action for each clone of FN, if FN is a function with clones. This macro should be used like: @@ -6333,7 +6337,6 @@ extern void check_abi_tags (tree); extern tree missing_abi_tags (tree); extern void fixup_type_variants (tree); extern void fixup_attribute_variants (tree); -extern tree* decl_cloned_function_p (const_tree, bool); extern void clone_function_decl (tree, bool); extern void adjust_clone_args (tree); extern void deduce_noexcept_on_destructor (tree); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index c5915a5..4c49a1f 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -19905,8 +19905,9 @@ instantiate_template_1 (tree tmpl, tree orig_args, tsubst_flags_t complain) instantiate all the alternate entry points as well. We do this by cloning the instantiation of the main entry point, not by instantiating the template clones. */ - if (DECL_CHAIN (gen_tmpl) && DECL_CLONED_FUNCTION_P (DECL_CHAIN (gen_tmpl))) - clone_function_decl (fndecl, /*update_methods=*/false); + if (tree chain = DECL_CHAIN (gen_tmpl)) + if (DECL_P (chain) && DECL_CLONED_FUNCTION_P (chain)) + clone_function_decl (fndecl, /*update_methods=*/false); if (!access_ok) { -- cgit v1.1 From 3e0679c8d4e22f00614a52cbd2b33780f3f1a911 Mon Sep 17 00:00:00 2001 From: Thomas Koenig Date: Sun, 15 Sep 2019 14:57:48 +0000 Subject: re PR fortran/91550 (ICE in do_subscript, at fortran/frontend-passes.c:2652) 2019-09-15 Thomas Koenig PR fortran/91550 * frontend-passes.c (do_subscript): If step equals zero, a previuos error has been reported; do nothing in this case. * resolve.c (gfc_resolve_iterator): Move error checking after type conversion. 2019-09-15 Thomas Koenig PR fortran/91550 * gfortran.dg/do_subscript_6.f90: New test. From-SVN: r275729 --- gcc/fortran/ChangeLog | 9 +++++++++ gcc/fortran/frontend-passes.c | 15 ++++++++++++--- gcc/fortran/resolve.c | 26 +++++++++++++------------- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gfortran.dg/do_subscript_6.f90 | 11 +++++++++++ 5 files changed, 50 insertions(+), 16 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/do_subscript_6.f90 (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 56a107d..1006cbd 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,12 @@ +2019-09-15 Thomas Koenig + + PR fortran/91550 + * frontend-passes.c (do_subscript): If step equals + zero, a previuos error has been reported; do nothing + in this case. + * resolve.c (gfc_resolve_iterator): Move error checking + after type conversion. + 2019-09-14 Thomas Koenig PR fortran/91557 diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c index b095d5f..87518b8 100644 --- a/gcc/fortran/frontend-passes.c +++ b/gcc/fortran/frontend-passes.c @@ -2578,6 +2578,7 @@ do_subscript (gfc_expr **e) bool have_do_start, have_do_end; bool error_not_proven; int warn; + int sgn; dl = lp->c; if (dl == NULL) @@ -2606,7 +2607,16 @@ do_subscript (gfc_expr **e) Do not warn in this case. */ if (dl->ext.iterator->step->expr_type == EXPR_CONSTANT) - mpz_init_set (do_step, dl->ext.iterator->step->value.integer); + { + sgn = mpz_cmp_ui (dl->ext.iterator->step->value.integer, 0); + /* This can happen, but then the error has been + reported previously. */ + if (sgn == 0) + continue; + + mpz_init_set (do_step, dl->ext.iterator->step->value.integer); + } + else continue; @@ -2632,9 +2642,8 @@ do_subscript (gfc_expr **e) /* No warning inside a zero-trip loop. */ if (have_do_start && have_do_end) { - int sgn, cmp; + int cmp; - sgn = mpz_cmp_ui (do_step, 0); cmp = mpz_cmp (do_end, do_start); if ((sgn > 0 && cmp < 0) || (sgn < 0 && cmp > 0)) break; diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index c4260bb..ce192bb 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -7105,19 +7105,6 @@ gfc_resolve_iterator (gfc_iterator *iter, bool real_ok, bool own_scope) "Step expression in DO loop")) return false; - if (iter->step->expr_type == EXPR_CONSTANT) - { - if ((iter->step->ts.type == BT_INTEGER - && mpz_cmp_ui (iter->step->value.integer, 0) == 0) - || (iter->step->ts.type == BT_REAL - && mpfr_sgn (iter->step->value.real) == 0)) - { - gfc_error ("Step expression in DO loop at %L cannot be zero", - &iter->step->where); - return false; - } - } - /* Convert start, end, and step to the same type as var. */ if (iter->start->ts.kind != iter->var->ts.kind || iter->start->ts.type != iter->var->ts.type) @@ -7131,6 +7118,19 @@ gfc_resolve_iterator (gfc_iterator *iter, bool real_ok, bool own_scope) || iter->step->ts.type != iter->var->ts.type) gfc_convert_type (iter->step, &iter->var->ts, 1); + if (iter->step->expr_type == EXPR_CONSTANT) + { + if ((iter->step->ts.type == BT_INTEGER + && mpz_cmp_ui (iter->step->value.integer, 0) == 0) + || (iter->step->ts.type == BT_REAL + && mpfr_sgn (iter->step->value.real) == 0)) + { + gfc_error ("Step expression in DO loop at %L cannot be zero", + &iter->step->where); + return false; + } + } + if (iter->start->expr_type == EXPR_CONSTANT && iter->end->expr_type == EXPR_CONSTANT && iter->step->expr_type == EXPR_CONSTANT) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1ec4fb9..c06029a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2019-09-15 Thomas Koenig + PR fortran/91550 + * gfortran.dg/do_subscript_6.f90: New test. + +2019-09-15 Thomas Koenig + PR fortran/91556 * gfortran.dg/warn_argument_mismatch_1.f90: Remove. diff --git a/gcc/testsuite/gfortran.dg/do_subscript_6.f90 b/gcc/testsuite/gfortran.dg/do_subscript_6.f90 new file mode 100644 index 0000000..d78b9d3 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/do_subscript_6.f90 @@ -0,0 +1,11 @@ +! { dg-do compile } +! { dg-options "-std=legacy" } +! PR 91550 - this used to cause an ICE +! Test case by Gerhard Steinmetz +program p + real :: a(3) + integer :: i + do i = 1, 3, .1 ! { dg-error "cannot be zero" } + a(i) = i + end do +end -- cgit v1.1 From 204a3763d9bd304847ca2cd1e706c037302823d9 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Sun, 15 Sep 2019 13:29:24 -0400 Subject: Change C++ to C comments. From-SVN: r275730 --- gcc/cp/constraint.cc | 129 +++++++++++++++++++++++++-------------------------- gcc/cp/parser.c | 6 +-- gcc/cp/pt.c | 16 +++---- gcc/cp/semantics.c | 9 ++-- 4 files changed, 78 insertions(+), 82 deletions(-) (limited to 'gcc') diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 48ecb76..c7a172c 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -178,27 +178,27 @@ build_variable_check (tree id) Resolution of qualified concept names ---------------------------------------------------------------------------*/ -/* This facility is used to resolve constraint checks from - requirement expressions. A constraint check is a call to - a function template declared with the keyword 'concept'. +/* This facility is used to resolve constraint checks from requirement + expressions. A constraint check is a call to a function template declared + with the keyword 'concept'. - The result of resolution is a pair (a TREE_LIST) whose value - is the matched declaration, and whose purpose contains the - coerced template arguments that can be substituted into the - call. */ + The result of resolution is a pair (a TREE_LIST) whose value is the + matched declaration, and whose purpose contains the coerced template + arguments that can be substituted into the call. */ + +/* Given an overload set OVL, try to find a unique definition that can be + instantiated by the template arguments ARGS. + + This function is not called for arbitrary call expressions. In particular, + the call expression must be written with explicit template arguments + and no function arguments. For example: + + f() + + If a single match is found, this returns a TREE_LIST whose VALUE + is the constraint function (not the template), and its PURPOSE is + the complete set of arguments substituted into the parameter list. */ -// Given an overload set OVL, try to find a unique definition that can be -// instantiated by the template arguments ARGS. -// -// This function is not called for arbitrary call expressions. In particular, -// the call expression must be written with explicit template arguments -// and no function arguments. For example: -// -// f() -// -// If a single match is found, this returns a TREE_LIST whose VALUE -// is the constraint function (not the template), and its PURPOSE is -// the complete set of arguments substituted into the parameter list. static tree resolve_constraint_check (tree ovl, tree args) { @@ -211,20 +211,20 @@ resolve_constraint_check (tree ovl, tree args) if (TREE_CODE (tmpl) != TEMPLATE_DECL) continue; - // Don't try to deduce checks for non-concepts. We often - // end up trying to resolve constraints in functional casts - // as part of a postfix-expression. We can save time and - // headaches by not instantiating those declarations. - // - // NOTE: This masks a potential error, caused by instantiating - // non-deduced contexts using placeholder arguments. + /* Don't try to deduce checks for non-concepts. We often end up trying + to resolve constraints in functional casts as part of a + postfix-expression. We can save time and headaches by not + instantiating those declarations. + + NOTE: This masks a potential error, caused by instantiating + non-deduced contexts using placeholder arguments. */ tree fn = DECL_TEMPLATE_RESULT (tmpl); if (DECL_ARGUMENTS (fn)) continue; if (!DECL_DECLARED_CONCEPT_P (fn)) continue; - // Remember the candidate if we can deduce a substitution. + /* Remember the candidate if we can deduce a substitution. */ ++processing_template_decl; tree parms = TREE_VALUE (DECL_TEMPLATE_PARMS (tmpl)); if (tree subst = coerce_template_parms (parms, args, tmpl)) @@ -247,29 +247,30 @@ resolve_constraint_check (tree ovl, tree args) return cands; } -// Determine if the the call expression CALL is a constraint check, and -// return the concept declaration and arguments being checked. If CALL -// does not denote a constraint check, return NULL. +/* Determine if the the call expression CALL is a constraint check, and + return the concept declaration and arguments being checked. If CALL + does not denote a constraint check, return NULL. */ + tree resolve_constraint_check (tree call) { gcc_assert (TREE_CODE (call) == CALL_EXPR); - // A constraint check must be only a template-id expression. If - // it's a call to a base-link, its function(s) should be a - // template-id expression. If this is not a template-id, then it - // cannot be a concept-check. + /* A constraint check must be only a template-id expression. + If it's a call to a base-link, its function(s) should be a + template-id expression. If this is not a template-id, then + it cannot be a concept-check. */ tree target = CALL_EXPR_FN (call); if (BASELINK_P (target)) target = BASELINK_FUNCTIONS (target); if (TREE_CODE (target) != TEMPLATE_ID_EXPR) return NULL_TREE; - // Get the overload set and template arguments and try to - // resolve the target. + /* Get the overload set and template arguments and try to + resolve the target. */ tree ovl = TREE_OPERAND (target, 0); - /* This is a function call of a variable concept... ill-formed. */ + /* This is a function call of a variable concept... ill-formed. */ if (TREE_CODE (ovl) == TEMPLATE_DECL) { error_at (location_of (call), @@ -311,14 +312,11 @@ resolve_variable_concept_check (tree id) return error_mark_node; } - -/* Given a call expression or template-id expression to - a concept EXPR possibly including a wildcard, deduce - the concept being checked and the prototype parameter. - Returns true if the constraint and prototype can be - deduced and false otherwise. Note that the CHECK and - PROTO arguments are set to NULL_TREE if this returns - false. */ +/* Given a call expression or template-id expression to a concept EXPR + possibly including a wildcard, deduce the concept being checked and + the prototype parameter. Returns true if the constraint and prototype + can be deduced and false otherwise. Note that the CHECK and PROTO + arguments are set to NULL_TREE if this returns false. */ bool deduce_constrained_parameter (tree expr, tree& check, tree& proto) @@ -344,9 +342,9 @@ deduce_constrained_parameter (tree expr, tree& check, tree& proto) return false; } -// Given a call expression or template-id expression to a concept, EXPR, -// deduce the concept being checked and return the template arguments. -// Returns NULL_TREE if deduction fails. +/* Given a call expression or template-id expression to a concept, EXPR, + deduce the concept being checked and return the template arguments. + Returns NULL_TREE if deduction fails. */ static tree deduce_concept_introduction (tree expr) { @@ -1099,17 +1097,17 @@ current_template_constraints (void) return build_constraints (tmpl_constr, NULL_TREE); } -// If the recently parsed TYPE declares or defines a template or template -// specialization, get its corresponding constraints from the current -// template parameters and bind them to TYPE's declaration. +/* If the recently parsed TYPE declares or defines a template or + template specialization, get its corresponding constraints from the + current template parameters and bind them to TYPE's declaration. */ + tree associate_classtype_constraints (tree type) { if (!type || type == error_mark_node || TREE_CODE (type) != RECORD_TYPE) return type; - // An explicit class template specialization has no template - // parameters. + /* An explicit class template specialization has no template parameters. */ if (!current_template_parms) return type; @@ -1118,10 +1116,10 @@ associate_classtype_constraints (tree type) tree decl = TYPE_STUB_DECL (type); tree ci = current_template_constraints (); - // An implicitly instantiated member template declaration already - // has associated constraints. If it is defined outside of its - // class, then we need match these constraints against those of - // original declaration. + /* An implicitly instantiated member template declaration already + has associated constraints. If it is defined outside of its + class, then we need match these constraints against those of + original declaration. */ if (tree orig_ci = get_constraints (decl)) { if (!equivalent_constraints (ci, orig_ci)) @@ -2431,7 +2429,7 @@ constraint_expression_satisfied_p (tree expr, tree args) ---------------------------------------------------------------------------*/ /* Finish a requires expression for the given PARMS (possibly - null) and the non-empty sequence of requirements. */ + null) and the non-empty sequence of requirements. */ tree finish_requires_expr (tree parms, tree reqs) { @@ -2485,21 +2483,20 @@ finish_nested_requirement (tree expr) return build_nt (NESTED_REQ, expr); } -// Check that FN satisfies the structural requirements of a -// function concept definition. +/* Check that FN satisfies the structural requirements of a + function concept definition. */ tree check_function_concept (tree fn) { - // Check that the function is comprised of only a single - // return statement. + /* Check that the function is comprised of only a return statement. */ tree body = DECL_SAVED_TREE (fn); if (TREE_CODE (body) == BIND_EXPR) body = BIND_EXPR_BODY (body); - // Sometimes a function call results in the creation of clean up - // points. Allow these to be preserved in the body of the - // constraint, as we might actually need them for some constexpr - // evaluations. + /* Sometimes a function call results in the creation of clean up + points. Allow these to be preserved in the body of the + constraint, as we might actually need them for some constexpr + evaluations. */ if (TREE_CODE (body) == CLEANUP_POINT_EXPR) body = TREE_OPERAND (body, 0); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index b2fb150..165039e 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -42033,7 +42033,7 @@ synthesize_implicit_template_parm (cp_parser *parser, tree constr) non_type = true; } - // Attach the constraint to the parm before processing. + /* Attach the constraint to the parm before processing. */ tree node = build_tree_list (NULL_TREE, synth_tmpl_parm); TREE_TYPE (node) = constr; tree new_parm @@ -42076,8 +42076,8 @@ synthesize_implicit_template_parm (cp_parser *parser, tree constr) TREE_VEC_ELT (new_parms, new_parm_idx) = parser->implicit_template_parms; } - // If the new parameter was constrained, we need to add that to the - // constraints in the template parameter list. + /* If the new parameter was constrained, we need to add that to the + constraints in the template parameter list. */ if (tree req = TEMPLATE_PARM_CONSTRAINTS (tree_last (new_parm))) { tree reqs = TEMPLATE_PARMS_CONSTRAINTS (current_template_parms); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 4c49a1f..54d2813 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -2438,7 +2438,7 @@ determine_specialization (tree template_id, tree fn = TREE_VALUE (candidates); *targs_out = copy_node (DECL_TI_ARGS (fn)); - // Propagate the candidate's constraints to the declaration. + /* Propagate the candidate's constraints to the declaration. */ set_constraints (decl, get_constraints (fn)); /* DECL is a re-declaration or partial instantiation of a template @@ -7789,13 +7789,13 @@ is_compatible_template_arg (tree parm, tree arg) tree arg_cons = get_constraints (arg); - // If the template parameter is constrained, we need to rewrite its - // constraints in terms of the ARG's template parameters. This ensures - // that all of the template parameter types will have the same depth. - // - // Note that this is only valid when coerce_template_template_parm is - // true for the innermost template parameters of PARM and ARG. In other - // words, because coercion is successful, this conversion will be valid. + /* If the template parameter is constrained, we need to rewrite its + constraints in terms of the ARG's template parameters. This ensures + that all of the template parameter types will have the same depth. + + Note that this is only valid when coerce_template_template_parm is + true for the innermost template parameters of PARM and ARG. In other + words, because coercion is successful, this conversion will be valid. */ if (parm_cons) { tree args = template_parms_to_args (DECL_TEMPLATE_PARMS (arg)); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 56f70a0..7563248 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -3058,8 +3058,8 @@ finish_template_template_parm (tree aggr, tree identifier) DECL_TEMPLATE_RESULT (tmpl) = decl; DECL_ARTIFICIAL (decl) = 1; - // Associate the constraints with the underlying declaration, - // not the template. + /* Associate the constraints with the underlying declaration, + not the template. */ tree reqs = TEMPLATE_PARMS_CONSTRAINTS (current_template_parms); tree constr = build_constraints (reqs, NULL_TREE); set_constraints (decl, constr); @@ -10075,7 +10075,6 @@ apply_deduced_return_type (tree fco, tree return_type) #endif cfun->returns_struct = aggr; } - } /* DECL is a local variable or parameter from the surrounding scope of a @@ -10132,7 +10131,7 @@ capture_decltype (tree decl) static tree finish_unary_fold_expr (tree expr, int op, tree_code dir) { - // Build a pack expansion (assuming expr has pack type). + /* Build a pack expansion (assuming expr has pack type). */ if (!uses_parameter_packs (expr)) { error_at (location_of (expr), "operand of fold expression has no " @@ -10141,7 +10140,7 @@ finish_unary_fold_expr (tree expr, int op, tree_code dir) } tree pack = make_pack_expansion (expr); - // Build the fold expression. + /* Build the fold expression. */ tree code = build_int_cstu (integer_type_node, abs (op)); tree fold = build_min_nt_loc (UNKNOWN_LOCATION, dir, code, pack); FOLD_EXPR_MODIFY_P (fold) = (op < 0); -- cgit v1.1 From e6e3aa01aa4b9e5d7e1cc69ec134d89cabdfd018 Mon Sep 17 00:00:00 2001 From: "Steven G. Kargl" Date: Sun, 15 Sep 2019 17:49:44 +0000 Subject: re PR fortran/91727 (ICE in conformable_arrays, at fortran/resolve.c:7490) 2019-09-15 Steven G. Kargl PR fortran/91727 * resolve.c (conformable_arrays): If array-spec is NULL, then allocate-object is a scalar. a conformability check only occurs for an array source-expr. 2019-09-15 Steven G. Kargl PR fortran/91727 * gfortran.dg/pr91727.f90: New test. From-SVN: r275731 --- gcc/fortran/ChangeLog | 7 +++++++ gcc/fortran/resolve.c | 2 +- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gfortran.dg/pr91727.f90 | 9 +++++++++ 4 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gfortran.dg/pr91727.f90 (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 1006cbd..7b383b3 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,10 @@ +2019-09-15 Steven G. Kargl + + PR fortran/91727 + * resolve.c (conformable_arrays): If array-spec is NULL, then + allocate-object is a scalar. a conformability check only occurs + for an array source-expr. + 2019-09-15 Thomas Koenig PR fortran/91550 diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index ce192bb..f1de7dd 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -7485,7 +7485,7 @@ conformable_arrays (gfc_expr *e1, gfc_expr *e2) for (tail = e2->ref; tail && tail->next; tail = tail->next); /* First compare rank. */ - if ((tail && e1->rank != tail->u.ar.as->rank) + if ((tail && (!tail->u.ar.as || e1->rank != tail->u.ar.as->rank)) || (!tail && e1->rank != e2->rank)) { gfc_error ("Source-expr at %L must be scalar or have the " diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c06029a..786e6a4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-15 Steven G. Kargl + + PR fortran/91727 + * gfortran.dg/pr91727.f90: New test. + 2019-09-15 Thomas Koenig PR fortran/91550 diff --git a/gcc/testsuite/gfortran.dg/pr91727.f90 b/gcc/testsuite/gfortran.dg/pr91727.f90 new file mode 100644 index 0000000..54276b4 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr91727.f90 @@ -0,0 +1,9 @@ +! { dg-do compile } +! Code contributed by Gerhard Steinmetz. +program p + type t + class(*), allocatable :: a + end type + type(t) :: x + allocate (x%a, source=[1]) ! { dg-error "have the same rank as" } +end -- cgit v1.1 From 41fb55fd5cb551f4b32d9ca122f45140acbb1f26 Mon Sep 17 00:00:00 2001 From: Sandra Loosemore Date: Sun, 15 Sep 2019 16:19:40 -0400 Subject: 2019-09-15 Sandra Loosemore gcc/testsuite/ * lib/target-supports.exp (check_effective_target_arm_neon_fp16_hw) (check_effective_target_arm_fp16_hw): Use check_runtime instead of check_runtime_nocache. From-SVN: r275735 --- gcc/testsuite/ChangeLog | 7 +++++++ gcc/testsuite/lib/target-supports.exp | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 786e6a4..7e10fb4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2019-09-15 Sandra Loosemore + + * lib/target-supports.exp + (check_effective_target_arm_neon_fp16_hw) + (check_effective_target_arm_fp16_hw): Use check_runtime + instead of check_runtime_nocache. + 2019-09-15 Steven G. Kargl PR fortran/91727 diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index f05a093..6760e59 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -3909,7 +3909,7 @@ proc check_effective_target_arm_neon_fp16_hw { } { return 0 } global et_arm_neon_fp16_flags - check_runtime_nocache arm_neon_fp16_hw { + check_runtime arm_neon_fp16_hw { int main (int argc, char **argv) { @@ -4162,7 +4162,7 @@ proc check_effective_target_arm_fp16_hw { } { return 0 } global et_arm_fp16_flags - check_runtime_nocache arm_fp16_hw { + check_runtime arm_fp16_hw { int main (int argc, char **argv) { -- cgit v1.1 From 2abc02a1f5e6078f67172c64b22e91b8a5f1884e Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Sun, 15 Sep 2019 20:22:27 +0000 Subject: PR c++/91740 - ICE with constexpr call and ?: in ARRAY_REF. * pt.c (build_non_dependent_expr): Call build_non_dependent_expr for the first operand. * g++.dg/cpp1y/var-templ63.C: New test. From-SVN: r275736 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/pt.c | 2 +- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/cpp1y/var-templ63.C | 5 +++++ 4 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp1y/var-templ63.C (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bca3075..e92d49f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2019-09-15 Marek Polacek + + PR c++/91740 - ICE with constexpr call and ?: in ARRAY_REF. + * pt.c (build_non_dependent_expr): Call build_non_dependent_expr for + the first operand. + 2019-09-15 Nathan Sidwell * cp-tree.h (DECL_CLONED_FUNCTION_P): Reimplement using diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 54d2813..9de1b8f 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -26710,7 +26710,7 @@ build_non_dependent_expr (tree expr) if (TREE_CODE (expr) == COND_EXPR) return build3 (COND_EXPR, TREE_TYPE (expr), - TREE_OPERAND (expr, 0), + build_non_dependent_expr (TREE_OPERAND (expr, 0)), (TREE_OPERAND (expr, 1) ? build_non_dependent_expr (TREE_OPERAND (expr, 1)) : build_non_dependent_expr (TREE_OPERAND (expr, 0))), diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7e10fb4..6a5ba09 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-15 Marek Polacek + + PR c++/91740 - ICE with constexpr call and ?: in ARRAY_REF. + * g++.dg/cpp1y/var-templ63.C: New test. + 2019-09-15 Sandra Loosemore * lib/target-supports.exp diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ63.C b/gcc/testsuite/g++.dg/cpp1y/var-templ63.C new file mode 100644 index 0000000..a65f53b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/var-templ63.C @@ -0,0 +1,5 @@ +// PR c++/91740 - ICE with constexpr call and ?: in ARRAY_REF. +// { dg-do compile { target c++14 } } + +constexpr bool f(const char*) { return true; } +template const char c = "FOO"[f("BAR") ? 1 : 0]; -- cgit v1.1 From 27e0979b8b432e5bc109754d4426f49f190b2359 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Mon, 16 Sep 2019 00:16:28 +0000 Subject: Daily bump. From-SVN: r275741 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index c958b3a..2a82338 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20190915 +20190916 -- cgit v1.1 From c4438114d6133f4266be57b8678c49badbe60145 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 16 Sep 2019 00:34:12 -0400 Subject: Handle location wrappers better in warn_logical_operator. When we introduced location wrappers, we added fold_for_warn to warnings that are interested in a constant value, or wrapper-stripping to warnings that are interested in literal constants. This particular warning is looking for a literal constant, but was wrongly changed to use fold_for_warn; this patch makes it strip instead. * c-warn.c (warn_logical_operator): Strip location wrappers. Don't fold_for_warn in "|| mask" warning. From-SVN: r275743 --- gcc/c-family/ChangeLog | 5 +++++ gcc/c-family/c-warn.c | 40 ++++++++++++++++++++-------------------- 2 files changed, 25 insertions(+), 20 deletions(-) (limited to 'gcc') diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 2b700c2..93bdf3e0 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,8 @@ +2019-09-15 Jason Merrill + + * c-warn.c (warn_logical_operator): Strip location wrappers. Don't + fold_for_warn in "|| mask" warning. + 2019-09-10 Martin Liska * c.opt: Use newly added WarnRemoved. diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c index d671b77..bee5449 100644 --- a/gcc/c-family/c-warn.c +++ b/gcc/c-family/c-warn.c @@ -208,32 +208,32 @@ warn_logical_operator (location_t location, enum tree_code code, tree type, programmer. That is, an expression such as op && MASK where op should not be any boolean expression, nor a constant, and mask seems to be a non-boolean integer constant. */ + STRIP_ANY_LOCATION_WRAPPER (op_right); if (TREE_CODE (op_right) == CONST_DECL) /* An enumerator counts as a constant. */ op_right = DECL_INITIAL (op_right); + tree stripped_op_left = tree_strip_any_location_wrapper (op_left); if (!truth_value_p (code_left) && INTEGRAL_TYPE_P (TREE_TYPE (op_left)) - && !CONSTANT_CLASS_P (op_left) - && !TREE_NO_WARNING (op_left)) + && !CONSTANT_CLASS_P (stripped_op_left) + && TREE_CODE (stripped_op_left) != CONST_DECL + && !TREE_NO_WARNING (op_left) + && TREE_CODE (op_right) == INTEGER_CST + && !integer_zerop (op_right) + && !integer_onep (op_right)) { - tree folded_op_right = fold_for_warn (op_right); - if (TREE_CODE (folded_op_right) == INTEGER_CST - && !integer_zerop (folded_op_right) - && !integer_onep (folded_op_right)) - { - bool warned; - if (or_op) - warned - = warning_at (location, OPT_Wlogical_op, - "logical % applied to non-boolean constant"); - else - warned - = warning_at (location, OPT_Wlogical_op, - "logical % applied to non-boolean constant"); - if (warned) - TREE_NO_WARNING (op_left) = true; - return; - } + bool warned; + if (or_op) + warned + = warning_at (location, OPT_Wlogical_op, + "logical % applied to non-boolean constant"); + else + warned + = warning_at (location, OPT_Wlogical_op, + "logical % applied to non-boolean constant"); + if (warned) + TREE_NO_WARNING (op_left) = true; + return; } /* We do not warn for constants because they are typical of macro -- cgit v1.1 From a4d034d714f5799d3038aaf85347923686c7db64 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 16 Sep 2019 00:34:18 -0400 Subject: Fix conversions for built-in operator overloading candidates. While working on C++20 operator<=>, I noticed that build_new_op_1 was doing too much conversion when a built-in candidate was selected; the standard says it should only perform user-defined conversions, and then leave the normal operator semantics to handle any standard conversions. This is important for operator<=> because a comparison of two different unscoped enums is ill-formed; if we promote the enums to int here, cp_build_binary_op never gets to see the original operand types, so we can't give the error. * call.c (build_new_op_1): Don't apply any standard conversions to the operands of a built-in operator. Don't suppress conversions in cp_build_unary_op. * typeck.c (cp_build_unary_op): Do integral promotions for enums. From-SVN: r275744 --- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/call.c | 51 +++++++++++++++++++++++++-------------------------- gcc/cp/typeck.c | 4 ++-- 3 files changed, 34 insertions(+), 28 deletions(-) (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e92d49f..a03a428 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2019-09-15 Jason Merrill + + * call.c (build_new_op_1): Don't apply any standard conversions to + the operands of a built-in operator. Don't suppress conversions in + cp_build_unary_op. + * typeck.c (cp_build_unary_op): Do integral promotions for enums. + 2019-09-15 Marek Polacek PR c++/91740 - ICE with constexpr call and ?: in ARRAY_REF. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index c3045d9..457fa66 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -6139,41 +6139,40 @@ build_new_op_1 (const op_location_t &loc, enum tree_code code, int flags, break; } - /* We need to strip any leading REF_BIND so that bitfields - don't cause errors. This should not remove any important - conversions, because builtins don't apply to class - objects directly. */ + /* "If a built-in candidate is selected by overload resolution, the + operands of class type are converted to the types of the + corresponding parameters of the selected operation function, + except that the second standard conversion sequence of a + user-defined conversion sequence (12.3.3.1.2) is not applied." */ conv = cand->convs[0]; - if (conv->kind == ck_ref_bind) - conv = next_conversion (conv); - arg1 = convert_like (conv, arg1, complain); + if (conv->user_conv_p) + { + while (conv->kind != ck_user) + conv = next_conversion (conv); + arg1 = convert_like (conv, arg1, complain); + } if (arg2) { conv = cand->convs[1]; - if (conv->kind == ck_ref_bind) - conv = next_conversion (conv); - else - arg2 = decay_conversion (arg2, complain); - - /* We need to call warn_logical_operator before - converting arg2 to a boolean_type, but after - decaying an enumerator to its value. */ - if (complain & tf_warning) - warn_logical_operator (loc, code, boolean_type_node, - code_orig_arg1, arg1, - code_orig_arg2, arg2); - - arg2 = convert_like (conv, arg2, complain); + if (conv->user_conv_p) + { + while (conv->kind != ck_user) + conv = next_conversion (conv); + arg2 = convert_like (conv, arg2, complain); + } } + if (arg3) { conv = cand->convs[2]; - if (conv->kind == ck_ref_bind) - conv = next_conversion (conv); - convert_like (conv, arg3, complain); + if (conv->user_conv_p) + { + while (conv->kind != ck_user) + conv = next_conversion (conv); + arg3 = convert_like (conv, arg3, complain); + } } - } } @@ -6241,7 +6240,7 @@ build_new_op_1 (const op_location_t &loc, enum tree_code code, int flags, case REALPART_EXPR: case IMAGPART_EXPR: case ABS_EXPR: - return cp_build_unary_op (code, arg1, candidates != 0, complain); + return cp_build_unary_op (code, arg1, false, complain); case ARRAY_REF: return cp_build_array_ref (input_location, arg1, arg2, complain); diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 70094d1..620f2c9 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -6242,7 +6242,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, bool noconvert, : _("wrong type argument to unary plus")); else { - if (!noconvert && CP_INTEGRAL_TYPE_P (TREE_TYPE (arg))) + if (!noconvert && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (arg))) arg = cp_perform_integral_promotions (arg, complain); /* Make sure the result is not an lvalue: a unary plus or minus @@ -6267,7 +6267,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, bool noconvert, | WANT_VECTOR_OR_COMPLEX, arg, true))) errstring = _("wrong type argument to bit-complement"); - else if (!noconvert && CP_INTEGRAL_TYPE_P (TREE_TYPE (arg))) + else if (!noconvert && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (arg))) { /* Warn if the expression has boolean value. */ if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE -- cgit v1.1 From 47518e131f299f69d0c14f7e5efe83609185ed9f Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 16 Sep 2019 00:34:23 -0400 Subject: PR c++/82165 - enum bitfields and operator overloading. In this testcase, !f.b0 was failing to call the overloaded operator because TREE_TYPE is the magic bitfield integer type, and we weren't using unlowered_expr_type the way we do in other places. It would be nice if we could give bit-field COMPONENT_REFs their declared type until genericization time... * call.c (build_new_op_1): Use unlowered_expr_type. From-SVN: r275745 --- gcc/cp/ChangeLog | 3 +++ gcc/cp/call.c | 31 ++++++++++++++++------------- gcc/testsuite/g++.dg/expr/bitfield13.C | 36 ++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/g++.dg/expr/bitfield13.C (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a03a428..bed72c9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,8 @@ 2019-09-15 Jason Merrill + PR c++/82165 - enum bitfields and operator overloading. + * call.c (build_new_op_1): Use unlowered_expr_type. + * call.c (build_new_op_1): Don't apply any standard conversions to the operands of a built-in operator. Don't suppress conversions in cp_build_unary_op. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 457fa66..b780b0a 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -5815,6 +5815,9 @@ build_new_op_1 (const op_location_t &loc, enum tree_code code, int flags, } tree fnname = ovl_op_identifier (ismodop, ismodop ? code2 : code); + tree arg1_type = unlowered_expr_type (arg1); + tree arg2_type = arg2 ? unlowered_expr_type (arg2) : NULL_TREE; + arg1 = prep_operand (arg1); bool memonly = false; @@ -5846,8 +5849,8 @@ build_new_op_1 (const op_location_t &loc, enum tree_code code, int flags, case EQ_EXPR: case NE_EXPR: /* These are saved for the sake of maybe_warn_bool_compare. */ - code_orig_arg1 = TREE_CODE (TREE_TYPE (arg1)); - code_orig_arg2 = TREE_CODE (TREE_TYPE (arg2)); + code_orig_arg1 = TREE_CODE (arg1_type); + code_orig_arg2 = TREE_CODE (arg2_type); break; /* =, ->, [], () must be non-static member functions. */ @@ -5870,8 +5873,8 @@ build_new_op_1 (const op_location_t &loc, enum tree_code code, int flags, if (code == COND_EXPR) /* Use build_conditional_expr instead. */ gcc_unreachable (); - else if (! OVERLOAD_TYPE_P (TREE_TYPE (arg1)) - && (! arg2 || ! OVERLOAD_TYPE_P (TREE_TYPE (arg2)))) + else if (! OVERLOAD_TYPE_P (arg1_type) + && (! arg2 || ! OVERLOAD_TYPE_P (arg2_type))) goto builtin; if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR) @@ -5903,11 +5906,11 @@ build_new_op_1 (const op_location_t &loc, enum tree_code code, int flags, args[2] = NULL_TREE; /* Add class-member operators to the candidate set. */ - if (CLASS_TYPE_P (TREE_TYPE (arg1))) + if (CLASS_TYPE_P (arg1_type)) { tree fns; - fns = lookup_fnfields (TREE_TYPE (arg1), fnname, 1); + fns = lookup_fnfields (arg1_type, fnname, 1); if (fns == error_mark_node) { result = error_mark_node; @@ -5927,7 +5930,7 @@ build_new_op_1 (const op_location_t &loc, enum tree_code code, int flags, has an enumeration type, or T2 or reference to cv-qualified-opt T2 for the second argument, if the second argument has an enumeration type. Filter out those that don't match. */ - else if (! arg2 || ! CLASS_TYPE_P (TREE_TYPE (arg2))) + else if (! arg2 || ! CLASS_TYPE_P (arg2_type)) { struct z_candidate **candp, **next; @@ -5947,9 +5950,9 @@ build_new_op_1 (const op_location_t &loc, enum tree_code code, int flags, if (TYPE_REF_P (parmtype)) parmtype = TREE_TYPE (parmtype); - if (TREE_CODE (TREE_TYPE (args[i])) == ENUMERAL_TYPE + if (TREE_CODE (unlowered_expr_type (args[i])) == ENUMERAL_TYPE && (same_type_ignoring_top_level_qualifiers_p - (TREE_TYPE (args[i]), parmtype))) + (unlowered_expr_type (args[i]), parmtype))) break; parmlist = TREE_CHAIN (parmlist); @@ -6124,15 +6127,15 @@ build_new_op_1 (const op_location_t &loc, enum tree_code code, int flags, case LE_EXPR: case EQ_EXPR: case NE_EXPR: - if (TREE_CODE (TREE_TYPE (arg1)) == ENUMERAL_TYPE - && TREE_CODE (TREE_TYPE (arg2)) == ENUMERAL_TYPE - && (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) - != TYPE_MAIN_VARIANT (TREE_TYPE (arg2))) + if (TREE_CODE (arg1_type) == ENUMERAL_TYPE + && TREE_CODE (arg2_type) == ENUMERAL_TYPE + && (TYPE_MAIN_VARIANT (arg1_type) + != TYPE_MAIN_VARIANT (arg2_type)) && (complain & tf_warning)) { warning (OPT_Wenum_compare, "comparison between %q#T and %q#T", - TREE_TYPE (arg1), TREE_TYPE (arg2)); + arg1_type, arg2_type); } break; default: diff --git a/gcc/testsuite/g++.dg/expr/bitfield13.C b/gcc/testsuite/g++.dg/expr/bitfield13.C new file mode 100644 index 0000000..3f57d5f0 --- /dev/null +++ b/gcc/testsuite/g++.dg/expr/bitfield13.C @@ -0,0 +1,36 @@ +// PR c++/82165 +// { dg-do compile { target c++11 } } + +struct flags { + enum field { f0, f1, no_field }; + field b0 : 4; + field b1 : 4; + field a0, a1; +}; + +constexpr bool operator!(flags::field f) { + return f == flags::no_field; +} + +#define SA(X) static_assert ((X), #X) + +int main() { + constexpr flags f { flags::f0, flags::f1, flags::f0, flags::f1 }; + + SA( flags::f0 == 0 ); // 0 + SA( flags::f1 == 1 ); // 1 + SA( flags::no_field == 2 ); // 2 + SA( !flags::f0 == 0 ); // (!) 0 + SA( !flags::f1 == 0 ); // (!) 0 + SA( !flags::no_field == 1 ); // (!) 1 + + SA( f.a0 == 0 ); // 0 + SA( f.a1 == 1 ); // 1 + SA( !f.a0 == 0 ); // (!) 0 + SA( !f.a1 == 0 ); // (!) 0 + + SA( f.b0 == 0 ); // 0 + SA( f.b1 == 1 ); // 1 + SA( !f.b0 == 0 ); // expected "(!) 0", but got "1" + SA( !f.b1 == 0 ); // expected "(!) 0", but got "0" +} -- cgit v1.1 From ddc1a45b373ce98929d0d67e8c97ab6783236c40 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 16 Sep 2019 00:34:28 -0400 Subject: PR c++/30277 - int-width bit-field promotion. Here, if cp_perform_integral_promotions saw that the TREE_TYPE of a bit-field reference was the same as the type it promotes to, it didn't do anything. But then decay_conversion saw that the bit-field reference was unchanged, and converted it to its declared type. So I needed to add something to make it clear that promotion has been done. But then the 33819 change caused trouble by looking through the NOP_EXPR I just added. This was the wrong fix for that bug; I've now fixed that better by recognizing in cp_perform_integral_promotions that we won't promote a bit-field larger than 32 bits, so we should use the declared type. PR c++/33819 - long bit-field promotion. * typeck.c (cp_perform_integral_promotions): Handle large bit-fields properly. Handle 32-bit non-int bit-fields properly. (is_bitfield_expr_with_lowered_type): Don't look through NOP_EXPR. From-SVN: r275746 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/typeck.c | 29 ++++++++++++++++++----------- gcc/testsuite/g++.dg/expr/bitfield14.C | 17 +++++++++++++++++ 3 files changed, 41 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/g++.dg/expr/bitfield14.C (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bed72c9..7bf28f8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2019-09-15 Jason Merrill + PR c++/30277 - int-width bit-field promotion. + PR c++/33819 - long bit-field promotion. + * typeck.c (cp_perform_integral_promotions): Handle large bit-fields + properly. Handle 32-bit non-int bit-fields properly. + (is_bitfield_expr_with_lowered_type): Don't look through NOP_EXPR. + PR c++/82165 - enum bitfields and operator overloading. * call.c (build_new_op_1): Use unlowered_expr_type. diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 620f2c9..c6bf41e 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1971,12 +1971,6 @@ is_bitfield_expr_with_lowered_type (const_tree exp) else return NULL_TREE; - CASE_CONVERT: - if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (exp, 0))) - == TYPE_MAIN_VARIANT (TREE_TYPE (exp))) - return is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 0)); - /* Fallthrough. */ - default: return NULL_TREE; } @@ -2189,13 +2183,23 @@ cp_perform_integral_promotions (tree expr, tsubst_flags_t complain) if (error_operand_p (expr)) return error_mark_node; + type = TREE_TYPE (expr); + /* [conv.prom] - If the bitfield has an enumerated type, it is treated as any - other value of that type for promotion purposes. */ - type = is_bitfield_expr_with_lowered_type (expr); - if (!type || TREE_CODE (type) != ENUMERAL_TYPE) - type = TREE_TYPE (expr); + A prvalue for an integral bit-field (11.3.9) can be converted to a prvalue + of type int if int can represent all the values of the bit-field; + otherwise, it can be converted to unsigned int if unsigned int can + represent all the values of the bit-field. If the bit-field is larger yet, + no integral promotion applies to it. If the bit-field has an enumerated + type, it is treated as any other value of that type for promotion + purposes. */ + tree bitfield_type = is_bitfield_expr_with_lowered_type (expr); + if (bitfield_type + && (TREE_CODE (bitfield_type) == ENUMERAL_TYPE + || TYPE_PRECISION (type) > TYPE_PRECISION (integer_type_node))) + type = bitfield_type; + gcc_assert (INTEGRAL_OR_ENUMERATION_TYPE_P (type)); /* Scoped enums don't promote. */ if (SCOPED_ENUM_P (type)) @@ -2203,6 +2207,9 @@ cp_perform_integral_promotions (tree expr, tsubst_flags_t complain) promoted_type = type_promotes_to (type); if (type != promoted_type) expr = cp_convert (promoted_type, expr, complain); + else if (bitfield_type && bitfield_type != type) + /* Prevent decay_conversion from converting to bitfield_type. */ + expr = build_nop (type, expr); return expr; } diff --git a/gcc/testsuite/g++.dg/expr/bitfield14.C b/gcc/testsuite/g++.dg/expr/bitfield14.C new file mode 100644 index 0000000..546af85 --- /dev/null +++ b/gcc/testsuite/g++.dg/expr/bitfield14.C @@ -0,0 +1,17 @@ +// PR c++/30277 +// { dg-do compile { target c++11 } } + +struct S +{ + signed long l: 32; +}; + +void foo(long) = delete; +void foo(int) {} + +int main() +{ + S x = {1}; + foo(x.l+0); + return 0; +} -- cgit v1.1 From 10f30ac9cda947d117e50f0cbd4cf94ee70a944f Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 16 Sep 2019 11:58:35 +0000 Subject: re PR tree-optimization/91756 (g++.dg/lto/alias-3 FAILs) 2019-09-16 Richard Biener PR tree-optimization/91756 PR tree-optimization/87132 * tree-ssa-alias.h (enum translate_flags): New. (get_continuation_for_phi): Use it instead of simple bool flag. (walk_non_aliased_vuses): Likewise. * tree-ssa-alias.c (maybe_skip_until): Adjust. (get_continuation_for_phi): When looking across backedges only disallow valueization. (walk_non_aliased_vuses): Adjust. * tree-ssa-sccvn.c (vn_reference_lookup_3): Avoid valueization if requested. * gcc.dg/tree-ssa/ssa-fre-81.c: New testcase. From-SVN: r275747 --- gcc/ChangeLog | 14 ++++++++++++++ gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-81.c | 29 +++++++++++++++++++++++++++++ gcc/tree-ssa-alias.c | 28 +++++++++++++++++----------- gcc/tree-ssa-alias.h | 11 ++++++++--- gcc/tree-ssa-sccvn.c | 22 ++++++++++++++-------- 6 files changed, 88 insertions(+), 22 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-81.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 41cf926..49b7902 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2019-09-16 Richard Biener + + PR tree-optimization/91756 + PR tree-optimization/87132 + * tree-ssa-alias.h (enum translate_flags): New. + (get_continuation_for_phi): Use it instead of simple bool flag. + (walk_non_aliased_vuses): Likewise. + * tree-ssa-alias.c (maybe_skip_until): Adjust. + (get_continuation_for_phi): When looking across backedges only + disallow valueization. + (walk_non_aliased_vuses): Adjust. + * tree-ssa-sccvn.c (vn_reference_lookup_3): Avoid valueization + if requested. + 2019-09-14 Kewen Lin PR middle-end/80791 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6a5ba09..b893ed0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2019-09-16 Richard Biener + + PR tree-optimization/91756 + PR tree-optimization/87132 + * gcc.dg/tree-ssa/ssa-fre-81.c: New testcase. + 2019-09-15 Marek Polacek PR c++/91740 - ICE with constexpr call and ?: in ARRAY_REF. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-81.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-81.c new file mode 100644 index 0000000..e88f666 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-81.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-fre1-details" } */ + +struct a +{ + int foo,bar; +}; +struct b +{ + struct a a[10]; +}; +struct b b, *bptr=&b, *bptr2=&b; +int j; +int i; +int n=1; + +int +main () +{ + int jj=j; + bptr2->a[jj].bar = 0; + for (int i=0; ia[i].foo=1; + if (!__builtin_constant_p (bptr2->a[jj].bar == 0)) + __builtin_abort (); + return 0; +} + +/* { dg-final { scan-tree-dump "Replaced __builtin_constant_p \\\(\[^)\]*\\\) with 1" "fre1" } } */ diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index dd2a43e..52cda38 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -3150,7 +3150,8 @@ static bool maybe_skip_until (gimple *phi, tree &target, basic_block target_bb, ao_ref *ref, tree vuse, bool tbaa_p, unsigned int &limit, bitmap *visited, bool abort_on_visited, - void *(*translate)(ao_ref *, tree, void *, bool *), + void *(*translate)(ao_ref *, tree, void *, translate_flags *), + translate_flags disambiguate_only, void *data) { basic_block bb = gimple_bb (phi); @@ -3185,7 +3186,7 @@ maybe_skip_until (gimple *phi, tree &target, basic_block target_bb, return !abort_on_visited; vuse = get_continuation_for_phi (def_stmt, ref, tbaa_p, limit, visited, abort_on_visited, - translate, data); + translate, data, disambiguate_only); if (!vuse) return false; continue; @@ -3200,9 +3201,9 @@ maybe_skip_until (gimple *phi, tree &target, basic_block target_bb, --limit; if (stmt_may_clobber_ref_p_1 (def_stmt, ref, tbaa_p)) { - bool disambiguate_only = true; + translate_flags tf = disambiguate_only; if (translate - && (*translate) (ref, vuse, data, &disambiguate_only) == NULL) + && (*translate) (ref, vuse, data, &tf) == NULL) ; else return false; @@ -3233,8 +3234,10 @@ tree get_continuation_for_phi (gimple *phi, ao_ref *ref, bool tbaa_p, unsigned int &limit, bitmap *visited, bool abort_on_visited, - void *(*translate)(ao_ref *, tree, void *, bool *), - void *data) + void *(*translate)(ao_ref *, tree, void *, + translate_flags *), + void *data, + translate_flags disambiguate_only) { unsigned nargs = gimple_phi_num_args (phi); @@ -3276,13 +3279,15 @@ get_continuation_for_phi (gimple *phi, ao_ref *ref, bool tbaa_p, else if (! maybe_skip_until (phi, arg0, dom, ref, arg1, tbaa_p, limit, visited, abort_on_visited, - /* Do not translate when walking over + translate, + /* Do not valueize when walking over backedges. */ dominated_by_p (CDI_DOMINATORS, gimple_bb (SSA_NAME_DEF_STMT (arg1)), phi_bb) - ? NULL : translate, data)) + ? TR_DISAMBIGUATE + : disambiguate_only, data)) return NULL_TREE; } @@ -3320,7 +3325,8 @@ get_continuation_for_phi (gimple *phi, ao_ref *ref, bool tbaa_p, void * walk_non_aliased_vuses (ao_ref *ref, tree vuse, bool tbaa_p, void *(*walker)(ao_ref *, tree, void *), - void *(*translate)(ao_ref *, tree, void *, bool *), + void *(*translate)(ao_ref *, tree, void *, + translate_flags *), tree (*valueize)(tree), unsigned &limit, void *data) { @@ -3373,7 +3379,7 @@ walk_non_aliased_vuses (ao_ref *ref, tree vuse, bool tbaa_p, { if (!translate) break; - bool disambiguate_only = false; + translate_flags disambiguate_only = TR_TRANSLATE; res = (*translate) (ref, vuse, data, &disambiguate_only); /* Failed lookup and translation. */ if (res == (void *)-1) @@ -3385,7 +3391,7 @@ walk_non_aliased_vuses (ao_ref *ref, tree vuse, bool tbaa_p, else if (res != NULL) break; /* Translation succeeded, continue walking. */ - translated = translated || !disambiguate_only; + translated = translated || disambiguate_only == TR_TRANSLATE; } vuse = gimple_vuse (def_stmt); } diff --git a/gcc/tree-ssa-alias.h b/gcc/tree-ssa-alias.h index c7c6020..6d72c2f 100644 --- a/gcc/tree-ssa-alias.h +++ b/gcc/tree-ssa-alias.h @@ -132,13 +132,18 @@ extern bool call_may_clobber_ref_p (gcall *, tree); extern bool call_may_clobber_ref_p_1 (gcall *, ao_ref *); extern bool stmt_kills_ref_p (gimple *, tree); extern bool stmt_kills_ref_p (gimple *, ao_ref *); +enum translate_flags + { TR_TRANSLATE, TR_VALUEIZE_AND_DISAMBIGUATE, TR_DISAMBIGUATE }; extern tree get_continuation_for_phi (gimple *, ao_ref *, bool, unsigned int &, bitmap *, bool, - void *(*)(ao_ref *, tree, void *, bool *), - void *); + void *(*)(ao_ref *, tree, void *, + translate_flags *), + void *, translate_flags + = TR_VALUEIZE_AND_DISAMBIGUATE); extern void *walk_non_aliased_vuses (ao_ref *, tree, bool, void *(*)(ao_ref *, tree, void *), - void *(*)(ao_ref *, tree, void *, bool *), + void *(*)(ao_ref *, tree, void *, + translate_flags *), tree (*)(tree), unsigned &, void *); extern int walk_aliased_vdefs (ao_ref *, tree, bool (*)(ao_ref *, tree, void *), diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index f5d75bd..c29e2de 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -2189,7 +2189,7 @@ adjust_offsets_for_equal_base_address (tree base1, poly_int64 *offset1, static void * vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_, - bool *disambiguate_only) + translate_flags *disambiguate_only) { vn_walk_cb_data *data = (vn_walk_cb_data *)data_; vn_reference_t vr = data->vr; @@ -2210,8 +2210,11 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_, lhs_ops.truncate (0); basic_block saved_rpo_bb = vn_context_bb; vn_context_bb = gimple_bb (def_stmt); - copy_reference_ops_from_ref (lhs, &lhs_ops); - lhs_ops = valueize_refs_1 (lhs_ops, &valueized_anything, true); + if (*disambiguate_only <= TR_VALUEIZE_AND_DISAMBIGUATE) + { + copy_reference_ops_from_ref (lhs, &lhs_ops); + lhs_ops = valueize_refs_1 (lhs_ops, &valueized_anything, true); + } vn_context_bb = saved_rpo_bb; if (valueized_anything) { @@ -2221,7 +2224,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_, if (lhs_ref_ok && !refs_may_alias_p_1 (ref, &lhs_ref, data->tbaa_p)) { - *disambiguate_only = true; + *disambiguate_only = TR_VALUEIZE_AND_DISAMBIGUATE; return NULL; } } @@ -2248,7 +2251,9 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_, } if (!refs_may_alias_p_1 (&data->orig_ref, lref, data->tbaa_p)) { - *disambiguate_only = true; + *disambiguate_only = (valueized_anything + ? TR_VALUEIZE_AND_DISAMBIGUATE + : TR_DISAMBIGUATE); return NULL; } } @@ -2290,7 +2295,8 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_, } } } - else if (gimple_call_builtin_p (def_stmt, BUILT_IN_NORMAL) + else if (*disambiguate_only <= TR_VALUEIZE_AND_DISAMBIGUATE + && gimple_call_builtin_p (def_stmt, BUILT_IN_NORMAL) && gimple_call_num_args (def_stmt) <= 4) { /* For builtin calls valueize its arguments and call the @@ -2319,7 +2325,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_, gimple_call_set_arg (def_stmt, i, oldargs[i]); if (!res) { - *disambiguate_only = true; + *disambiguate_only = TR_VALUEIZE_AND_DISAMBIGUATE; return NULL; } } @@ -2327,7 +2333,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_, /* If we are looking for redundant stores do not create new hashtable entries from aliasing defs with made up alias-sets. */ - if (*disambiguate_only || !data->tbaa_p) + if (*disambiguate_only > TR_TRANSLATE || !data->tbaa_p) return (void *)-1; /* If we cannot constrain the size of the reference we cannot -- cgit v1.1 From 5f487a349de62613d7fa429bcbfbeeafbfc94f3a Mon Sep 17 00:00:00 2001 From: Li Jia He Date: Mon, 16 Sep 2019 14:21:20 +0000 Subject: Auto-generate maybe_fold_and/or_comparisons from match.pd 2019-09-16 Li Jia He Martin Liska * gimple-fold.c (and_comparisons_1): Add type as first argument. (and_var_with_comparison): Likewise. (and_var_with_comparison_1): Likewise. (or_comparisons_1): Likewise. (or_var_with_comparison): Likewise. (or_var_with_comparison_1): Likewise. (maybe_fold_and_comparisons): Call maybe_fold_comparisons_from_match_pd. (maybe_fold_or_comparisons): Likewise. (maybe_fold_comparisons_from_match_pd): New. * gimple-fold.h (maybe_fold_and_comparisons): Add type argument. (maybe_fold_or_comparisons): Likewise. * gimple.c (gimple_size): Make it public and add num_ops argument. (gimple_init): New function. (gimple_alloc): Call gimple_init. * gimple.h (gimple_size): New. (gimple_init): Likewise. * tree-if-conv.c (fold_or_predicates): Pass type. * tree-ssa-ifcombine.c (ifcombine_ifandif): Likewise. * tree-ssa-reassoc.c (eliminate_redundant_comparison): Likewise. (optimize_vec_cond_expr): Likewise. (ovce_extract_ops): Return type of conditional expression. * tree-ssanames.c (init_ssa_name_imm_use): New. (make_ssa_name_fn): Use init_ssa_name_imm_use. * tree-ssanames.h (init_ssa_name_imm_use): New. Co-Authored-By: Martin Liska From-SVN: r275748 --- gcc/ChangeLog | 29 ++++++++ gcc/gimple-fold.c | 170 +++++++++++++++++++++++++++++++++++------------ gcc/gimple-fold.h | 4 +- gcc/gimple.c | 37 ++++++----- gcc/gimple.h | 2 + gcc/tree-if-conv.c | 2 +- gcc/tree-ssa-ifcombine.c | 2 +- gcc/tree-ssa-reassoc.c | 25 ++++--- gcc/tree-ssanames.c | 21 ++++-- gcc/tree-ssanames.h | 1 + 10 files changed, 218 insertions(+), 75 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 49b7902..864da5a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,32 @@ +2019-09-16 Li Jia He + Martin Liska + + * gimple-fold.c (and_comparisons_1): Add type as first + argument. + (and_var_with_comparison): Likewise. + (and_var_with_comparison_1): Likewise. + (or_comparisons_1): Likewise. + (or_var_with_comparison): Likewise. + (or_var_with_comparison_1): Likewise. + (maybe_fold_and_comparisons): Call maybe_fold_comparisons_from_match_pd. + (maybe_fold_or_comparisons): Likewise. + (maybe_fold_comparisons_from_match_pd): New. + * gimple-fold.h (maybe_fold_and_comparisons): Add type argument. + (maybe_fold_or_comparisons): Likewise. + * gimple.c (gimple_size): Make it public and add num_ops argument. + (gimple_init): New function. + (gimple_alloc): Call gimple_init. + * gimple.h (gimple_size): New. + (gimple_init): Likewise. + * tree-if-conv.c (fold_or_predicates): Pass type. + * tree-ssa-ifcombine.c (ifcombine_ifandif): Likewise. + * tree-ssa-reassoc.c (eliminate_redundant_comparison): Likewise. + (optimize_vec_cond_expr): Likewise. + (ovce_extract_ops): Return type of conditional expression. + * tree-ssanames.c (init_ssa_name_imm_use): New. + (make_ssa_name_fn): Use init_ssa_name_imm_use. + * tree-ssanames.h (init_ssa_name_imm_use): New. + 2019-09-16 Richard Biener PR tree-optimization/91756 diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index fcffb98..6d9ba36 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -5371,22 +5371,22 @@ same_bool_result_p (const_tree op1, const_tree op2) /* Forward declarations for some mutually recursive functions. */ static tree -and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, +and_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b, enum tree_code code2, tree op2a, tree op2b); static tree -and_var_with_comparison (tree var, bool invert, +and_var_with_comparison (tree type, tree var, bool invert, enum tree_code code2, tree op2a, tree op2b); static tree -and_var_with_comparison_1 (gimple *stmt, +and_var_with_comparison_1 (tree type, gimple *stmt, enum tree_code code2, tree op2a, tree op2b); static tree -or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, +or_comparisons_1 (tree, enum tree_code code1, tree op1a, tree op1b, enum tree_code code2, tree op2a, tree op2b); static tree -or_var_with_comparison (tree var, bool invert, +or_var_with_comparison (tree, tree var, bool invert, enum tree_code code2, tree op2a, tree op2b); static tree -or_var_with_comparison_1 (gimple *stmt, +or_var_with_comparison_1 (tree, gimple *stmt, enum tree_code code2, tree op2a, tree op2b); /* Helper function for and_comparisons_1: try to simplify the AND of the @@ -5395,7 +5395,7 @@ or_var_with_comparison_1 (gimple *stmt, Return NULL_EXPR if we can't simplify this to a single expression. */ static tree -and_var_with_comparison (tree var, bool invert, +and_var_with_comparison (tree type, tree var, bool invert, enum tree_code code2, tree op2a, tree op2b) { tree t; @@ -5409,11 +5409,11 @@ and_var_with_comparison (tree var, bool invert, !var AND (op2a code2 op2b) => !(var OR !(op2a code2 op2b)) Then we only have to consider the simpler non-inverted cases. */ if (invert) - t = or_var_with_comparison_1 (stmt, + t = or_var_with_comparison_1 (type, stmt, invert_tree_comparison (code2, false), op2a, op2b); else - t = and_var_with_comparison_1 (stmt, code2, op2a, op2b); + t = and_var_with_comparison_1 (type, stmt, code2, op2a, op2b); return canonicalize_bool (t, invert); } @@ -5422,7 +5422,7 @@ and_var_with_comparison (tree var, bool invert, Return NULL_EXPR if we can't simplify this to a single expression. */ static tree -and_var_with_comparison_1 (gimple *stmt, +and_var_with_comparison_1 (tree type, gimple *stmt, enum tree_code code2, tree op2a, tree op2b) { tree var = gimple_assign_lhs (stmt); @@ -5453,7 +5453,7 @@ and_var_with_comparison_1 (gimple *stmt, /* If the definition is a comparison, recurse on it. */ if (TREE_CODE_CLASS (innercode) == tcc_comparison) { - tree t = and_comparisons_1 (innercode, + tree t = and_comparisons_1 (type, innercode, gimple_assign_rhs1 (stmt), gimple_assign_rhs2 (stmt), code2, @@ -5489,18 +5489,20 @@ and_var_with_comparison_1 (gimple *stmt, else if (inner1 == false_test_var) return (is_and ? boolean_false_node - : and_var_with_comparison (inner2, false, code2, op2a, op2b)); + : and_var_with_comparison (type, inner2, false, code2, op2a, + op2b)); else if (inner2 == false_test_var) return (is_and ? boolean_false_node - : and_var_with_comparison (inner1, false, code2, op2a, op2b)); + : and_var_with_comparison (type, inner1, false, code2, op2a, + op2b)); /* Next, redistribute/reassociate the AND across the inner tests. Compute the first partial result, (inner1 AND (op2a code op2b)) */ if (TREE_CODE (inner1) == SSA_NAME && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner1)) && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison - && (t = maybe_fold_and_comparisons (gimple_assign_rhs_code (s), + && (t = maybe_fold_and_comparisons (type, gimple_assign_rhs_code (s), gimple_assign_rhs1 (s), gimple_assign_rhs2 (s), code2, op2a, op2b))) @@ -5532,7 +5534,7 @@ and_var_with_comparison_1 (gimple *stmt, if (TREE_CODE (inner2) == SSA_NAME && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner2)) && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison - && (t = maybe_fold_and_comparisons (gimple_assign_rhs_code (s), + && (t = maybe_fold_and_comparisons (type, gimple_assign_rhs_code (s), gimple_assign_rhs1 (s), gimple_assign_rhs2 (s), code2, op2a, op2b))) @@ -5588,7 +5590,7 @@ and_var_with_comparison_1 (gimple *stmt, in the first comparison but not the second. */ static tree -and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, +and_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b, enum tree_code code2, tree op2a, tree op2b) { tree truth_type = truth_type_for (TREE_TYPE (op1a)); @@ -5762,7 +5764,8 @@ and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, { case GIMPLE_ASSIGN: /* Try to simplify by copy-propagating the definition. */ - return and_var_with_comparison (op1a, invert, code2, op2a, op2b); + return and_var_with_comparison (type, op1a, invert, code2, op2a, + op2b); case GIMPLE_PHI: /* If every argument to the PHI produces the same result when @@ -5812,7 +5815,7 @@ and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, gimple_bb (def_stmt), gimple_bb (stmt))) return NULL_TREE; - temp = and_var_with_comparison (arg, invert, code2, + temp = and_var_with_comparison (type, arg, invert, code2, op2a, op2b); if (!temp) return NULL_TREE; @@ -5834,6 +5837,73 @@ and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, return NULL_TREE; } +/* Helper function for maybe_fold_and_comparisons and maybe_fold_or_comparisons + : try to simplify the AND/OR of the ssa variable VAR with the comparison + specified by (OP2A CODE2 OP2B) from match.pd. Return NULL_EXPR if we can't + simplify this to a single expression. As we are going to lower the cost + of building SSA names / gimple stmts significantly, we need to allocate + them ont the stack. This will cause the code to be a bit ugly. */ + +static tree +maybe_fold_comparisons_from_match_pd (tree type, enum tree_code code, + enum tree_code code1, + tree op1a, tree op1b, + enum tree_code code2, tree op2a, + tree op2b) +{ + /* Allocate gimple stmt1 on the stack. */ + gassign *stmt1 + = (gassign *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, 3)); + gimple_init (stmt1, GIMPLE_ASSIGN, 3); + gimple_assign_set_rhs_code (stmt1, code1); + gimple_assign_set_rhs1 (stmt1, op1a); + gimple_assign_set_rhs2 (stmt1, op1b); + + /* Allocate gimple stmt2 on the stack. */ + gassign *stmt2 + = (gassign *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, 3)); + gimple_init (stmt2, GIMPLE_ASSIGN, 3); + gimple_assign_set_rhs_code (stmt2, code2); + gimple_assign_set_rhs1 (stmt2, op2a); + gimple_assign_set_rhs2 (stmt2, op2b); + + /* Allocate SSA names(lhs1) on the stack. */ + tree lhs1 = (tree)XALLOCA (tree_ssa_name); + memset (lhs1, 0, sizeof (tree_ssa_name)); + TREE_SET_CODE (lhs1, SSA_NAME); + TREE_TYPE (lhs1) = type; + init_ssa_name_imm_use (lhs1); + + /* Allocate SSA names(lhs2) on the stack. */ + tree lhs2 = (tree)XALLOCA (tree_ssa_name); + memset (lhs2, 0, sizeof (tree_ssa_name)); + TREE_SET_CODE (lhs2, SSA_NAME); + TREE_TYPE (lhs2) = type; + init_ssa_name_imm_use (lhs2); + + gimple_assign_set_lhs (stmt1, lhs1); + gimple_assign_set_lhs (stmt2, lhs2); + + gimple_match_op op (gimple_match_cond::UNCOND, code, + type, gimple_assign_lhs (stmt1), + gimple_assign_lhs (stmt2)); + if (op.resimplify (NULL, follow_all_ssa_edges)) + { + if (gimple_simplified_result_is_gimple_val (&op)) + { + tree res = op.ops[0]; + if (res == lhs1) + return build2 (code1, type, op1a, op1b); + else if (res == lhs2) + return build2 (code2, type, op2a, op2b); + else + return res; + } + } + + return NULL_TREE; +} + /* Try to simplify the AND of two comparisons, specified by (OP1A CODE1 OP1B) and (OP2B CODE2 OP2B), respectively. If this can be simplified to a single expression (without requiring @@ -5842,14 +5912,22 @@ and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, If the result expression is non-null, it has boolean type. */ tree -maybe_fold_and_comparisons (enum tree_code code1, tree op1a, tree op1b, +maybe_fold_and_comparisons (tree type, + enum tree_code code1, tree op1a, tree op1b, enum tree_code code2, tree op2a, tree op2b) { - tree t = and_comparisons_1 (code1, op1a, op1b, code2, op2a, op2b); - if (t) + if (tree t = and_comparisons_1 (type, code1, op1a, op1b, code2, op2a, op2b)) return t; - else - return and_comparisons_1 (code2, op2a, op2b, code1, op1a, op1b); + + if (tree t = and_comparisons_1 (type, code2, op2a, op2b, code1, op1a, op1b)) + return t; + + if (tree t = maybe_fold_comparisons_from_match_pd (type, BIT_AND_EXPR, code1, + op1a, op1b, code2, op2a, + op2b)) + return t; + + return NULL_TREE; } /* Helper function for or_comparisons_1: try to simplify the OR of the @@ -5858,7 +5936,7 @@ maybe_fold_and_comparisons (enum tree_code code1, tree op1a, tree op1b, Return NULL_EXPR if we can't simplify this to a single expression. */ static tree -or_var_with_comparison (tree var, bool invert, +or_var_with_comparison (tree type, tree var, bool invert, enum tree_code code2, tree op2a, tree op2b) { tree t; @@ -5872,11 +5950,11 @@ or_var_with_comparison (tree var, bool invert, !var OR (op2a code2 op2b) => !(var AND !(op2a code2 op2b)) Then we only have to consider the simpler non-inverted cases. */ if (invert) - t = and_var_with_comparison_1 (stmt, + t = and_var_with_comparison_1 (type, stmt, invert_tree_comparison (code2, false), op2a, op2b); else - t = or_var_with_comparison_1 (stmt, code2, op2a, op2b); + t = or_var_with_comparison_1 (type, stmt, code2, op2a, op2b); return canonicalize_bool (t, invert); } @@ -5885,7 +5963,7 @@ or_var_with_comparison (tree var, bool invert, Return NULL_EXPR if we can't simplify this to a single expression. */ static tree -or_var_with_comparison_1 (gimple *stmt, +or_var_with_comparison_1 (tree type, gimple *stmt, enum tree_code code2, tree op2a, tree op2b) { tree var = gimple_assign_lhs (stmt); @@ -5916,7 +5994,7 @@ or_var_with_comparison_1 (gimple *stmt, /* If the definition is a comparison, recurse on it. */ if (TREE_CODE_CLASS (innercode) == tcc_comparison) { - tree t = or_comparisons_1 (innercode, + tree t = or_comparisons_1 (type, innercode, gimple_assign_rhs1 (stmt), gimple_assign_rhs2 (stmt), code2, @@ -5952,18 +6030,20 @@ or_var_with_comparison_1 (gimple *stmt, else if (inner1 == false_test_var) return (is_or ? boolean_true_node - : or_var_with_comparison (inner2, false, code2, op2a, op2b)); + : or_var_with_comparison (type, inner2, false, code2, op2a, + op2b)); else if (inner2 == false_test_var) return (is_or ? boolean_true_node - : or_var_with_comparison (inner1, false, code2, op2a, op2b)); + : or_var_with_comparison (type, inner1, false, code2, op2a, + op2b)); /* Next, redistribute/reassociate the OR across the inner tests. Compute the first partial result, (inner1 OR (op2a code op2b)) */ if (TREE_CODE (inner1) == SSA_NAME && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner1)) && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison - && (t = maybe_fold_or_comparisons (gimple_assign_rhs_code (s), + && (t = maybe_fold_or_comparisons (type, gimple_assign_rhs_code (s), gimple_assign_rhs1 (s), gimple_assign_rhs2 (s), code2, op2a, op2b))) @@ -5995,7 +6075,7 @@ or_var_with_comparison_1 (gimple *stmt, if (TREE_CODE (inner2) == SSA_NAME && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner2)) && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison - && (t = maybe_fold_or_comparisons (gimple_assign_rhs_code (s), + && (t = maybe_fold_or_comparisons (type, gimple_assign_rhs_code (s), gimple_assign_rhs1 (s), gimple_assign_rhs2 (s), code2, op2a, op2b))) @@ -6052,7 +6132,7 @@ or_var_with_comparison_1 (gimple *stmt, in the first comparison but not the second. */ static tree -or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, +or_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b, enum tree_code code2, tree op2a, tree op2b) { tree truth_type = truth_type_for (TREE_TYPE (op1a)); @@ -6226,7 +6306,8 @@ or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, { case GIMPLE_ASSIGN: /* Try to simplify by copy-propagating the definition. */ - return or_var_with_comparison (op1a, invert, code2, op2a, op2b); + return or_var_with_comparison (type, op1a, invert, code2, op2a, + op2b); case GIMPLE_PHI: /* If every argument to the PHI produces the same result when @@ -6276,7 +6357,7 @@ or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, gimple_bb (def_stmt), gimple_bb (stmt))) return NULL_TREE; - temp = or_var_with_comparison (arg, invert, code2, + temp = or_var_with_comparison (type, arg, invert, code2, op2a, op2b); if (!temp) return NULL_TREE; @@ -6306,16 +6387,23 @@ or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, If the result expression is non-null, it has boolean type. */ tree -maybe_fold_or_comparisons (enum tree_code code1, tree op1a, tree op1b, +maybe_fold_or_comparisons (tree type, + enum tree_code code1, tree op1a, tree op1b, enum tree_code code2, tree op2a, tree op2b) { - tree t = or_comparisons_1 (code1, op1a, op1b, code2, op2a, op2b); - if (t) + if (tree t = or_comparisons_1 (type, code1, op1a, op1b, code2, op2a, op2b)) return t; - else - return or_comparisons_1 (code2, op2a, op2b, code1, op1a, op1b); -} + if (tree t = or_comparisons_1 (type, code2, op2a, op2b, code1, op1a, op1b)) + return t; + + if (tree t = maybe_fold_comparisons_from_match_pd (type, BIT_IOR_EXPR, code1, + op1a, op1b, code2, op2a, + op2b)) + return t; + + return NULL_TREE; +} /* Fold STMT to a constant using VALUEIZE to valueize SSA names. diff --git a/gcc/gimple-fold.h b/gcc/gimple-fold.h index 673d484..f9d1d54 100644 --- a/gcc/gimple-fold.h +++ b/gcc/gimple-fold.h @@ -31,9 +31,9 @@ extern void gimplify_and_update_call_from_tree (gimple_stmt_iterator *, tree); extern bool fold_stmt (gimple_stmt_iterator *); extern bool fold_stmt (gimple_stmt_iterator *, tree (*) (tree)); extern bool fold_stmt_inplace (gimple_stmt_iterator *); -extern tree maybe_fold_and_comparisons (enum tree_code, tree, tree, +extern tree maybe_fold_and_comparisons (tree, enum tree_code, tree, tree, enum tree_code, tree, tree); -extern tree maybe_fold_or_comparisons (enum tree_code, tree, tree, +extern tree maybe_fold_or_comparisons (tree, enum tree_code, tree, tree, enum tree_code, tree, tree); extern bool optimize_atomic_compare_exchange_p (gimple *); extern void fold_builtin_atomic_compare_exchange (gimple_stmt_iterator *); diff --git a/gcc/gimple.c b/gcc/gimple.c index 633ef51..88250ca 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -110,10 +110,27 @@ gimple_set_code (gimple *g, enum gimple_code code) /* Return the number of bytes needed to hold a GIMPLE statement with code CODE. */ -static inline size_t -gimple_size (enum gimple_code code) +size_t +gimple_size (enum gimple_code code, unsigned num_ops) { - return gsstruct_code_size[gss_for_code (code)]; + size_t size = gsstruct_code_size[gss_for_code (code)]; + if (num_ops > 0) + size += (sizeof (tree) * (num_ops - 1)); + return size; +} + +/* Initialize GIMPLE statement G with CODE and NUM_OPS. */ + +void +gimple_init (gimple *g, enum gimple_code code, unsigned num_ops) +{ + gimple_set_code (g, code); + gimple_set_num_ops (g, num_ops); + + /* Do not call gimple_set_modified here as it has other side + effects and this tuple is still not completely built. */ + g->modified = 1; + gimple_init_singleton (g); } /* Allocate memory for a GIMPLE statement with code CODE and NUM_OPS @@ -125,10 +142,7 @@ gimple_alloc (enum gimple_code code, unsigned num_ops MEM_STAT_DECL) size_t size; gimple *stmt; - size = gimple_size (code); - if (num_ops > 0) - size += sizeof (tree) * (num_ops - 1); - + size = gimple_size (code, num_ops); if (GATHER_STATISTICS) { enum gimple_alloc_kind kind = gimple_alloc_kind (code); @@ -137,14 +151,7 @@ gimple_alloc (enum gimple_code code, unsigned num_ops MEM_STAT_DECL) } stmt = ggc_alloc_cleared_gimple_statement_stat (size PASS_MEM_STAT); - gimple_set_code (stmt, code); - gimple_set_num_ops (stmt, num_ops); - - /* Do not call gimple_set_modified here as it has other side - effects and this tuple is still not completely built. */ - stmt->modified = 1; - gimple_init_singleton (stmt); - + gimple_init (stmt, code, num_ops); return stmt; } diff --git a/gcc/gimple.h b/gcc/gimple.h index 55f5d0d..cf1f8da 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -1445,6 +1445,8 @@ extern enum gimple_statement_structure_enum const gss_for_code_[]; of comminucating the profile info to the builtin expanders. */ extern gimple *currently_expanding_gimple_stmt; +size_t gimple_size (enum gimple_code code, unsigned num_ops = 0); +void gimple_init (gimple *g, enum gimple_code code, unsigned num_ops); gimple *gimple_alloc (enum gimple_code, unsigned CXX_MEM_STAT_INFO); greturn *gimple_build_return (tree); void gimple_call_reset_alias_info (gcall *); diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index da67e39..40ad4c5 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -436,7 +436,7 @@ fold_or_predicates (location_t loc, tree c1, tree c2) if (code1 != ERROR_MARK && code2 != ERROR_MARK) { - tree t = maybe_fold_or_comparisons (code1, op1a, op1b, + tree t = maybe_fold_or_comparisons (boolean_type_node, code1, op1a, op1b, code2, op2a, op2b); if (t) return t; diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c index f30816a..90d8bb5 100644 --- a/gcc/tree-ssa-ifcombine.c +++ b/gcc/tree-ssa-ifcombine.c @@ -555,7 +555,7 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv, return false; /* Don't return false so fast, try maybe_fold_or_comparisons? */ - if (!(t = maybe_fold_and_comparisons (inner_cond_code, + if (!(t = maybe_fold_and_comparisons (boolean_type_node, inner_cond_code, gimple_cond_lhs (inner_cond), gimple_cond_rhs (inner_cond), outer_cond_code, diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index df76e66..510dfd1 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -2088,12 +2088,15 @@ eliminate_redundant_comparison (enum tree_code opcode, /* If we got here, we have a match. See if we can combine the two comparisons. */ + tree type = TREE_TYPE (gimple_assign_lhs (def1)); if (opcode == BIT_IOR_EXPR) - t = maybe_fold_or_comparisons (lcode, op1, op2, + t = maybe_fold_or_comparisons (type, + lcode, op1, op2, rcode, gimple_assign_rhs1 (def2), gimple_assign_rhs2 (def2)); else - t = maybe_fold_and_comparisons (lcode, op1, op2, + t = maybe_fold_and_comparisons (type, + lcode, op1, op2, rcode, gimple_assign_rhs1 (def2), gimple_assign_rhs2 (def2)); if (!t) @@ -3745,10 +3748,11 @@ optimize_range_tests (enum tree_code opcode, /* A subroutine of optimize_vec_cond_expr to extract and canonicalize the operands of the VEC_COND_EXPR. Returns ERROR_MARK on failure, - otherwise the comparison code. */ + otherwise the comparison code. TYPE is a return value that is set + to type of comparison. */ static tree_code -ovce_extract_ops (tree var, gassign **rets, bool *reti) +ovce_extract_ops (tree var, gassign **rets, bool *reti, tree *type) { if (TREE_CODE (var) != SSA_NAME) return ERROR_MARK; @@ -3790,6 +3794,8 @@ ovce_extract_ops (tree var, gassign **rets, bool *reti) *rets = stmt; if (reti) *reti = inv; + if (type) + *type = TREE_TYPE (cond); return cmp; } @@ -3811,7 +3817,8 @@ optimize_vec_cond_expr (tree_code opcode, vec *ops) gassign *stmt0; bool invert; - tree_code cmp0 = ovce_extract_ops (elt0, &stmt0, &invert); + tree type; + tree_code cmp0 = ovce_extract_ops (elt0, &stmt0, &invert, &type); if (cmp0 == ERROR_MARK) continue; @@ -3820,7 +3827,7 @@ optimize_vec_cond_expr (tree_code opcode, vec *ops) tree &elt1 = (*ops)[j]->op; gassign *stmt1; - tree_code cmp1 = ovce_extract_ops (elt1, &stmt1, NULL); + tree_code cmp1 = ovce_extract_ops (elt1, &stmt1, NULL, NULL); if (cmp1 == ERROR_MARK) continue; @@ -3834,9 +3841,11 @@ optimize_vec_cond_expr (tree_code opcode, vec *ops) tree comb; if (opcode == BIT_AND_EXPR) - comb = maybe_fold_and_comparisons (cmp0, x0, y0, cmp1, x1, y1); + comb = maybe_fold_and_comparisons (type, cmp0, x0, y0, cmp1, x1, + y1); else if (opcode == BIT_IOR_EXPR) - comb = maybe_fold_or_comparisons (cmp0, x0, y0, cmp1, x1, y1); + comb = maybe_fold_or_comparisons (type, cmp0, x0, y0, cmp1, x1, + y1); else gcc_unreachable (); if (comb == NULL) diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c index 3911db9..f7b638d 100644 --- a/gcc/tree-ssanames.c +++ b/gcc/tree-ssanames.c @@ -252,6 +252,19 @@ flush_ssaname_freelist (void) vec_safe_truncate (FREE_SSANAMES_QUEUE (cfun), 0); } +/* Initialize SSA_NAME_IMM_USE_NODE of a SSA NAME. */ + +void +init_ssa_name_imm_use (tree name) +{ + use_operand_p imm; + imm = &(SSA_NAME_IMM_USE_NODE (name)); + imm->use = NULL; + imm->prev = imm; + imm->next = imm; + imm->loc.ssa_name = name; +} + /* Return an SSA_NAME node for variable VAR defined in statement STMT in function FN. STMT may be an empty statement for artificial references (e.g., default definitions created when a variable is @@ -263,8 +276,6 @@ make_ssa_name_fn (struct function *fn, tree var, gimple *stmt, unsigned int version) { tree t; - use_operand_p imm; - gcc_assert (VAR_P (var) || TREE_CODE (var) == PARM_DECL || TREE_CODE (var) == RESULT_DECL @@ -318,11 +329,7 @@ make_ssa_name_fn (struct function *fn, tree var, gimple *stmt, SSA_NAME_IN_FREE_LIST (t) = 0; SSA_NAME_IS_DEFAULT_DEF (t) = 0; - imm = &(SSA_NAME_IMM_USE_NODE (t)); - imm->use = NULL; - imm->prev = imm; - imm->next = imm; - imm->loc.ssa_name = t; + init_ssa_name_imm_use (t); return t; } diff --git a/gcc/tree-ssanames.h b/gcc/tree-ssanames.h index 6e6cffb..1a7d0bc 100644 --- a/gcc/tree-ssanames.h +++ b/gcc/tree-ssanames.h @@ -82,6 +82,7 @@ extern void fini_ssanames (struct function *); extern void ssanames_print_statistics (void); extern tree make_ssa_name_fn (struct function *, tree, gimple *, unsigned int version = 0); +extern void init_ssa_name_imm_use (tree); extern void release_ssa_name_fn (struct function *, tree); extern bool get_ptr_info_alignment (struct ptr_info_def *, unsigned int *, unsigned int *); -- cgit v1.1 From c16504f6eabad7e173e4fbcfacf52820fffcb9ec Mon Sep 17 00:00:00 2001 From: Li Jia He Date: Mon, 16 Sep 2019 14:22:16 +0000 Subject: Fix PR88784, middle end is missing some optimizations about unsigned 2019-09-16 Li Jia He Qi Feng PR middle-end/88784 * match.pd (x > y && x != XXX_MIN): Optimize into 'x > y'. (x > y && x == XXX_MIN): Optimize into 'false'. (x <= y && x == XXX_MIN): Optimize into 'x == XXX_MIN'. (x < y && x != XXX_MAX): Optimize into 'x < y'. (x < y && x == XXX_MAX): Optimize into 'false'. (x >= y && x == XXX_MAX): Optimize into 'x == XXX_MAX'. (x > y || x != XXX_MIN): Optimize into 'x != XXX_MIN'. (x <= y || x != XXX_MIN): Optimize into 'true'. (x <= y || x == XXX_MIN): Optimize into 'x <= y'. (x < y || x != XXX_MAX): Optimize into 'x != XXX_MAX'. (x >= y || x != XXX_MAX): Optimize into 'true'. (x >= y || x == XXX_MAX): Optimize into 'x >= y'. 2019-09-16 Li Jia He Qi Feng PR middle-end/88784 * gcc.dg/pr88784-1.c: New testcase. * gcc.dg/pr88784-2.c: New testcase. * gcc.dg/pr88784-3.c: New testcase. * gcc.dg/pr88784-4.c: New testcase. * gcc.dg/pr88784-5.c: New testcase. * gcc.dg/pr88784-6.c: New testcase. * gcc.dg/pr88784-7.c: New testcase. * gcc.dg/pr88784-8.c: New testcase. * gcc.dg/pr88784-9.c: New testcase. * gcc.dg/pr88784-10.c: New testcase. * gcc.dg/pr88784-11.c: New testcase. * gcc.dg/pr88784-12.c: New testcase. Co-Authored-By: Qi Feng From-SVN: r275749 --- gcc/ChangeLog | 17 ++++++++ gcc/match.pd | 82 +++++++++++++++++++++++++++++++++++++-- gcc/testsuite/ChangeLog | 17 ++++++++ gcc/testsuite/gcc.dg/pr88784-1.c | 30 ++++++++++++++ gcc/testsuite/gcc.dg/pr88784-10.c | 32 +++++++++++++++ gcc/testsuite/gcc.dg/pr88784-11.c | 30 ++++++++++++++ gcc/testsuite/gcc.dg/pr88784-12.c | 30 ++++++++++++++ gcc/testsuite/gcc.dg/pr88784-2.c | 30 ++++++++++++++ gcc/testsuite/gcc.dg/pr88784-3.c | 32 +++++++++++++++ gcc/testsuite/gcc.dg/pr88784-4.c | 32 +++++++++++++++ gcc/testsuite/gcc.dg/pr88784-5.c | 31 +++++++++++++++ gcc/testsuite/gcc.dg/pr88784-6.c | 31 +++++++++++++++ gcc/testsuite/gcc.dg/pr88784-7.c | 31 +++++++++++++++ gcc/testsuite/gcc.dg/pr88784-8.c | 31 +++++++++++++++ gcc/testsuite/gcc.dg/pr88784-9.c | 32 +++++++++++++++ 15 files changed, 484 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr88784-1.c create mode 100644 gcc/testsuite/gcc.dg/pr88784-10.c create mode 100644 gcc/testsuite/gcc.dg/pr88784-11.c create mode 100644 gcc/testsuite/gcc.dg/pr88784-12.c create mode 100644 gcc/testsuite/gcc.dg/pr88784-2.c create mode 100644 gcc/testsuite/gcc.dg/pr88784-3.c create mode 100644 gcc/testsuite/gcc.dg/pr88784-4.c create mode 100644 gcc/testsuite/gcc.dg/pr88784-5.c create mode 100644 gcc/testsuite/gcc.dg/pr88784-6.c create mode 100644 gcc/testsuite/gcc.dg/pr88784-7.c create mode 100644 gcc/testsuite/gcc.dg/pr88784-8.c create mode 100644 gcc/testsuite/gcc.dg/pr88784-9.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 864da5a..3bb3837 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,21 @@ 2019-09-16 Li Jia He + Qi Feng + + PR middle-end/88784 + * match.pd (x > y && x != XXX_MIN): Optimize into 'x > y'. + (x > y && x == XXX_MIN): Optimize into 'false'. + (x <= y && x == XXX_MIN): Optimize into 'x == XXX_MIN'. + (x < y && x != XXX_MAX): Optimize into 'x < y'. + (x < y && x == XXX_MAX): Optimize into 'false'. + (x >= y && x == XXX_MAX): Optimize into 'x == XXX_MAX'. + (x > y || x != XXX_MIN): Optimize into 'x != XXX_MIN'. + (x <= y || x != XXX_MIN): Optimize into 'true'. + (x <= y || x == XXX_MIN): Optimize into 'x <= y'. + (x < y || x != XXX_MAX): Optimize into 'x != XXX_MAX'. + (x >= y || x != XXX_MAX): Optimize into 'true'. + (x >= y || x == XXX_MAX): Optimize into 'x >= y'. + +2019-09-16 Li Jia He Martin Liska * gimple-fold.c (and_comparisons_1): Add type as first diff --git a/gcc/match.pd b/gcc/match.pd index 5690cf3..2ca8800 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1883,6 +1883,80 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) { wide_int_to_tree (type, (wi::to_wide (@1) & (bitpos / BITS_PER_UNIT))); })))) +(match min_value + INTEGER_CST + (if (INTEGRAL_TYPE_P (type) + && wi::eq_p (wi::to_wide (t), wi::min_value (type))))) + +(match max_value + INTEGER_CST + (if (INTEGRAL_TYPE_P (type) + && wi::eq_p (wi::to_wide (t), wi::max_value (type))))) + +/* x > y && x != XXX_MIN --> x > y + x > y && x == XXX_MIN --> false . */ +(for eqne (eq ne) + (simplify + (bit_and:c (gt:c@2 @0 @1) (eqne @0 min_value)) + (switch + (if (eqne == EQ_EXPR) + { constant_boolean_node (false, type); }) + (if (eqne == NE_EXPR) + @2) + ))) + +/* x < y && x != XXX_MAX --> x < y + x < y && x == XXX_MAX --> false. */ +(for eqne (eq ne) + (simplify + (bit_and:c (lt:c@2 @0 @1) (eqne @0 max_value)) + (switch + (if (eqne == EQ_EXPR) + { constant_boolean_node (false, type); }) + (if (eqne == NE_EXPR) + @2) + ))) + +/* x <= y && x == XXX_MIN --> x == XXX_MIN. */ +(simplify + (bit_and:c (le:c @0 @1) (eq@2 @0 min_value)) + @2) + +/* x >= y && x == XXX_MAX --> x == XXX_MAX. */ +(simplify + (bit_and:c (ge:c @0 @1) (eq@2 @0 max_value)) + @2) + +/* x > y || x != XXX_MIN --> x != XXX_MIN. */ +(simplify + (bit_ior:c (gt:c @0 @1) (ne@2 @0 min_value)) + @2) + +/* x <= y || x != XXX_MIN --> true. */ +(simplify + (bit_ior:c (le:c @0 @1) (ne @0 min_value)) + { constant_boolean_node (true, type); }) + +/* x <= y || x == XXX_MIN --> x <= y. */ +(simplify + (bit_ior:c (le:c@2 @0 @1) (eq @0 min_value)) + @2) + +/* x < y || x != XXX_MAX --> x != XXX_MAX. */ +(simplify + (bit_ior:c (lt:c @0 @1) (ne@2 @0 max_value)) + @2) + +/* x >= y || x != XXX_MAX --> true + x >= y || x == XXX_MAX --> x >= y. */ +(for eqne (eq ne) + (simplify + (bit_ior:c (ge:c@2 @0 @1) (eqne @0 max_value)) + (switch + (if (eqne == EQ_EXPR) + @2) + (if (eqne == NE_EXPR) + { constant_boolean_node (true, type); })))) /* We can't reassociate at all for saturating types. */ (if (!TYPE_SATURATING (type)) @@ -5425,10 +5499,10 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) on c, so could drop potentially-trapping arithmetic, but that's a valid simplification if the result of the operation isn't needed. - Avoid speculatively generating a stand-alone vector comparison - on targets that might not support them. Any target implementing - conditional internal functions must support the same comparisons - inside and outside a VEC_COND_EXPR. */ + Avoid speculatively generating a stand-alone vector comparison + on targets that might not support them. Any target implementing + conditional internal functions must support the same comparisons + inside and outside a VEC_COND_EXPR. */ #if GIMPLE (for uncond_op (UNCOND_BINARY) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b893ed0..7b9d0d0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,20 @@ +2019-09-16 Li Jia He + Qi Feng + + PR middle-end/88784 + * gcc.dg/pr88784-1.c: New testcase. + * gcc.dg/pr88784-2.c: New testcase. + * gcc.dg/pr88784-3.c: New testcase. + * gcc.dg/pr88784-4.c: New testcase. + * gcc.dg/pr88784-5.c: New testcase. + * gcc.dg/pr88784-6.c: New testcase. + * gcc.dg/pr88784-7.c: New testcase. + * gcc.dg/pr88784-8.c: New testcase. + * gcc.dg/pr88784-9.c: New testcase. + * gcc.dg/pr88784-10.c: New testcase. + * gcc.dg/pr88784-11.c: New testcase. + * gcc.dg/pr88784-12.c: New testcase. + 2019-09-16 Richard Biener PR tree-optimization/91756 diff --git a/gcc/testsuite/gcc.dg/pr88784-1.c b/gcc/testsuite/gcc.dg/pr88784-1.c new file mode 100644 index 0000000..b8daae0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr88784-1.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-ifcombine" } */ + +#include + +_Bool and1(unsigned x, unsigned y) +{ + /* x > y && x != 0 --> x > y */ + return x > y && x != 0; +} + +_Bool and2(unsigned x, unsigned y) +{ + /* x < y && x != UINT_MAX --> x < y */ + return x < y && x != UINT_MAX; +} + +_Bool and3(signed x, signed y) +{ + /* x > y && x != INT_MIN --> x > y */ + return x > y && x != INT_MIN; +} + +_Bool and4(signed x, signed y) +{ + /* x < y && x != INT_MAX --> x < y */ + return x < y && x != INT_MAX; +} + +/* { dg-final { scan-tree-dump-not " != " "ifcombine" } } */ diff --git a/gcc/testsuite/gcc.dg/pr88784-10.c b/gcc/testsuite/gcc.dg/pr88784-10.c new file mode 100644 index 0000000..958d765 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr88784-10.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +#include + +_Bool or1(unsigned x, unsigned y) +{ + /* x <= y || x != 0 --> true */ + return x <= y || x != 0; +} + +_Bool or2(unsigned x, unsigned y) +{ + /* x >= y || x != UINT_MAX --> true */ + return x >= y || x != UINT_MAX; +} + +_Bool or3(signed x, signed y) +{ + /* x <= y || x != INT_MIN --> true */ + return x <= y || x != INT_MIN; +} + +_Bool or4(signed x, signed y) +{ + /* x >= y || x != INT_MAX --> true */ + return x >= y || x != INT_MAX; +} + +/* { dg-final { scan-tree-dump-not " != " "optimized" } } */ +/* { dg-final { scan-tree-dump-not " <= " "optimized" } } */ +/* { dg-final { scan-tree-dump-not " >= " "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/pr88784-11.c b/gcc/testsuite/gcc.dg/pr88784-11.c new file mode 100644 index 0000000..c4b0508 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr88784-11.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-ifcombine" } */ + +#include + +_Bool or1(unsigned x, unsigned y) +{ + /* x <= y || x == 0 --> x <= y */ + return x <= y || x == 0; +} + +_Bool or2(unsigned x, unsigned y) +{ + /* x >= y || x == UINT_MAX --> x >= y */ + return x >= y || x == UINT_MAX; +} + +_Bool or3(signed x, signed y) +{ + /* x <= y || x == INT_MIN --> x <= y */ + return x <= y || x == INT_MIN; +} + +_Bool or4(signed x, signed y) +{ + /* x >= y || x == INT_MAX --> x >= y */ + return x >= y || x == INT_MAX; +} + +/* { dg-final { scan-tree-dump-not " == " "ifcombine" } } */ diff --git a/gcc/testsuite/gcc.dg/pr88784-12.c b/gcc/testsuite/gcc.dg/pr88784-12.c new file mode 100644 index 0000000..5b60b388 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr88784-12.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-dce3" } */ + +#include + +_Bool or1(unsigned x, unsigned y) +{ + /* x <= y || x == 0 --> x <= y */ + return x <= y || x == 0; +} + +_Bool or2(unsigned x, unsigned y) +{ + /* x >= y || x == UINT_MAX --> x >= y */ + return x >= y || x == UINT_MAX; +} + +_Bool or3(signed x, signed y) +{ + /* x <= y || x == INT_MIN --> x <= y */ + return x <= y || x == INT_MIN; +} + +_Bool or4(signed x, signed y) +{ + /* x >= y || x == INT_MAX --> x >= y */ + return x >= y || x == INT_MAX; +} + +/* { dg-final { scan-tree-dump-not " == " "dce3" } } */ diff --git a/gcc/testsuite/gcc.dg/pr88784-2.c b/gcc/testsuite/gcc.dg/pr88784-2.c new file mode 100644 index 0000000..ed360018 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr88784-2.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +#include + +_Bool and1(unsigned x, unsigned y) +{ + /* x > y && x != 0 --> x > y */ + return x > y && x != 0; +} + +_Bool and2(unsigned x, unsigned y) +{ + /* x < y && x != UINT_MAX --> x < y */ + return x < y && x != UINT_MAX; +} + +_Bool and3(signed x, signed y) +{ + /* x > y && x != INT_MIN --> x > y */ + return x > y && x != INT_MIN; +} + +_Bool and4(signed x, signed y) +{ + /* x < y && x != INT_MAX --> x < y */ + return x < y && x != INT_MAX; +} + +/* { dg-final { scan-tree-dump-not " != " "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/pr88784-3.c b/gcc/testsuite/gcc.dg/pr88784-3.c new file mode 100644 index 0000000..8c48e1b --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr88784-3.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-ifcombine" } */ + +#include + +_Bool and1(unsigned x, unsigned y) +{ + /* x > y && x == 0 --> false */ + return x > y && x == 0; +} + +_Bool and2(unsigned x, unsigned y) +{ + /* x < y && x == UINT_MAX --> false */ + return x < y && x == UINT_MAX; +} + +_Bool and3(signed x, signed y) +{ + /* x > y && x == INT_MIN --> false */ + return x > y && x == INT_MIN; +} + +_Bool and4(signed x, signed y) +{ + /* x < y && x == INT_MAX --> false */ + return x < y && x == INT_MAX; +} + +/* { dg-final { scan-tree-dump-not " == " "ifcombine" } } */ +/* { dg-final { scan-tree-dump-not " > " "ifcombine" } } */ +/* { dg-final { scan-tree-dump-not " < " "ifcombine" } } */ diff --git a/gcc/testsuite/gcc.dg/pr88784-4.c b/gcc/testsuite/gcc.dg/pr88784-4.c new file mode 100644 index 0000000..a9aa74c --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr88784-4.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +#include + +_Bool and1(unsigned x, unsigned y) +{ + /* x > y && x == 0 --> false */ + return x > y && x == 0; +} + +_Bool and2(unsigned x, unsigned y) +{ + /* x < y && x == UINT_MAX --> false */ + return x < y && x == UINT_MAX; +} + +_Bool and3(signed x, signed y) +{ + /* x > y && x == INT_MIN --> false */ + return x > y && x == INT_MIN; +} + +_Bool and4(signed x, signed y) +{ + /* x < y && x == INT_MAX --> false */ + return x < y && x == INT_MAX; +} + +/* { dg-final { scan-tree-dump-not " == " "optimized" } } */ +/* { dg-final { scan-tree-dump-not " > " "optimized" } } */ +/* { dg-final { scan-tree-dump-not " < " "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/pr88784-5.c b/gcc/testsuite/gcc.dg/pr88784-5.c new file mode 100644 index 0000000..b147abb --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr88784-5.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-ifcombine" } */ + +#include + +_Bool and1(unsigned x, unsigned y) +{ + /* x <= y && x == 0 --> x == 0 */ + return x <= y && x == 0; +} + +_Bool and2(unsigned x, unsigned y) +{ + /* x >= y && x == UINT_MAX --> x == UINT_MAX */ + return x >= y && x == UINT_MAX; +} + +_Bool and3(signed x, signed y) +{ + /* x <= y && x == INT_MIN --> x == INT_MIN */ + return x <= y && x == INT_MIN; +} + +_Bool and4(signed x, signed y) +{ + /* x >= y && x == INT_MAX --> x == INT_MAX */ + return x >= y && x == INT_MAX; +} + +/* { dg-final { scan-tree-dump-not " <= " "ifcombine" } } */ +/* { dg-final { scan-tree-dump-not " >= " "ifcombine" } } */ diff --git a/gcc/testsuite/gcc.dg/pr88784-6.c b/gcc/testsuite/gcc.dg/pr88784-6.c new file mode 100644 index 0000000..6d5bd7b --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr88784-6.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +#include + +_Bool and1(unsigned x, unsigned y) +{ + /* x <= y && x == 0 --> x == 0 */ + return x <= y && x == 0; +} + +_Bool and2(unsigned x, unsigned y) +{ + /* x >= y && x == UINT_MAX --> x == UINT_MAX */ + return x >= y && x == UINT_MAX; +} + +_Bool and3(signed x, signed y) +{ + /* x <= y && x == INT_MIN --> x == INT_MIN */ + return x <= y && x == INT_MIN; +} + +_Bool and4(signed x, signed y) +{ + /* x >= y && x == INT_MAX --> x == INT_MAX */ + return x >= y && x == INT_MAX; +} + +/* { dg-final { scan-tree-dump-not " <= " "optimized" } } */ +/* { dg-final { scan-tree-dump-not " >= " "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/pr88784-7.c b/gcc/testsuite/gcc.dg/pr88784-7.c new file mode 100644 index 0000000..6577ff9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr88784-7.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-ifcombine" } */ + +#include + +_Bool or1(unsigned x, unsigned y) +{ + /* x > y || x != 0 --> x != 0 */ + return x > y || x != 0; +} + +_Bool or2(unsigned x, unsigned y) +{ + /* x < y || x != UINT_MAX --> x != UINT_MAX */ + return x < y || x != UINT_MAX; +} + +_Bool or3(signed x, signed y) +{ + /* x > y || x != INT_MIN --> x != INT_MIN */ + return x > y || x != INT_MIN; +} + +_Bool or4(signed x, signed y) +{ + /* x < y || x != INT_MAX --> x != INT_MAX */ + return x < y || x != INT_MAX; +} + +/* { dg-final { scan-tree-dump-not " > " "ifcombine" } } */ +/* { dg-final { scan-tree-dump-not " < " "ifcombine" } } */ diff --git a/gcc/testsuite/gcc.dg/pr88784-8.c b/gcc/testsuite/gcc.dg/pr88784-8.c new file mode 100644 index 0000000..6bb56a9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr88784-8.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +#include + +_Bool or1(unsigned x, unsigned y) +{ + /* x > y || x != 0 --> x != 0 */ + return x > y || x != 0; +} + +_Bool or2(unsigned x, unsigned y) +{ + /* x < y || x != UINT_MAX --> x != UINT_MAX */ + return x < y || x != UINT_MAX; +} + +_Bool or3(signed x, signed y) +{ + /* x > y || x != INT_MIN --> x != INT_MIN */ + return x > y || x != INT_MIN; +} + +_Bool or4(signed x, signed y) +{ + /* x < y || x != INT_MAX --> x != INT_MAX */ + return x < y || x != INT_MAX; +} + +/* { dg-final { scan-tree-dump-not " > " "optimized" } } */ +/* { dg-final { scan-tree-dump-not " < " "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/pr88784-9.c b/gcc/testsuite/gcc.dg/pr88784-9.c new file mode 100644 index 0000000..27e3281 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr88784-9.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-ifcombine" } */ + +#include + +_Bool or1(unsigned x, unsigned y) +{ + /* x <= y || x != 0 --> true */ + return x <= y || x != 0; +} + +_Bool or2(unsigned x, unsigned y) +{ + /* x >= y || x != UINT_MAX --> true */ + return x >= y || x != UINT_MAX; +} + +_Bool or3(signed x, signed y) +{ + /* x <= y || x != INT_MIN --> true */ + return x <= y || x != INT_MIN; +} + +_Bool or4(signed x, signed y) +{ + /* x >= y || x != INT_MAX --> true */ + return x >= y || x != INT_MAX; +} + +/* { dg-final { scan-tree-dump-not " != " "ifcombine" } } */ +/* { dg-final { scan-tree-dump-not " <= " "ifcombine" } } */ +/* { dg-final { scan-tree-dump-not " >= " "ifcombine" } } */ -- cgit v1.1 From ae9c3507829ca139749ac3f9cf4a78707a036d3b Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Mon, 16 Sep 2019 16:22:36 +0200 Subject: Rewrite part of and_comparisons_1 into match.pd. 2019-09-16 Martin Liska * genmatch.c (dt_node::append_simplify): Do not print warning when we have duplicate patterns belonging to a same simplify rule. * gimple-fold.c (and_comparisons_1): Remove matching moved to match.pd. (maybe_fold_comparisons_from_match_pd): Handle tcc_comparison as a results. * match.pd: Handle (X == CST1) && (X OP2 CST2) conditions. From-SVN: r275750 --- gcc/ChangeLog | 10 ++++ gcc/genmatch.c | 7 ++- gcc/gimple-fold.c | 140 ++++-------------------------------------------------- gcc/match.pd | 66 +++++++++++++++++++++++++ 4 files changed, 92 insertions(+), 131 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3bb3837..cc3a397 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2019-09-16 Martin Liska + + * genmatch.c (dt_node::append_simplify): Do not print + warning when we have duplicate patterns belonging + to a same simplify rule. + * gimple-fold.c (and_comparisons_1): Remove matching moved to match.pd. + (maybe_fold_comparisons_from_match_pd): Handle + tcc_comparison as a results. + * match.pd: Handle (X == CST1) && (X OP2 CST2) conditions. + 2019-09-16 Li Jia He Qi Feng diff --git a/gcc/genmatch.c b/gcc/genmatch.c index 2e7bf27..cede432 100644 --- a/gcc/genmatch.c +++ b/gcc/genmatch.c @@ -1894,10 +1894,15 @@ dt_node * dt_node::append_simplify (simplify *s, unsigned pattern_no, dt_operand **indexes) { + dt_simplify *s2; dt_simplify *n = new dt_simplify (s, pattern_no, indexes); for (unsigned i = 0; i < kids.length (); ++i) - if (dt_simplify *s2 = dyn_cast (kids[i])) + if ((s2 = dyn_cast (kids[i])) + && (verbose >= 1 + || s->match->location != s2->s->match->location)) { + /* With a nested patters, it's hard to avoid these in order + to keep match.pd rules relatively small. */ warning_at (s->match->location, "duplicate pattern"); warning_at (s2->s->match->location, "previous pattern defined here"); print_operand (s->match, stderr); diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 6d9ba36..f82bedc 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -5620,136 +5620,6 @@ and_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b, return t; } - /* If both comparisons are of the same value against constants, we might - be able to merge them. */ - if (operand_equal_p (op1a, op2a, 0) - && TREE_CODE (op1b) == INTEGER_CST - && TREE_CODE (op2b) == INTEGER_CST) - { - int cmp = tree_int_cst_compare (op1b, op2b); - - /* If we have (op1a == op1b), we should either be able to - return that or FALSE, depending on whether the constant op1b - also satisfies the other comparison against op2b. */ - if (code1 == EQ_EXPR) - { - bool done = true; - bool val; - switch (code2) - { - case EQ_EXPR: val = (cmp == 0); break; - case NE_EXPR: val = (cmp != 0); break; - case LT_EXPR: val = (cmp < 0); break; - case GT_EXPR: val = (cmp > 0); break; - case LE_EXPR: val = (cmp <= 0); break; - case GE_EXPR: val = (cmp >= 0); break; - default: done = false; - } - if (done) - { - if (val) - return fold_build2 (code1, boolean_type_node, op1a, op1b); - else - return boolean_false_node; - } - } - /* Likewise if the second comparison is an == comparison. */ - else if (code2 == EQ_EXPR) - { - bool done = true; - bool val; - switch (code1) - { - case EQ_EXPR: val = (cmp == 0); break; - case NE_EXPR: val = (cmp != 0); break; - case LT_EXPR: val = (cmp > 0); break; - case GT_EXPR: val = (cmp < 0); break; - case LE_EXPR: val = (cmp >= 0); break; - case GE_EXPR: val = (cmp <= 0); break; - default: done = false; - } - if (done) - { - if (val) - return fold_build2 (code2, boolean_type_node, op2a, op2b); - else - return boolean_false_node; - } - } - - /* Same business with inequality tests. */ - else if (code1 == NE_EXPR) - { - bool val; - switch (code2) - { - case EQ_EXPR: val = (cmp != 0); break; - case NE_EXPR: val = (cmp == 0); break; - case LT_EXPR: val = (cmp >= 0); break; - case GT_EXPR: val = (cmp <= 0); break; - case LE_EXPR: val = (cmp > 0); break; - case GE_EXPR: val = (cmp < 0); break; - default: - val = false; - } - if (val) - return fold_build2 (code2, boolean_type_node, op2a, op2b); - } - else if (code2 == NE_EXPR) - { - bool val; - switch (code1) - { - case EQ_EXPR: val = (cmp == 0); break; - case NE_EXPR: val = (cmp != 0); break; - case LT_EXPR: val = (cmp <= 0); break; - case GT_EXPR: val = (cmp >= 0); break; - case LE_EXPR: val = (cmp < 0); break; - case GE_EXPR: val = (cmp > 0); break; - default: - val = false; - } - if (val) - return fold_build2 (code1, boolean_type_node, op1a, op1b); - } - - /* Chose the more restrictive of two < or <= comparisons. */ - else if ((code1 == LT_EXPR || code1 == LE_EXPR) - && (code2 == LT_EXPR || code2 == LE_EXPR)) - { - if ((cmp < 0) || (cmp == 0 && code1 == LT_EXPR)) - return fold_build2 (code1, boolean_type_node, op1a, op1b); - else - return fold_build2 (code2, boolean_type_node, op2a, op2b); - } - - /* Likewise chose the more restrictive of two > or >= comparisons. */ - else if ((code1 == GT_EXPR || code1 == GE_EXPR) - && (code2 == GT_EXPR || code2 == GE_EXPR)) - { - if ((cmp > 0) || (cmp == 0 && code1 == GT_EXPR)) - return fold_build2 (code1, boolean_type_node, op1a, op1b); - else - return fold_build2 (code2, boolean_type_node, op2a, op2b); - } - - /* Check for singleton ranges. */ - else if (cmp == 0 - && ((code1 == LE_EXPR && code2 == GE_EXPR) - || (code1 == GE_EXPR && code2 == LE_EXPR))) - return fold_build2 (EQ_EXPR, boolean_type_node, op1a, op2b); - - /* Check for disjoint ranges. */ - else if (cmp <= 0 - && (code1 == LT_EXPR || code1 == LE_EXPR) - && (code2 == GT_EXPR || code2 == GE_EXPR)) - return boolean_false_node; - else if (cmp >= 0 - && (code1 == GT_EXPR || code1 == GE_EXPR) - && (code2 == LT_EXPR || code2 == LE_EXPR)) - return boolean_false_node; - } - /* Perhaps the first comparison is (NAME != 0) or (NAME == 1) where NAME's definition is a truth value. See if there are any simplifications that can be done against the NAME's definition. */ @@ -5899,6 +5769,16 @@ maybe_fold_comparisons_from_match_pd (tree type, enum tree_code code, else return res; } + else if (op.code.is_tree_code () + && TREE_CODE_CLASS ((tree_code)op.code) == tcc_comparison) + { + tree op0 = op.ops[0]; + tree op1 = op.ops[1]; + if (op0 == lhs1 || op0 == lhs2 || op1 == lhs1 || op1 == lhs2) + return NULL_TREE; /* not simple */ + + return build2 ((enum tree_code)op.code, op.type, op0, op1); + } } return NULL_TREE; diff --git a/gcc/match.pd b/gcc/match.pd index 2ca8800..ac80dd7 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1958,6 +1958,72 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (eqne == NE_EXPR) { constant_boolean_node (true, type); })))) +/* Convert (X == CST1) && (X OP2 CST2) to a known value + based on CST1 OP2 CST2. Similarly for (X != CST1). */ + +(for code1 (eq ne) + (for code2 (eq ne lt gt le ge) + (simplify + (bit_and:c (code1@3 @0 INTEGER_CST@1) (code2@4 @0 INTEGER_CST@2)) + (with + { + int cmp = tree_int_cst_compare (@1, @2); + bool val; + switch (code2) + { + case EQ_EXPR: val = (cmp == 0); break; + case NE_EXPR: val = (cmp != 0); break; + case LT_EXPR: val = (cmp < 0); break; + case GT_EXPR: val = (cmp > 0); break; + case LE_EXPR: val = (cmp <= 0); break; + case GE_EXPR: val = (cmp >= 0); break; + default: gcc_unreachable (); + } + } + (switch + (if (code1 == EQ_EXPR && val) @3) + (if (code1 == EQ_EXPR && !val) { constant_boolean_node (false, type); }) + (if (code1 == NE_EXPR && !val) @4)))))) + +/* Convert (X OP1 CST1) && (X OP2 CST2). */ + +(for code1 (lt le gt ge) + (for code2 (lt le gt ge) + (simplify + (bit_and (code1:c@3 @0 INTEGER_CST@1) (code2:c@4 @0 INTEGER_CST@2)) + (with + { + int cmp = tree_int_cst_compare (@1, @2); + } + (switch + /* Choose the more restrictive of two < or <= comparisons. */ + (if ((code1 == LT_EXPR || code1 == LE_EXPR) + && (code2 == LT_EXPR || code2 == LE_EXPR)) + (if ((cmp < 0) || (cmp == 0 && code1 == LT_EXPR)) + @3 + @4)) + /* Likewise chose the more restrictive of two > or >= comparisons. */ + (if ((code1 == GT_EXPR || code1 == GE_EXPR) + && (code2 == GT_EXPR || code2 == GE_EXPR)) + (if ((cmp > 0) || (cmp == 0 && code1 == GT_EXPR)) + @3 + @4)) + /* Check for singleton ranges. */ + (if (cmp == 0 + && ((code1 == LE_EXPR && code2 == GE_EXPR) + || (code1 == GE_EXPR && code2 == LE_EXPR))) + (eq @0 @1)) + /* Check for disjoint ranges. */ + (if (cmp <= 0 + && (code1 == LT_EXPR || code1 == LE_EXPR) + && (code2 == GT_EXPR || code2 == GE_EXPR)) + { constant_boolean_node (false, type); }) + (if (cmp >= 0 + && (code1 == GT_EXPR || code1 == GE_EXPR) + && (code2 == LT_EXPR || code2 == LE_EXPR)) + { constant_boolean_node (false, type); }) + ))))) + /* We can't reassociate at all for saturating types. */ (if (!TYPE_SATURATING (type)) -- cgit v1.1 From 130c4034c732fae5196f02fe4248fb1a5a602276 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Mon, 16 Sep 2019 16:22:50 +0200 Subject: Rewrite first part of or_comparisons_1 into match.pd. 2019-09-16 Martin Liska * gimple-fold.c (or_comparisons_1): Remove rules moved to ... * match.pd: ... here. From-SVN: r275751 --- gcc/ChangeLog | 6 ++++ gcc/gimple-fold.c | 87 +------------------------------------------------------ gcc/match.pd | 28 ++++++++++++++++++ 3 files changed, 35 insertions(+), 86 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cc3a397..e70e090 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2019-09-16 Martin Liska + * gimple-fold.c (or_comparisons_1): Remove rules + moved to ... + * match.pd: ... here. + +2019-09-16 Martin Liska + * genmatch.c (dt_node::append_simplify): Do not print warning when we have duplicate patterns belonging to a same simplify rule. diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index f82bedc..694d2ee 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -6050,93 +6050,8 @@ or_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b, { int cmp = tree_int_cst_compare (op1b, op2b); - /* If we have (op1a != op1b), we should either be able to - return that or TRUE, depending on whether the constant op1b - also satisfies the other comparison against op2b. */ - if (code1 == NE_EXPR) - { - bool done = true; - bool val; - switch (code2) - { - case EQ_EXPR: val = (cmp == 0); break; - case NE_EXPR: val = (cmp != 0); break; - case LT_EXPR: val = (cmp < 0); break; - case GT_EXPR: val = (cmp > 0); break; - case LE_EXPR: val = (cmp <= 0); break; - case GE_EXPR: val = (cmp >= 0); break; - default: done = false; - } - if (done) - { - if (val) - return boolean_true_node; - else - return fold_build2 (code1, boolean_type_node, op1a, op1b); - } - } - /* Likewise if the second comparison is a != comparison. */ - else if (code2 == NE_EXPR) - { - bool done = true; - bool val; - switch (code1) - { - case EQ_EXPR: val = (cmp == 0); break; - case NE_EXPR: val = (cmp != 0); break; - case LT_EXPR: val = (cmp > 0); break; - case GT_EXPR: val = (cmp < 0); break; - case LE_EXPR: val = (cmp >= 0); break; - case GE_EXPR: val = (cmp <= 0); break; - default: done = false; - } - if (done) - { - if (val) - return boolean_true_node; - else - return fold_build2 (code2, boolean_type_node, op2a, op2b); - } - } - - /* See if an equality test is redundant with the other comparison. */ - else if (code1 == EQ_EXPR) - { - bool val; - switch (code2) - { - case EQ_EXPR: val = (cmp == 0); break; - case NE_EXPR: val = (cmp != 0); break; - case LT_EXPR: val = (cmp < 0); break; - case GT_EXPR: val = (cmp > 0); break; - case LE_EXPR: val = (cmp <= 0); break; - case GE_EXPR: val = (cmp >= 0); break; - default: - val = false; - } - if (val) - return fold_build2 (code2, boolean_type_node, op2a, op2b); - } - else if (code2 == EQ_EXPR) - { - bool val; - switch (code1) - { - case EQ_EXPR: val = (cmp == 0); break; - case NE_EXPR: val = (cmp != 0); break; - case LT_EXPR: val = (cmp > 0); break; - case GT_EXPR: val = (cmp < 0); break; - case LE_EXPR: val = (cmp >= 0); break; - case GE_EXPR: val = (cmp <= 0); break; - default: - val = false; - } - if (val) - return fold_build2 (code1, boolean_type_node, op1a, op1b); - } - /* Chose the less restrictive of two < or <= comparisons. */ - else if ((code1 == LT_EXPR || code1 == LE_EXPR) + if ((code1 == LT_EXPR || code1 == LE_EXPR) && (code2 == LT_EXPR || code2 == LE_EXPR)) { if ((cmp < 0) || (cmp == 0 && code1 == LT_EXPR)) diff --git a/gcc/match.pd b/gcc/match.pd index ac80dd7..c465eab 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -2024,6 +2024,34 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) { constant_boolean_node (false, type); }) ))))) +/* Convert (X == CST1) || (X OP2 CST2) to a known value + based on CST1 OP2 CST2. Similarly for (X != CST1). */ + +(for code1 (eq ne) + (for code2 (eq ne lt gt le ge) + (simplify + (bit_ior:c (code1@3 @0 INTEGER_CST@1) (code2@4 @0 INTEGER_CST@2)) + (with + { + int cmp = tree_int_cst_compare (@1, @2); + bool val; + switch (code2) + { + case EQ_EXPR: val = (cmp == 0); break; + case NE_EXPR: val = (cmp != 0); break; + case LT_EXPR: val = (cmp < 0); break; + case GT_EXPR: val = (cmp > 0); break; + case LE_EXPR: val = (cmp <= 0); break; + case GE_EXPR: val = (cmp >= 0); break; + default: gcc_unreachable (); + } + } + (switch + (if (code1 == EQ_EXPR && val) @4) + (if (code1 == NE_EXPR && val) { constant_boolean_node (true, type); }) + (if (code1 == NE_EXPR && !val) @3)))))) + + /* We can't reassociate at all for saturating types. */ (if (!TYPE_SATURATING (type)) -- cgit v1.1 From cda65821d3c398f5ad969ca1de71e8cd70c58e55 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Mon, 16 Sep 2019 16:23:04 +0200 Subject: Rewrite second part of or_comparisons_1 into match.pd. 2019-09-16 Martin Liska * gimple-fold.c (or_comparisons_1): Remove rules moved to ... * match.pd: ... here. From-SVN: r275752 --- gcc/ChangeLog | 6 ++++++ gcc/gimple-fold.c | 45 --------------------------------------------- gcc/match.pd | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 45 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e70e090..1921bc7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2019-09-16 Martin Liska + * gimple-fold.c (or_comparisons_1): Remove rules moved + to ... + * match.pd: ... here. + +2019-09-16 Martin Liska + * gimple-fold.c (or_comparisons_1): Remove rules moved to ... * match.pd: ... here. diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 694d2ee..8d642de 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -6042,51 +6042,6 @@ or_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b, return t; } - /* If both comparisons are of the same value against constants, we might - be able to merge them. */ - if (operand_equal_p (op1a, op2a, 0) - && TREE_CODE (op1b) == INTEGER_CST - && TREE_CODE (op2b) == INTEGER_CST) - { - int cmp = tree_int_cst_compare (op1b, op2b); - - /* Chose the less restrictive of two < or <= comparisons. */ - if ((code1 == LT_EXPR || code1 == LE_EXPR) - && (code2 == LT_EXPR || code2 == LE_EXPR)) - { - if ((cmp < 0) || (cmp == 0 && code1 == LT_EXPR)) - return fold_build2 (code2, boolean_type_node, op2a, op2b); - else - return fold_build2 (code1, boolean_type_node, op1a, op1b); - } - - /* Likewise chose the less restrictive of two > or >= comparisons. */ - else if ((code1 == GT_EXPR || code1 == GE_EXPR) - && (code2 == GT_EXPR || code2 == GE_EXPR)) - { - if ((cmp > 0) || (cmp == 0 && code1 == GT_EXPR)) - return fold_build2 (code2, boolean_type_node, op2a, op2b); - else - return fold_build2 (code1, boolean_type_node, op1a, op1b); - } - - /* Check for singleton ranges. */ - else if (cmp == 0 - && ((code1 == LT_EXPR && code2 == GT_EXPR) - || (code1 == GT_EXPR && code2 == LT_EXPR))) - return fold_build2 (NE_EXPR, boolean_type_node, op1a, op2b); - - /* Check for less/greater pairs that don't restrict the range at all. */ - else if (cmp >= 0 - && (code1 == LT_EXPR || code1 == LE_EXPR) - && (code2 == GT_EXPR || code2 == GE_EXPR)) - return boolean_true_node; - else if (cmp <= 0 - && (code1 == GT_EXPR || code1 == GE_EXPR) - && (code2 == LT_EXPR || code2 == LE_EXPR)) - return boolean_true_node; - } - /* Perhaps the first comparison is (NAME != 0) or (NAME == 1) where NAME's definition is a truth value. See if there are any simplifications that can be done against the NAME's definition. */ diff --git a/gcc/match.pd b/gcc/match.pd index c465eab..4fd7590 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -2051,6 +2051,44 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (code1 == NE_EXPR && val) { constant_boolean_node (true, type); }) (if (code1 == NE_EXPR && !val) @3)))))) +/* Convert (X OP1 CST1) || (X OP2 CST2). */ + +(for code1 (lt le gt ge) + (for code2 (lt le gt ge) + (simplify + (bit_ior (code1@3 @0 INTEGER_CST@1) (code2@4 @0 INTEGER_CST@2)) + (with + { + int cmp = tree_int_cst_compare (@1, @2); + } + (switch + /* Choose the more restrictive of two < or <= comparisons. */ + (if ((code1 == LT_EXPR || code1 == LE_EXPR) + && (code2 == LT_EXPR || code2 == LE_EXPR)) + (if ((cmp < 0) || (cmp == 0 && code1 == LT_EXPR)) + @4 + @3)) + /* Likewise chose the more restrictive of two > or >= comparisons. */ + (if ((code1 == GT_EXPR || code1 == GE_EXPR) + && (code2 == GT_EXPR || code2 == GE_EXPR)) + (if ((cmp > 0) || (cmp == 0 && code1 == GT_EXPR)) + @4 + @3)) + /* Check for singleton ranges. */ + (if (cmp == 0 + && ((code1 == LT_EXPR && code2 == GT_EXPR) + || (code1 == GT_EXPR && code2 == LT_EXPR))) + (ne @0 @2)) + /* Check for disjoint ranges. */ + (if (cmp >= 0 + && (code1 == LT_EXPR || code1 == LE_EXPR) + && (code2 == GT_EXPR || code2 == GE_EXPR)) + { constant_boolean_node (true, type); }) + (if (cmp <= 0 + && (code1 == GT_EXPR || code1 == GE_EXPR) + && (code2 == LT_EXPR || code2 == LE_EXPR)) + { constant_boolean_node (true, type); }) + ))))) /* We can't reassociate at all for saturating types. */ (if (!TYPE_SATURATING (type)) -- cgit v1.1 From e4ab9e060be99646f066264d6f23320825a46054 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 16 Sep 2019 12:19:18 -0400 Subject: * Makefile.in (build/genmatch.o): Depend on $(CPPLIB_H). From-SVN: r275753 --- gcc/ChangeLog | 4 ++++ gcc/Makefile.in | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1921bc7..63fae86 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2019-09-16 Jason Merrill + + * Makefile.in (build/genmatch.o): Depend on $(CPPLIB_H). + 2019-09-16 Martin Liska * gimple-fold.c (or_comparisons_1): Remove rules moved diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 0fe02fb..152df9f 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2783,7 +2783,7 @@ build/genmddump.o : genmddump.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \ $(CORETYPES_H) $(GTM_H) errors.h $(READ_MD_H) $(GENSUPPORT_H) build/genmatch.o : genmatch.c $(BCONFIG_H) $(SYSTEM_H) \ $(CORETYPES_H) errors.h $(HASH_TABLE_H) hash-map.h $(GGC_H) is-a.h \ - tree.def builtins.def internal-fn.def case-cfn-macros.h + tree.def builtins.def internal-fn.def case-cfn-macros.h $(CPPLIB_H) build/gencfn-macros.o : gencfn-macros.c $(BCONFIG_H) $(SYSTEM_H) \ $(CORETYPES_H) errors.h $(HASH_TABLE_H) hash-set.h builtins.def \ internal-fn.def -- cgit v1.1 From 48d552e5cd56ff3212d050efca3d5f34778af79f Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Mon, 16 Sep 2019 20:37:28 +0200 Subject: re PR target/91719 (gcc compiles seq_cst store on x86-64 differently from clang/icc) PR target/91719 * config/i386/i386.h (TARGET_USE_XCHG_FOR_ATOMIC_STORE): New macro. * config/i386/x86-tune.def (X86_TUNE_USE_XCHG_FOR_ATOMIC_STORE): New. * config/i386/sync.md (atomic_store): emit XCHG for TARGET_USE_XCHG_FOR_ATOMIC_STORE. From-SVN: r275754 --- gcc/ChangeLog | 8 ++++++++ gcc/config/i386/i386.h | 2 ++ gcc/config/i386/sync.md | 7 +++++-- gcc/config/i386/x86-tune.def | 4 ++++ 4 files changed, 19 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 63fae86..2f4de49 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2019-09-16 Uroš Bizjak + + PR target/91719 + * config/i386/i386.h (TARGET_USE_XCHG_FOR_ATOMIC_STORE): New macro. + * config/i386/x86-tune.def (X86_TUNE_USE_XCHG_FOR_ATOMIC_STORE): New. + * config/i386/sync.md (atomic_store): emit XCHG for + TARGET_USE_XCHG_FOR_ATOMIC_STORE. + 2019-09-16 Jason Merrill * Makefile.in (build/genmatch.o): Depend on $(CPPLIB_H). diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index a1d0484d7..885846e 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -590,6 +590,8 @@ extern unsigned char ix86_tune_features[X86_TUNE_LAST]; ix86_tune_features[X86_TUNE_AVOID_FALSE_DEP_FOR_BMI] #define TARGET_ONE_IF_CONV_INSN \ ix86_tune_features[X86_TUNE_ONE_IF_CONV_INSN] +#define TARGET_USE_XCHG_FOR_ATOMIC_STORE \ + ix86_tune_features[X86_TUNE_USE_XCHG_FOR_ATOMIC_STORE] #define TARGET_EMIT_VZEROUPPER \ ix86_tune_features[X86_TUNE_EMIT_VZEROUPPER] diff --git a/gcc/config/i386/sync.md b/gcc/config/i386/sync.md index ba146e3..2614ddb 100644 --- a/gcc/config/i386/sync.md +++ b/gcc/config/i386/sync.md @@ -306,8 +306,11 @@ { operands[1] = force_reg (mode, operands[1]); - /* For seq-cst stores, when we lack MFENCE, use XCHG. */ - if (is_mm_seq_cst (model) && !(TARGET_64BIT || TARGET_SSE2)) + /* For seq-cst stores, use XCHG + when we lack MFENCE or when target prefers XCHG. */ + if (is_mm_seq_cst (model) + && (!(TARGET_64BIT || TARGET_SSE2) + || TARGET_USE_XCHG_FOR_ATOMIC_STORE)) { emit_insn (gen_atomic_exchange (gen_reg_rtx (mode), operands[0], operands[1], diff --git a/gcc/config/i386/x86-tune.def b/gcc/config/i386/x86-tune.def index fd59a84..e289efd 100644 --- a/gcc/config/i386/x86-tune.def +++ b/gcc/config/i386/x86-tune.def @@ -313,6 +313,10 @@ DEF_TUNE (X86_TUNE_ONE_IF_CONV_INSN, "one_if_conv_insn", m_SILVERMONT | m_KNL | m_KNM | m_INTEL | m_CORE_ALL | m_GOLDMONT | m_GOLDMONT_PLUS | m_TREMONT | m_GENERIC) +/* X86_TUNE_USE_XCHG_FOR_ATOMIC_STORE: Use xchg instead of mov+mfence. */ +DEF_TUNE (X86_TUNE_USE_XCHG_FOR_ATOMIC_STORE, "use_xchg_for_atomic_store", + m_CORE_ALL | m_BDVER | m_ZNVER | m_GENERIC) + /*****************************************************************************/ /* 387 instruction selection tuning */ /*****************************************************************************/ -- cgit v1.1 From 9b47928e633f8f84db4cd6f863e3ea01c3ce63bb Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Mon, 16 Sep 2019 20:44:55 +0200 Subject: * config/i386/sync.md (atomic_store): Improve comment. From-SVN: r275755 --- gcc/config/i386/sync.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/config/i386/sync.md b/gcc/config/i386/sync.md index 2614ddb..189fee2 100644 --- a/gcc/config/i386/sync.md +++ b/gcc/config/i386/sync.md @@ -306,8 +306,8 @@ { operands[1] = force_reg (mode, operands[1]); - /* For seq-cst stores, use XCHG - when we lack MFENCE or when target prefers XCHG. */ + /* For seq-cst stores, use XCHG when we lack MFENCE + or when target prefers XCHG. */ if (is_mm_seq_cst (model) && (!(TARGET_64BIT || TARGET_SSE2) || TARGET_USE_XCHG_FOR_ATOMIC_STORE)) -- cgit v1.1 From 1890782243521d58f62bec44e773b0ddfc20de67 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Mon, 16 Sep 2019 20:50:35 +0200 Subject: pr89386.c (foo): Fix return type. * gcc.target/i386/pr89386.c (foo): Fix return type. * gcc.target/i386/pr89386-1.c (foo): Ditto. From-SVN: r275757 --- gcc/testsuite/gcc.target/i386/pr89386-1.c | 2 +- gcc/testsuite/gcc.target/i386/pr89386.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/gcc.target/i386/pr89386-1.c b/gcc/testsuite/gcc.target/i386/pr89386-1.c index a2d708b..479f0be 100644 --- a/gcc/testsuite/gcc.target/i386/pr89386-1.c +++ b/gcc/testsuite/gcc.target/i386/pr89386-1.c @@ -5,7 +5,7 @@ short a[N], b[N], c[N]; -int foo (void) +void foo (void) { int i; diff --git a/gcc/testsuite/gcc.target/i386/pr89386.c b/gcc/testsuite/gcc.target/i386/pr89386.c index b308787..b513bfa 100644 --- a/gcc/testsuite/gcc.target/i386/pr89386.c +++ b/gcc/testsuite/gcc.target/i386/pr89386.c @@ -5,7 +5,7 @@ short a[N], b[N], c[N]; -int foo (void) +void foo (void) { int i; -- cgit v1.1 From b3a77aa6ffa0186a966ad53360aa1485c783800a Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 16 Sep 2019 20:41:40 +0000 Subject: compiler: fix quoting of //go:linkname in error message Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/195718 From-SVN: r275758 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/gogo.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 522d408..1456026 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -5af62eda697da21155091cf5375ed9edb4639b67 +722990deeede7801e4ed3ca5d53ce312a19fcd7a The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 3ff88cb..e7af673 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -2541,7 +2541,7 @@ Gogo::add_linkname(const std::string& go_name, bool is_exported, { if (ext_name.empty()) go_error_at(loc, - ("//% missing external name " + ("% missing external name " "for declaration of %s"), go_name.c_str()); else -- cgit v1.1 From 61b204bf24adfe62d58400e60732bc569bc2164a Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Mon, 16 Sep 2019 23:04:10 +0000 Subject: decl.c (grokdeclarator): Use declspecs->locations and declarator->id_loc in a few error messages. /cp 2019-09-16 Paolo Carlini * decl.c (grokdeclarator): Use declspecs->locations and declarator->id_loc in a few error messages. * pt.c (finish_member_template_decl): Use DECL_SOURCE_LOCATION. (push_template_decl_real): Likewise. /testsuite 2019-09-16 Paolo Carlini * g++.dg/ext/int128-6.C: New. * c-c++-common/pr68107.c: Test location(s). * g++.dg/other/large-size-array.C: Likewise. * g++.dg/template/dtor2.C: Likewise. * g++.dg/template/error9.C: Likewise. * g++.dg/tls/diag-2.C: Likewise. * g++.dg/tls/diag-4.C: Likewise. * g++.dg/tls/diag-5.C: Likewise. * g++.old-deja/g++.pt/memtemp71.C: Likewise. From-SVN: r275759 --- gcc/cp/ChangeLog | 7 ++++++ gcc/cp/decl.c | 16 +++++++++----- gcc/cp/pt.c | 9 +++++--- gcc/testsuite/ChangeLog | 12 ++++++++++ gcc/testsuite/c-c++-common/pr68107.c | 32 +++++++++++++-------------- gcc/testsuite/g++.dg/ext/int128-6.C | 5 +++++ gcc/testsuite/g++.dg/other/large-size-array.C | 2 +- gcc/testsuite/g++.dg/template/dtor2.C | 2 +- gcc/testsuite/g++.dg/template/error9.C | 2 +- gcc/testsuite/g++.dg/tls/diag-2.C | 6 ++--- gcc/testsuite/g++.dg/tls/diag-4.C | 6 ++--- gcc/testsuite/g++.dg/tls/diag-5.C | 2 +- gcc/testsuite/g++.old-deja/g++.pt/memtemp71.C | 2 +- 13 files changed, 68 insertions(+), 35 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/int128-6.C (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7bf28f8..efa1686 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2019-09-16 Paolo Carlini + + * decl.c (grokdeclarator): Use declspecs->locations and + declarator->id_loc in a few error messages. + * pt.c (finish_member_template_decl): Use DECL_SOURCE_LOCATION. + (push_template_decl_real): Likewise. + 2019-09-15 Jason Merrill PR c++/30277 - int-width bit-field promotion. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index e0d6732..b753796 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -10948,14 +10948,15 @@ grokdeclarator (const cp_declarator *declarator, { if (! int_n_enabled_p[declspecs->int_n_idx]) { - error ("%<__int%d%> is not supported by this target", - int_n_data[declspecs->int_n_idx].bitsize); + error_at (declspecs->locations[ds_type_spec], + "%<__int%d%> is not supported by this target", + int_n_data[declspecs->int_n_idx].bitsize); explicit_intN = false; } /* Don't pedwarn if the alternate "__intN__" form has been used instead of "__intN". */ else if (!int_n_alt && pedantic && ! in_system_header_at (input_location)) - pedwarn (input_location, OPT_Wpedantic, + pedwarn (declspecs->locations[ds_type_spec], OPT_Wpedantic, "ISO C++ does not support %<__int%d%> for %qs", int_n_data[declspecs->int_n_idx].bitsize, name); } @@ -11330,7 +11331,10 @@ grokdeclarator (const cp_declarator *declarator, && storage_class != sc_static) || typedef_p)) { - error ("multiple storage classes in declaration of %qs", name); + location_t loc + = min_location (declspecs->locations[ds_thread], + declspecs->locations[ds_storage_class]); + error_at (loc, "multiple storage classes in declaration of %qs", name); thread_p = false; } if (decl_context != NORMAL @@ -11489,7 +11493,9 @@ grokdeclarator (const cp_declarator *declarator, type = create_array_type_for_decl (dname, type, declarator->u.array.bounds, declarator->id_loc); - if (!valid_array_size_p (input_location, type, dname)) + if (!valid_array_size_p (dname + ? declarator->id_loc : input_location, + type, dname)) type = error_mark_node; if (declarator->std_attributes) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 9de1b8f..4b3993c 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -298,7 +298,8 @@ finish_member_template_decl (tree decl) return NULL_TREE; } else if (TREE_CODE (decl) == FIELD_DECL) - error ("data member %qD cannot be a member template", decl); + error_at (DECL_SOURCE_LOCATION (decl), + "data member %qD cannot be a member template", decl); else if (DECL_TEMPLATE_INFO (decl)) { if (!DECL_TEMPLATE_SPECIALIZATION (decl)) @@ -310,7 +311,8 @@ finish_member_template_decl (tree decl) return decl; } else - error ("invalid member template declaration %qD", decl); + error_at (DECL_SOURCE_LOCATION (decl), + "invalid member template declaration %qD", decl); return error_mark_node; } @@ -5515,7 +5517,8 @@ push_template_decl_real (tree decl, bool is_friend) /* [temp.mem] A destructor shall not be a member template. */ - error ("destructor %qD declared as member template", decl); + error_at (DECL_SOURCE_LOCATION (decl), + "destructor %qD declared as member template", decl); return error_mark_node; } if (IDENTIFIER_NEWDEL_OP_P (DECL_NAME (decl)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7b9d0d0..f705dc4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,15 @@ +2019-09-16 Paolo Carlini + + * g++.dg/ext/int128-6.C: New. + * c-c++-common/pr68107.c: Test location(s). + * g++.dg/other/large-size-array.C: Likewise. + * g++.dg/template/dtor2.C: Likewise. + * g++.dg/template/error9.C: Likewise. + * g++.dg/tls/diag-2.C: Likewise. + * g++.dg/tls/diag-4.C: Likewise. + * g++.dg/tls/diag-5.C: Likewise. + * g++.old-deja/g++.pt/memtemp71.C: Likewise. + 2019-09-16 Li Jia He Qi Feng diff --git a/gcc/testsuite/c-c++-common/pr68107.c b/gcc/testsuite/c-c++-common/pr68107.c index 6cf19cb..b9f9afe 100644 --- a/gcc/testsuite/c-c++-common/pr68107.c +++ b/gcc/testsuite/c-c++-common/pr68107.c @@ -3,34 +3,34 @@ #define N ((__SIZE_MAX__ / sizeof (int)) / 2 + 1) -typedef int (*T1)[N]; /* { dg-error "exceeds maximum object size" } */ +typedef int (*T1)[N]; /* { dg-error "15:exceeds maximum object size" } */ typedef int (*T2)[N - 1]; -typedef int (*T3)[N][N]; /* { dg-error "exceeds maximum object size" } */ -typedef int (*T4)[N - 1][N - 1]; /* { dg-error "exceeds maximum object size" } */ -typedef int (**T5)[N]; /* { dg-error "exceeds maximum object size" } */ +typedef int (*T3)[N][N]; /* { dg-error "15:exceeds maximum object size" } */ +typedef int (*T4)[N - 1][N - 1]; /* { dg-error "15:exceeds maximum object size" } */ +typedef int (**T5)[N]; /* { dg-error "16:exceeds maximum object size" } */ struct S { - int (*q1)[N]; /* { dg-error "exceeds maximum object size" } */ + int (*q1)[N]; /* { dg-error "9:exceeds maximum object size" } */ int (*q2)[N - 1]; - int (*q3)[N][N]; /* { dg-error "exceeds maximum object size" } */ - int (*q4)[N - 1][N - 1]; /* { dg-error "exceeds maximum object size" } */ - int (**q5)[N]; /* { dg-error "exceeds maximum object size" } */ + int (*q3)[N][N]; /* { dg-error "9:exceeds maximum object size" } */ + int (*q4)[N - 1][N - 1]; /* { dg-error "9:exceeds maximum object size" } */ + int (**q5)[N]; /* { dg-error "10:exceeds maximum object size" } */ }; -void fn1 (int (*p1)[N]); /* { dg-error "exceeds maximum object size" } */ +void fn1 (int (*p1)[N]); /* { dg-error "17:exceeds maximum object size" } */ void fn2 (int (*p1)[N - 1]); -void fn3 (int (*p3)[N][N]); /* { dg-error "exceeds maximum object size" } */ -void fn4 (int (*p4)[N - 1][N - 1]); /* { dg-error "exceeds maximum object size" } */ -void fn5 (int (**p5)[N]); /* { dg-error "exceeds maximum object size" } */ +void fn3 (int (*p3)[N][N]); /* { dg-error "17:exceeds maximum object size" } */ +void fn4 (int (*p4)[N - 1][N - 1]); /* { dg-error "17:exceeds maximum object size" } */ +void fn5 (int (**p5)[N]); /* { dg-error "18:exceeds maximum object size" } */ void fn (void) { - int (*n1)[N]; /* { dg-error "exceeds maximum object size" } */ + int (*n1)[N]; /* { dg-error "9:exceeds maximum object size" } */ int (*n2)[N - 1]; - int (*n3)[N][N]; /* { dg-error "exceeds maximum object size" } */ - int (*n4)[N - 1][N - 1]; /* { dg-error "exceeds maximum object size" } */ - int (**n5)[N]; /* { dg-error "exceeds maximum object size" } */ + int (*n3)[N][N]; /* { dg-error "9:exceeds maximum object size" } */ + int (*n4)[N - 1][N - 1]; /* { dg-error "9:exceeds maximum object size" } */ + int (**n5)[N]; /* { dg-error "10:exceeds maximum object size" } */ sizeof (int (*)[N]); /* { dg-error "exceeds maximum object size" } */ sizeof (int [N]); /* { dg-error "exceeds maximum object size" } */ diff --git a/gcc/testsuite/g++.dg/ext/int128-6.C b/gcc/testsuite/g++.dg/ext/int128-6.C new file mode 100644 index 0000000..a475b01 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/int128-6.C @@ -0,0 +1,5 @@ +// { dg-do compile { target int128 } } + +__int128 i __attribute__((unused)); // { dg-error "1:ISO C\\+\\+ does not support" } + +unsigned __int128 ui __attribute__((unused)); // { dg-error "10:ISO C\\+\\+ does not support" } diff --git a/gcc/testsuite/g++.dg/other/large-size-array.C b/gcc/testsuite/g++.dg/other/large-size-array.C index 631e3a8..15a33f9 100644 --- a/gcc/testsuite/g++.dg/other/large-size-array.C +++ b/gcc/testsuite/g++.dg/other/large-size-array.C @@ -20,7 +20,7 @@ sub (int *a) int main (void) { - int a[DIM][DIM]; /* { dg-error "exceeds maximum object size" } */ + int a[DIM][DIM]; /* { dg-error "7:exceeds maximum object size" } */ return sub (&a[0][0]); /* { dg-error "declared" } */ } diff --git a/gcc/testsuite/g++.dg/template/dtor2.C b/gcc/testsuite/g++.dg/template/dtor2.C index 04bea9c..d8b6b4f 100644 --- a/gcc/testsuite/g++.dg/template/dtor2.C +++ b/gcc/testsuite/g++.dg/template/dtor2.C @@ -1,7 +1,7 @@ struct Foo { template - ~Foo() {} // { dg-error "" } + ~Foo() {} // { dg-error "5:destructor .Foo::~Foo\\\(\\\)." } }; int main() diff --git a/gcc/testsuite/g++.dg/template/error9.C b/gcc/testsuite/g++.dg/template/error9.C index 60f550a..65e3d91 100644 --- a/gcc/testsuite/g++.dg/template/error9.C +++ b/gcc/testsuite/g++.dg/template/error9.C @@ -3,5 +3,5 @@ struct Foo { template - ~Foo(); // { dg-error "" } + ~Foo(); // { dg-error "5:destructor .Foo::~Foo\\\(\\\)." } }; diff --git a/gcc/testsuite/g++.dg/tls/diag-2.C b/gcc/testsuite/g++.dg/tls/diag-2.C index c247a97..3e8f422 100644 --- a/gcc/testsuite/g++.dg/tls/diag-2.C +++ b/gcc/testsuite/g++.dg/tls/diag-2.C @@ -4,14 +4,14 @@ __thread extern int g1; /* { dg-error "'__thread' before 'extern'" } */ __thread static int g2; /* { dg-error "'__thread' before 'static'" } */ __thread __thread int g3; /* { dg-error "duplicate '__thread'" } */ -typedef __thread int g4; /* { dg-error "multiple storage classes" } */ +typedef __thread int g4; /* { dg-error "9:multiple storage classes" } */ void foo() { __thread int l1; /* { dg-error "3:function-scope .l1. implicitly auto and declared '__thread'" } */ - auto __thread int l2; /* { dg-error "multiple storage classes|data types" } */ + auto __thread int l2; /* { dg-error "3:multiple storage classes|data types" } */ __thread extern int l3; /* { dg-error "'__thread' before 'extern'" } */ - register __thread int l4; /* { dg-error "multiple storage classes" } */ + register __thread int l4; /* { dg-error "3:multiple storage classes" } */ } /* { dg-error "ISO C\\+\\+17 does not allow 'register' storage class specifier" "" { target c++17 } .-1 } */ __thread void f1 (); /* { dg-error "1:storage class .__thread. invalid for function" } */ diff --git a/gcc/testsuite/g++.dg/tls/diag-4.C b/gcc/testsuite/g++.dg/tls/diag-4.C index 56f185e..24e28c9 100644 --- a/gcc/testsuite/g++.dg/tls/diag-4.C +++ b/gcc/testsuite/g++.dg/tls/diag-4.C @@ -1,10 +1,10 @@ /* Invalid __thread specifiers. */ /* { dg-require-effective-target tls } */ -__thread typedef int g4; /* { dg-error "multiple storage classes" } */ +__thread typedef int g4; /* { dg-error "1:multiple storage classes" } */ void foo() { - __thread auto int l2; /* { dg-error "multiple storage classes|data types" } */ - __thread register int l4; /* { dg-error "multiple storage classes" } */ + __thread auto int l2; /* { dg-error "3:multiple storage classes|data types" } */ + __thread register int l4; /* { dg-error "3:multiple storage classes" } */ } /* { dg-error "ISO C\\+\\+17 does not allow 'register' storage class specifier" "" { target c++17 } .-1 } */ diff --git a/gcc/testsuite/g++.dg/tls/diag-5.C b/gcc/testsuite/g++.dg/tls/diag-5.C index ca92b30..f94e68c 100644 --- a/gcc/testsuite/g++.dg/tls/diag-5.C +++ b/gcc/testsuite/g++.dg/tls/diag-5.C @@ -2,4 +2,4 @@ // Invalid __thread specifiers. // { dg-require-effective-target tls } -struct A { __thread register int i; }; // { dg-error "multiple storage classes|storage class specified" } +struct A { __thread register int i; }; // { dg-error "12:multiple storage classes|storage class specified" } diff --git a/gcc/testsuite/g++.old-deja/g++.pt/memtemp71.C b/gcc/testsuite/g++.old-deja/g++.pt/memtemp71.C index 74149a0..91cfac0 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/memtemp71.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/memtemp71.C @@ -2,5 +2,5 @@ class A { - templateT epsilon; // { dg-error "" } invalid member template + templateT epsilon; // { dg-error "22:data member .epsilon. cannot be a member template" } }; -- cgit v1.1 From 8ba9c127cdbc661a4f10fcf977c560e61edc5ca4 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Tue, 17 Sep 2019 00:16:39 +0000 Subject: Daily bump. From-SVN: r275763 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 2a82338..2dd6da8 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20190916 +20190917 -- cgit v1.1 From 38b06e7a19d4002697117965d0bfce7ee77e1d40 Mon Sep 17 00:00:00 2001 From: Bob Duff Date: Tue, 17 Sep 2019 07:59:11 +0000 Subject: [Ada] Refine conditions for calling Copy_Bitfield Avoid calling Copy_Bitfield if there are volatile or independent components that might be read or written. The test is conservative. 2019-09-17 Bob Duff gcc/ada/ * exp_ch5.adb (Expand_Assign_Array_Loop_Or_Bitfield): Add tests for potential volatile or independent components. * libgnat/s-bituti.adb (Copy_Small_Bitfield, Copy_Large_Bitfield): Move declarations to more appropriate place. From-SVN: r275768 --- gcc/ada/ChangeLog | 8 ++++++++ gcc/ada/exp_ch5.adb | 29 +++++++++++++++++++++------- gcc/ada/libgnat/s-bituti.adb | 46 ++++++++++++++++++++++---------------------- 3 files changed, 53 insertions(+), 30 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index e3e274a..ecc67e5 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,11 @@ +2019-09-17 Bob Duff + + * exp_ch5.adb (Expand_Assign_Array_Loop_Or_Bitfield): Add tests + for potential volatile or independent components. + * libgnat/s-bituti.adb (Copy_Small_Bitfield, + Copy_Large_Bitfield): Move declarations to more appropriate + place. + 2019-09-13 Maciej W. Rozycki * make.adb (Scan_Make_Arg): Also accept `--sysroot=' for the diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb index ba0b793..6ef3fb2 100644 --- a/gcc/ada/exp_ch5.adb +++ b/gcc/ada/exp_ch5.adb @@ -1451,20 +1451,35 @@ package body Exp_Ch5 is begin -- Determine whether Copy_Bitfield is appropriate (will work, and will -- be more efficient than component-by-component copy). Copy_Bitfield - -- doesn't work for reversed storage orders. It is efficient only for - -- slices of bit-packed arrays. - - -- Note that Expand_Assign_Array_Bitfield is disabled for now - - if False -- ??? + -- doesn't work for reversed storage orders. It is efficient for slices + -- of bit-packed arrays. Copy_Bitfield can read and write bits that are + -- not part of the objects being copied, so we don't want to use it if + -- there are volatile or independent components. If the Prefix of the + -- slice is a selected component (etc, see below), then it might be a + -- component of an object with some other volatile or independent + -- components, so we disable the optimization in that case as well. + -- We could complicate this code by actually looking for such volatile + -- and independent components. + + -- Note that Expand_Assign_Array_Bitfield is disabled for now. + + if False and then -- ??? + RTE_Available (RE_Copy_Bitfield) and then Is_Bit_Packed_Array (L_Type) and then Is_Bit_Packed_Array (R_Type) - and then RTE_Available (RE_Copy_Bitfield) and then not Reverse_Storage_Order (L_Type) and then not Reverse_Storage_Order (R_Type) and then Ndim = 1 and then not Rev and then Slices + and then not Has_Volatile_Component (L_Type) + and then not Has_Volatile_Component (R_Type) + and then not Has_Independent_Components (L_Type) + and then not Has_Independent_Components (R_Type) + and then not Nkind_In (Prefix (Name (N)), + N_Selected_Component, + N_Indexed_Component, + N_Slice) then return Expand_Assign_Array_Bitfield (N, Larray, Rarray, L_Type, R_Type, Rev); diff --git a/gcc/ada/libgnat/s-bituti.adb b/gcc/ada/libgnat/s-bituti.adb index 78e391b..511dc57 100644 --- a/gcc/ada/libgnat/s-bituti.adb +++ b/gcc/ada/libgnat/s-bituti.adb @@ -71,6 +71,29 @@ package body System.Bitfield_Utils is -- set to Src_Value. Src_Value must have high order bits (Size and -- above) zero. The result is returned as the function result. + procedure Copy_Small_Bitfield + (Src_Address : Address; + Src_Offset : Bit_Offset; + Dest_Address : Address; + Dest_Offset : Bit_Offset; + Size : Small_Size); + -- Copy_Bitfield in the case where Size <= Val'Size. + -- The Address values must be aligned as for Val and Val_2. + -- This works for overlapping bit fields. + + procedure Copy_Large_Bitfield + (Src_Address : Address; + Src_Offset : Bit_Offset; + Dest_Address : Address; + Dest_Offset : Bit_Offset; + Size : Bit_Size); + -- Copy_Bitfield in the case where Size > Val'Size. + -- The Address values must be aligned as for Val and Val_2. + -- This works for overlapping bit fields only if the source + -- bit address is greater than or equal to the destination + -- bit address, because it copies forward (from lower to higher + -- bit addresses). + function Get_Bitfield (Src : Val_2; Src_Offset : Bit_Offset; Size : Small_Size) return Val @@ -120,29 +143,6 @@ package body System.Bitfield_Utils is Src_Offset : Bit_Offset; Dest_Address : Address; Dest_Offset : Bit_Offset; - Size : Small_Size); - -- Copy_Bitfield in the case where Size <= Val'Size. - -- The Address values must be aligned as for Val and Val_2. - -- This works for overlapping bit fields. - - procedure Copy_Large_Bitfield - (Src_Address : Address; - Src_Offset : Bit_Offset; - Dest_Address : Address; - Dest_Offset : Bit_Offset; - Size : Bit_Size); - -- Copy_Bitfield in the case where Size > Val'Size. - -- The Address values must be aligned as for Val and Val_2. - -- This works for overlapping bit fields only if the source - -- bit address is greater than or equal to the destination - -- bit address, because it copies forward (from lower to higher - -- bit addresses). - - procedure Copy_Small_Bitfield - (Src_Address : Address; - Src_Offset : Bit_Offset; - Dest_Address : Address; - Dest_Offset : Bit_Offset; Size : Small_Size) is Src : constant Val_2 with Import, Address => Src_Address; -- cgit v1.1 From 37915d022449d21fe7bfa7db640a15e77cd3352e Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Tue, 17 Sep 2019 07:59:16 +0000 Subject: [Ada] Fix wrong value of 'Size for slices of bit-packed arrays This fixes a long-standing issue in the compiler which would return a wrong value for the Size attribute applied to slices of bit-packed arrays whose size is not a multiple of the storage unit. The problem is that the computation was done in the code generator after the bit-packed array had been internally rewritten into an array of bytes, so the Size was always rounded up to the next byte. The computation is now rewritten into the product of the Length and Compnent_Size attribute of the slices before being sent to the code generator. 2019-09-17 Eric Botcazou gcc/ada/ * exp_attr.adb (Expand_Size_Attribute): Chain the special cases on the back-end path and rewrite the attribute appled to slices of bit-packed arrays into the product of the Length and the Compoent_Size attributes of the slices. * exp_ch5.adb (Expand_Assign_Array_Bitfield): Use Size attribute directly to compute the bitfield's size. gcc/testsuite/ * gnat.dg/pack25.adb: New testcase. From-SVN: r275769 --- gcc/ada/ChangeLog | 9 +++++++++ gcc/ada/exp_attr.adb | 24 +++++++++++++++++++++--- gcc/ada/exp_ch5.adb | 18 +++++------------- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gnat.dg/pack25.adb | 21 +++++++++++++++++++++ 5 files changed, 60 insertions(+), 16 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/pack25.adb (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index ecc67e5..ee7945c 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,12 @@ +2019-09-17 Eric Botcazou + + * exp_attr.adb (Expand_Size_Attribute): Chain the special cases + on the back-end path and rewrite the attribute appled to slices + of bit-packed arrays into the product of the Length and the + Compoent_Size attributes of the slices. + * exp_ch5.adb (Expand_Assign_Array_Bitfield): Use Size attribute + directly to compute the bitfield's size. + 2019-09-17 Bob Duff * exp_ch5.adb (Expand_Assign_Array_Loop_Or_Bitfield): Add tests diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb index c7d1647..c5ff9b5 100644 --- a/gcc/ada/exp_attr.adb +++ b/gcc/ada/exp_attr.adb @@ -7600,18 +7600,36 @@ package body Exp_Attr is New_Occurrence_Of (Get_Actual_Subtype (Pref), Loc), Attribute_Name => Name_Size)); Analyze_And_Resolve (N, Typ); - end if; - -- If Size applies to a dereference of an access to unconstrained + -- If Size is applied to a dereference of an access to unconstrained -- packed array, the back end needs to see its unconstrained nominal -- type, but also a hint to the actual constrained type. - if Nkind (Pref) = N_Explicit_Dereference + elsif Nkind (Pref) = N_Explicit_Dereference and then Is_Array_Type (Ptyp) and then not Is_Constrained (Ptyp) and then Is_Packed (Ptyp) then Set_Actual_Designated_Subtype (Pref, Get_Actual_Subtype (Pref)); + + -- If Size was applied to a slice of a bit-packed array, we rewrite + -- it into the product of Length and Component_Size. We need to do so + -- because bit-packed arrays are represented internally as arrays of + -- System.Unsigned_Types.Packed_Byte for code generation purposes so + -- the size is always rounded up in the back end. + + elsif Nkind (Original_Node (Pref)) = N_Slice + and then Is_Bit_Packed_Array (Ptyp) + then + Rewrite (N, + Make_Op_Multiply (Loc, + Make_Attribute_Reference (Loc, + Prefix => Duplicate_Subexpr (Pref, True), + Attribute_Name => Name_Length), + Make_Attribute_Reference (Loc, + Prefix => Duplicate_Subexpr (Pref, True), + Attribute_Name => Name_Component_Size))); + Analyze_And_Resolve (N, Typ); end if; return; diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb index 6ef3fb2..7c2d632 100644 --- a/gcc/ada/exp_ch5.adb +++ b/gcc/ada/exp_ch5.adb @@ -1408,23 +1408,15 @@ package body Exp_Ch5 is Expressions => New_List (New_Copy_Tree (Right_Lo))), Attribute_Name => Name_Bit); - -- Compute the Size of the bitfield. ???We can't use Size here, because - -- it doesn't work properly for slices of packed arrays, so we compute - -- the L'Size as L'Length*L'Component_Size. - -- + -- Compute the Size of the bitfield + -- Note that the length check has already been done, so we can use the -- size of either L or R. Size : constant Node_Id := - Make_Op_Multiply (Loc, - Make_Attribute_Reference (Loc, - Prefix => - Duplicate_Subexpr (Name (N), True), - Attribute_Name => Name_Length), - Make_Attribute_Reference (Loc, - Prefix => - Duplicate_Subexpr (Name (N), True), - Attribute_Name => Name_Component_Size)); + Make_Attribute_Reference (Loc, + Prefix => Duplicate_Subexpr (Name (N), True), + Attribute_Name => Name_Size); begin return Make_Procedure_Call_Statement (Loc, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f705dc4..b701f9e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-09-17 Eric Botcazou + + * gnat.dg/pack25.adb: New testcase. + 2019-09-16 Paolo Carlini * g++.dg/ext/int128-6.C: New. diff --git a/gcc/testsuite/gnat.dg/pack25.adb b/gcc/testsuite/gnat.dg/pack25.adb new file mode 100644 index 0000000..d1ac22a --- /dev/null +++ b/gcc/testsuite/gnat.dg/pack25.adb @@ -0,0 +1,21 @@ +-- { dg-do run } +procedure Pack25 is + + type Bit is ('0', '1'); + type Bit_Array is array (Natural range <>) of Bit; + pragma Pack (Bit_Array); + + procedure Test (Bits : Bit_Array; Size : Natural) is + begin + if Bits (0 .. Size - 1)'Size /= Size then + raise Program_Error; + end if; + end; + + A : Bit_Array (0 .. 127) := (others => '1'); + +begin + for X in A'First .. A'Last + 1 loop + Test (A, X); + end loop; +end; \ No newline at end of file -- cgit v1.1 From 38c4e50d8c738553de6f5e7a5fee3b55728ea457 Mon Sep 17 00:00:00 2001 From: Dmitriy Anisimkov Date: Tue, 17 Sep 2019 07:59:23 +0000 Subject: [Ada] Support for local unix sockets in GNAT.Sockets API Sock_Addr_Type has Family_Unix variant now. This variant can be created with function Unix_Local_Addr call. And this variant is working in GNAT.Socket routines where it is appropriate. 2019-09-17 Dmitriy Anisimkov gcc/ada/ * gsocket.h: Include sys/un.h. * s-oscons-tmplt.c (AF_UNIX): New constant generation. (SIZEOF_sockaddr_un): Idem. * libgnat/g-socket.ads (Family_Type): New value Family_Unix added. (Family_Inet_4_6): New subtype only for network families. (Sock_Addr_Type): Add Unbounded_String field for Family_Unix variant. (Unix_Socket_Address): Create Sock_Addr_Type from socket pathname. (Network_Socket_Address): Create Sock_Addr_Type from Inet_Addr_Type and Port_Type parameters. * libgnat/g-socket.adb: Support local unix address in socket routines. (Get_Address_Info): Disable warning about Result may be referenced before it has a value. Remove duplicated code to exit from Look_For_Supported. * libgnat/g-sothco.ads (Unix_Name_Length): New constant defining maximum number of characters in local socket address path. (Sockaddr): Add variant for Family_Unix address family. Move Sin_Port and Sin_Family to Family_Inet section. Add Sin6_Port and Sin6_Family to Family_Inet6 section. (Set_Address): Add out parameter Length to return valuable Sockaddr data length. (Get_Address): Add input parameter Length to set valuable Sockaddr data length. * libgnat/g-sothco.adb: Support local unix address in socket routines. From-SVN: r275770 --- gcc/ada/ChangeLog | 31 +++++++++++ gcc/ada/gsocket.h | 1 + gcc/ada/libgnat/g-socket.adb | 121 +++++++++++++++++++++++++++---------------- gcc/ada/libgnat/g-socket.ads | 45 ++++++++++------ gcc/ada/libgnat/g-sothco.adb | 72 +++++++++++++++++++++---- gcc/ada/libgnat/g-sothco.ads | 55 ++++++++++++-------- gcc/ada/s-oscons-tmplt.c | 18 +++++++ 7 files changed, 252 insertions(+), 91 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index ee7945c..f5b72a0 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,34 @@ +2019-09-17 Dmitriy Anisimkov + + * gsocket.h: Include sys/un.h. + * s-oscons-tmplt.c (AF_UNIX): New constant generation. + (SIZEOF_sockaddr_un): Idem. + * libgnat/g-socket.ads (Family_Type): New value Family_Unix + added. + (Family_Inet_4_6): New subtype only for network families. + (Sock_Addr_Type): Add Unbounded_String field for Family_Unix + variant. + (Unix_Socket_Address): Create Sock_Addr_Type from socket + pathname. + (Network_Socket_Address): Create Sock_Addr_Type from + Inet_Addr_Type and Port_Type parameters. + * libgnat/g-socket.adb: Support local unix address in socket + routines. + (Get_Address_Info): Disable warning about Result may be + referenced before it has a value. Remove duplicated code to exit + from Look_For_Supported. + * libgnat/g-sothco.ads (Unix_Name_Length): New constant defining + maximum number of characters in local socket address path. + (Sockaddr): Add variant for Family_Unix address family. Move + Sin_Port and Sin_Family to Family_Inet section. Add Sin6_Port + and Sin6_Family to Family_Inet6 section. + (Set_Address): Add out parameter Length to return valuable + Sockaddr data length. + (Get_Address): Add input parameter Length to set valuable + Sockaddr data length. + * libgnat/g-sothco.adb: Support local unix address in socket + routines. + 2019-09-17 Eric Botcazou * exp_attr.adb (Expand_Size_Attribute): Chain the special cases diff --git a/gcc/ada/gsocket.h b/gcc/ada/gsocket.h index c44e134..91a06b8 100644 --- a/gcc/ada/gsocket.h +++ b/gcc/ada/gsocket.h @@ -208,6 +208,7 @@ */ #if !(defined (VMS) || defined (__MINGW32__)) #include +#include #include #include #include diff --git a/gcc/ada/libgnat/g-socket.adb b/gcc/ada/libgnat/g-socket.adb index 51817ea..8565ccf 100644 --- a/gcc/ada/libgnat/g-socket.adb +++ b/gcc/ada/libgnat/g-socket.adb @@ -128,14 +128,12 @@ package body GNAT.Sockets is Socket_Error_Id : constant Exception_Id := Socket_Error'Identity; Host_Error_Id : constant Exception_Id := Host_Error'Identity; - type In_Addr_Union (Family : Family_Type) is record + type In_Addr_Union (Family : Family_Inet_4_6) is record case Family is when Family_Inet => In4 : In_Addr; when Family_Inet6 => In6 : In6_Addr; - when Family_Unspec => - null; end case; end record with Unchecked_Union; @@ -291,7 +289,7 @@ package body GNAT.Sockets is -- or the null selector. function Create_Address - (Family : Family_Type; Bytes : Inet_Addr_Bytes) return Inet_Addr_Type + (Family : Family_Inet_4_6; Bytes : Inet_Addr_Bytes) return Inet_Addr_Type with Inline; -- Creates address from family and Inet_Addr_Bytes array. @@ -354,7 +352,7 @@ package body GNAT.Sockets is end if; Socket := Socket_Type (Res); - Address := Get_Address (Sin); + Address := Get_Address (Sin, Len); end Accept_Socket; ------------------- @@ -465,12 +463,12 @@ package body GNAT.Sockets is is Res : C.int; Sin : aliased Sockaddr; + Len : C.int; begin - Set_Address (Sin'Unchecked_Access, Address); + Set_Address (Sin'Unchecked_Access, Address, Len); - Res := C_Bind - (C.int (Socket), Sin'Address, C.int (Lengths (Address.Family))); + Res := C_Bind (C.int (Socket), Sin'Address, Len); if Res = Failure then Raise_Socket_Error (Socket_Errno); @@ -670,11 +668,11 @@ package body GNAT.Sockets is Server : Sock_Addr_Type) return C.int is Sin : aliased Sockaddr; + Len : C.int; begin - Set_Address (Sin'Unchecked_Access, Server); + Set_Address (Sin'Unchecked_Access, Server, Len); - return C_Connect - (C.int (Socket), Sin'Address, C.int (Lengths (Server.Family))); + return C_Connect (C.int (Socket), Sin'Address, Len); end Connect_Socket; procedure Connect_Socket @@ -1039,10 +1037,17 @@ package body GNAT.Sockets is for J in Result'Range loop Look_For_Supported : loop if Iter = null then + pragma Warnings + (Off, "may be referenced before it has a value"); + return Result (1 .. J - 1); + + pragma Warnings + (On, "may be referenced before it has a value"); end if; - Result (J).Addr := Get_Address (Iter.ai_addr.all); + Result (J).Addr := + Get_Address (Iter.ai_addr.all, C.int (Iter.ai_addrlen)); if Result (J).Addr.Family = Family_Unspec then Unsupported; @@ -1071,10 +1076,6 @@ package body GNAT.Sockets is end if; Iter := Iter.ai_next; - - if Iter = null then - return Result (1 .. J - 1); - end if; end loop Look_For_Supported; Iter := Iter.ai_next; @@ -1149,15 +1150,16 @@ package body GNAT.Sockets is Numeric_Host : Boolean := False; Numeric_Serv : Boolean := False) return Host_Service is - SA : aliased Sockaddr; - H : aliased C.char_array := (1 .. SOSC.NI_MAXHOST => C.nul); - S : aliased C.char_array := (1 .. SOSC.NI_MAXSERV => C.nul); - RC : C.int; + SA : aliased Sockaddr; + H : aliased C.char_array := (1 .. SOSC.NI_MAXHOST => C.nul); + S : aliased C.char_array := (1 .. SOSC.NI_MAXSERV => C.nul); + RC : C.int; + Len : C.int; begin - Set_Address (SA'Unchecked_Access, Addr); + Set_Address (SA'Unchecked_Access, Addr, Len); RC := C_Getnameinfo - (SA'Unchecked_Access, socklen_t (Lengths (Addr.Family)), + (SA'Unchecked_Access, socklen_t (Len), H'Unchecked_Access, H'Length, S'Unchecked_Access, S'Length, (if Numeric_Host then SOSC.NI_NUMERICHOST else 0) + @@ -1197,9 +1199,6 @@ package body GNAT.Sockets is HA.In4 := To_In_Addr (Address); when Family_Inet6 => HA.In6 := To_In6_Addr (Address); - when Family_Unspec => - return (0, 0, (1, " "), (1 .. 0 => (1, " ")), - (1 .. 0 => No_Inet_Addr)); end case; Netdb_Lock; @@ -1208,8 +1207,7 @@ package body GNAT.Sockets is (HA'Address, (case Address.Family is when Family_Inet => HA.In4'Size, - when Family_Inet6 => HA.In6'Size, - when Family_Unspec => 0) / 8, + when Family_Inet6 => HA.In6'Size) / 8, Families (Address.Family), Res'Access, Buf'Address, Buflen, Err'Access) /= 0 then @@ -1280,7 +1278,7 @@ package body GNAT.Sockets is Raise_Socket_Error (Socket_Errno); end if; - return Get_Address (Sin); + return Get_Address (Sin, Len); end Get_Peer_Name; ------------------------- @@ -1364,7 +1362,7 @@ package body GNAT.Sockets is return No_Sock_Addr; end if; - return Get_Address (Sin); + return Get_Address (Sin, Len); end Get_Socket_Name; ----------------------- @@ -1572,9 +1570,8 @@ package body GNAT.Sockets is Size : constant socklen_t := (case Value.Family is when Family_Inet => 4 * Value.Sin_V4'Length, - when Family_Inet6 => 6 * 5 + 4 * 4, + when Family_Inet6 => 6 * 5 + 4 * 4); -- 1234:1234:1234:1234:1234:1234:123.123.123.123 - when Family_Unspec => 0); Dst : aliased C.char_array := (1 .. C.size_t (Size) => C.nul); Ia : aliased In_Addr_Union (Value.Family); begin @@ -1583,8 +1580,6 @@ package body GNAT.Sockets is Ia.In6 := To_In6_Addr (Value); when Family_Inet => Ia.In4 := To_In_Addr (Value); - when Family_Unspec => - return ""; end case; if Inet_Ntop @@ -1602,11 +1597,30 @@ package body GNAT.Sockets is ----------- function Image (Value : Sock_Addr_Type) return String is - Port : constant String := Value.Port'Img; function Ipv6_Brackets (S : String) return String is (if Value.Family = Family_Inet6 then "[" & S & "]" else S); begin - return Ipv6_Brackets (Image (Value.Addr)) & ':' & Port (2 .. Port'Last); + case Value.Family is + when Family_Unix => + if ASU.Length (Value.Name) > 0 + and then ASU.Element (Value.Name, 1) = ASCII.NUL + then + return '@' & ASU.Slice (Value.Name, 2, ASU.Length (Value.Name)); + else + return ASU.To_String (Value.Name); + end if; + + when Family_Inet_4_6 => + declare + Port : constant String := Value.Port'Img; + begin + return Ipv6_Brackets (Image (Value.Addr)) & ':' + & Port (2 .. Port'Last); + end; + + when Family_Unspec => + return ""; + end case; end Image; ----------- @@ -1924,6 +1938,19 @@ package body GNAT.Sockets is end if; end Netdb_Unlock; + ---------------------------- + -- Network_Socket_Address -- + ---------------------------- + + function Network_Socket_Address + (Addr : Inet_Addr_Type; Port : Port_Type) return Sock_Addr_Type is + begin + return Result : Sock_Addr_Type (Addr.Family) do + Result.Addr := Addr; + Result.Port := Port; + end return; + end Network_Socket_Address; + -------------------------------- -- Normalize_Empty_Socket_Set -- -------------------------------- @@ -2139,7 +2166,7 @@ package body GNAT.Sockets is Last := Last_Index (First => Item'First, Count => size_t (Res)); - From := Get_Address (Sin); + From := Get_Address (Sin, Len); end Receive_Socket; -------------------- @@ -2404,9 +2431,8 @@ package body GNAT.Sockets is begin if To /= null then - Set_Address (Sin'Unchecked_Access, To.all); + Set_Address (Sin'Unchecked_Access, To.all, Len); C_To := Sin'Address; - Len := C.int (Thin_Common.Lengths (To.Family)); else C_To := System.Null_Address; @@ -3055,12 +3081,11 @@ package body GNAT.Sockets is -------------------- function Create_Address - (Family : Family_Type; Bytes : Inet_Addr_Bytes) return Inet_Addr_Type + (Family : Family_Inet_4_6; Bytes : Inet_Addr_Bytes) return Inet_Addr_Type is (case Family is when Family_Inet => (Family_Inet, Bytes), - when Family_Inet6 => (Family_Inet6, Bytes), - when Family_Unspec => (Family => Family_Unspec)); + when Family_Inet6 => (Family_Inet6, Bytes)); --------------- -- Get_Bytes -- @@ -3069,15 +3094,14 @@ package body GNAT.Sockets is function Get_Bytes (Addr : Inet_Addr_Type) return Inet_Addr_Bytes is (case Addr.Family is when Family_Inet => Addr.Sin_V4, - when Family_Inet6 => Addr.Sin_V6, - when Family_Unspec => (1 .. 0 => 0)); + when Family_Inet6 => Addr.Sin_V6); ---------- -- Mask -- ---------- function Mask - (Family : Family_Type; + (Family : Family_Inet_4_6; Length : Natural; Host : Boolean := False) return Inet_Addr_Type is @@ -3109,6 +3133,15 @@ package body GNAT.Sockets is end; end Mask; + ------------------------- + -- Unix_Socket_Address -- + ------------------------- + + function Unix_Socket_Address (Addr : String) return Sock_Addr_Type is + begin + return Sock_Addr_Type'(Family_Unix, ASU.To_Unbounded_String (Addr)); + end Unix_Socket_Address; + ----------- -- "and" -- ----------- diff --git a/gcc/ada/libgnat/g-socket.ads b/gcc/ada/libgnat/g-socket.ads index acd72f1..38d1078 100644 --- a/gcc/ada/libgnat/g-socket.ads +++ b/gcc/ada/libgnat/g-socket.ads @@ -45,6 +45,7 @@ with Ada.Exceptions; with Ada.Streams; +with Ada.Strings.Unbounded; with Ada.Unchecked_Deallocation; with Interfaces.C; @@ -469,12 +470,14 @@ package GNAT.Sockets is -- Return a file descriptor to be used by external subprograms. This is -- useful for C functions that are not yet interfaced in this package. - type Family_Type is (Family_Inet, Family_Inet6, Family_Unspec); + type Family_Type is (Family_Inet, Family_Inet6, Family_Unix, Family_Unspec); -- Address family (or protocol family) identifies the communication domain -- and groups protocols with similar address formats. -- The order of the enumeration elements should not be changed unilaterally -- because the IPv6_TCP_Preferred routine rely on it. + subtype Family_Inet_4_6 is Family_Type range Family_Inet .. Family_Inet6; + type Mode_Type is (Socket_Stream, Socket_Datagram, Socket_Raw); -- Stream sockets provide connection-oriented byte streams. Datagram -- sockets support unreliable connectionless message-based communication. @@ -502,8 +505,8 @@ package GNAT.Sockets is type Inet_Addr_Comp_Type is mod 2 ** 8; -- Octet for Internet address - Inet_Addr_Bytes_Length : constant array (Family_Type) of Natural := - (Family_Inet => 4, Family_Inet6 => 16, Family_Unspec => 0); + Inet_Addr_Bytes_Length : constant array (Family_Inet_4_6) of Natural := + (Family_Inet => 4, Family_Inet6 => 16); type Inet_Addr_Bytes is array (Natural range <>) of Inet_Addr_Comp_Type; @@ -515,7 +518,7 @@ package GNAT.Sockets is subtype Inet_Addr_VN_Type is Inet_Addr_Bytes; -- For backwards compatibility - type Inet_Addr_Type (Family : Family_Type := Family_Inet) is record + type Inet_Addr_Type (Family : Family_Inet_4_6 := Family_Inet) is record case Family is when Family_Inet => Sin_V4 : Inet_Addr_V4_Type := (others => 0); @@ -523,9 +526,6 @@ package GNAT.Sockets is when Family_Inet6 => Sin_V6 : Inet_Addr_V6_Type := (others => 0); - when Family_Unspec => - null; - end case; end record; @@ -541,10 +541,6 @@ package GNAT.Sockets is No_Inet_Addr : constant Inet_Addr_Type; -- Uninitialized inet address - Unspecified_Addr : constant Inet_Addr_Type; - -- Unspecified address. Unlike of No_Inet_Addr the constraint is - -- Family_Unspec for this constant. - Broadcast_Inet_Addr : constant Inet_Addr_Type; -- Broadcast destination address in the current network @@ -581,7 +577,7 @@ package GNAT.Sockets is -- Functions to handle masks and prefixes function Mask - (Family : Family_Type; + (Family : Family_Inet_4_6; Length : Natural; Host : Boolean := False) return Inet_Addr_Type; -- Return an address mask of the given family with the given prefix length. @@ -596,8 +592,15 @@ package GNAT.Sockets is -- same address family). type Sock_Addr_Type (Family : Family_Type := Family_Inet) is record - Addr : Inet_Addr_Type (Family); - Port : Port_Type; + case Family is + when Family_Unix => + Name : Ada.Strings.Unbounded.Unbounded_String; + when Family_Inet_4_6 => + Addr : Inet_Addr_Type (Family); + Port : Port_Type; + when Family_Unspec => + null; + end case; end record; pragma No_Component_Reordering (Sock_Addr_Type); -- Socket addresses fully define a socket connection with protocol family, @@ -619,12 +622,20 @@ package GNAT.Sockets is -- 8 hextets in hexadecimal format separated by colons. function Image (Value : Sock_Addr_Type) return String; - -- Return inet address image and port image separated by a colon + -- Return socket address image. Network socket address image will be with + -- a port image separated by a colon. function Inet_Addr (Image : String) return Inet_Addr_Type; -- Convert address image from numbers-dots-and-colons notation into an -- inet address. + function Unix_Socket_Address (Addr : String) return Sock_Addr_Type; + -- Convert unix local socket name to Sock_Addr_Type + + function Network_Socket_Address + (Addr : Inet_Addr_Type; Port : Port_Type) return Sock_Addr_Type; + -- Create network socket address + -- Host entries provide complete information on a given host: the official -- name, an array of alternative names or aliases and array of network -- addresses. @@ -1439,6 +1450,8 @@ package GNAT.Sockets is private + package ASU renames Ada.Strings.Unbounded; + type Socket_Type is new Integer; No_Socket : constant Socket_Type := -1; @@ -1493,8 +1506,6 @@ private (Family_Inet6, (others => 0)); No_Inet_Addr : constant Inet_Addr_Type := (Family_Inet, (others => 0)); - Unspecified_Addr : constant Inet_Addr_Type := - (Family => Family_Unspec); Broadcast_Inet_Addr : constant Inet_Addr_Type := (Family_Inet, (others => 255)); Loopback_Inet_Addr : constant Inet_Addr_Type := diff --git a/gcc/ada/libgnat/g-sothco.adb b/gcc/ada/libgnat/g-sothco.adb index eb15ac2..9794d8b 100644 --- a/gcc/ada/libgnat/g-sothco.adb +++ b/gcc/ada/libgnat/g-sothco.adb @@ -37,18 +37,59 @@ package body GNAT.Sockets.Thin_Common is procedure Set_Address (Sin : Sockaddr_Access; - Address : Sock_Addr_Type) + Address : Sock_Addr_Type; + Length : out C.int) is + use type C.char; + + function Network_Port return C.unsigned_short is + (Short_To_Network (C.unsigned_short (Address.Port))) with Inline; + begin Set_Family (Sin.Sin_Family, Address.Family); - Sin.Sin_Port := Short_To_Network (C.unsigned_short (Address.Port)); + + Length := C.int (Lengths (Address.Family)); case Address.Family is when Family_Inet => + Sin.Sin_Port := Network_Port; Sin.Sin_Addr := To_In_Addr (Address.Addr); + when Family_Inet6 => + Sin.Sin6_Port := Network_Port; Sin.Sin6_Addr := To_In6_Addr (Address.Addr); Sin.Sin6_Scope_Id := 0; + + when Family_Unix => + declare + use type C.size_t; + Name_Len : constant C.size_t := + C.size_t (ASU.Length (Address.Name)); + begin + Length := Sockaddr_Length_And_Family'Size / System.Storage_Unit + + C.int (Name_Len); + + if Name_Len > Sin.Sun_Path'Length then + raise Constraint_Error with + "Too big address length for UNIX local communication"; + end if; + + if Name_Len = 0 then + Sin.Sun_Path (1) := C.nul; + + else + Sin.Sun_Path (1 .. Name_Len) := + C.To_C (ASU.To_String (Address.Name), Append_Nul => False); + + if Sin.Sun_Path (1) /= C.nul + and then Name_Len < Sin.Sun_Path'Length + then + Sin.Sun_Path (Name_Len + 1) := C.nul; + Length := Length + 1; + end if; + end if; + end; + when Family_Unspec => null; end case; @@ -58,26 +99,39 @@ package body GNAT.Sockets.Thin_Common is -- Get_Address -- ----------------- - function Get_Address (Sin : Sockaddr) return Sock_Addr_Type is - use type C.unsigned_short; + function Get_Address + (Sin : Sockaddr; Length : C.int) return Sock_Addr_Type + is + use type C.unsigned_short, C.size_t, C.char, SOSC.OS_Type; Family : constant C.unsigned_short := (if SOSC.Has_Sockaddr_Len = 0 then Sin.Sin_Family.Short_Family else C.unsigned_short (Sin.Sin_Family.Char_Family)); - AF_INET6_Defined : constant Boolean := SOSC.AF_INET6 > 0; Result : Sock_Addr_Type - (if AF_INET6_Defined and then SOSC.AF_INET6 = Family then Family_Inet6 + (if SOSC.AF_INET6 > 0 and then SOSC.AF_INET6 = Family then Family_Inet6 + elsif SOSC.AF_UNIX > 0 and then SOSC.AF_UNIX = Family then Family_Unix elsif SOSC.AF_INET = Family then Family_Inet else Family_Unspec); begin - Result.Port := Port_Type (Network_To_Short (Sin.Sin_Port)); - case Result.Family is when Family_Inet => + Result.Port := Port_Type (Network_To_Short (Sin.Sin_Port)); To_Inet_Addr (Sin.Sin_Addr, Result.Addr); when Family_Inet6 => + Result.Port := Port_Type (Network_To_Short (Sin.Sin6_Port)); To_Inet_Addr (Sin.Sin6_Addr, Result.Addr); + when Family_Unix => + if Length > Sin.Sin_Family'Size / System.Storage_Unit then + Result.Name := ASU.To_Unbounded_String + (C.To_Ada + (Sin.Sun_Path + (1 .. C.size_t (Length) + - Sin.Sin_Family'Size / System.Storage_Unit), + Trim_Nul => Sin.Sun_Path (1) /= C.nul + or else SOSC.Target_OS = SOSC.Windows)); + end if; + when Family_Unspec => - Result.Addr := (Family => Family_Unspec); + null; end case; return Result; diff --git a/gcc/ada/libgnat/g-sothco.ads b/gcc/ada/libgnat/g-sothco.ads index c62161d..a68019c 100644 --- a/gcc/ada/libgnat/g-sothco.ads +++ b/gcc/ada/libgnat/g-sothco.ads @@ -75,11 +75,13 @@ package GNAT.Sockets.Thin_Common is Families : constant array (Family_Type) of C.int := (Family_Unspec => SOSC.AF_UNSPEC, + Family_Unix => SOSC.AF_UNIX, Family_Inet => SOSC.AF_INET, Family_Inet6 => SOSC.AF_INET6); Lengths : constant array (Family_Type) of C.unsigned_char := (Family_Unspec => 0, + Family_Unix => SOSC.SIZEOF_sockaddr_un, Family_Inet => SOSC.SIZEOF_sockaddr_in, Family_Inet6 => SOSC.SIZEOF_sockaddr_in6); @@ -106,9 +108,7 @@ package GNAT.Sockets.Thin_Common is when False => Short_Family : C.unsigned_short; end case; - end record; - pragma Unchecked_Union (Sockaddr_Length_And_Family); - pragma Convention (C, Sockaddr_Length_And_Family); + end record with Unchecked_Union, Convention => C; procedure Set_Family (Length_And_Family : out Sockaddr_Length_And_Family; @@ -122,9 +122,7 @@ package GNAT.Sockets.Thin_Common is type In_Addr is record S_B1, S_B2, S_B3, S_B4 : C.unsigned_char; - end record; - for In_Addr'Alignment use C.int'Alignment; - pragma Convention (C, In_Addr); + end record with Convention => C, Alignment => C.int'Alignment; -- IPv4 address, represented as a network-order C.int. Note that the -- underlying operating system may assume that values of this type have -- C.int alignment, so we need to provide a suitable alignment clause here. @@ -138,9 +136,10 @@ package GNAT.Sockets.Thin_Common is Result : out Inet_Addr_Type); -- Conversion functions - type In6_Addr is array (1 .. 16) of C.unsigned_char; - for In6_Addr'Alignment use C.int'Alignment; - pragma Convention (C, In6_Addr); + type In6_Addr is array (1 .. 16) of C.unsigned_char with Convention => C; + + Unix_Name_Length : constant := 108; + -- Maximum length for local unix socket name function To_In6_Addr (Addr : Inet_Addr_Type) return In6_Addr; procedure To_Inet_Addr @@ -149,14 +148,14 @@ package GNAT.Sockets.Thin_Common is -- Conversion functions type Sockaddr (Family : Family_Type := Family_Inet) is record - Sin_Family : Sockaddr_Length_And_Family; - -- Address family (and address length on some platforms) - - Sin_Port : C.unsigned_short; - -- Port in network byte order - case Family is when Family_Inet => + Sin_Family : Sockaddr_Length_And_Family; + -- Address family (and address length on some platforms) + + Sin_Port : C.unsigned_short; + -- Port in network byte order + Sin_Addr : In_Addr := (others => 0); -- IPv4 address @@ -165,16 +164,28 @@ package GNAT.Sockets.Thin_Common is -- -- Note that some platforms require that all unused (reserved) bytes -- in addresses be initialized to 0 (e.g. VxWorks). + when Family_Inet6 => + Sin6_Family : Sockaddr_Length_And_Family; + -- Address family (and address length on some platforms) + + Sin6_Port : C.unsigned_short; + -- Port in network byte order + Sin6_FlowInfo : Interfaces.Unsigned_32 := 0; Sin6_Addr : In6_Addr := (others => 0); Sin6_Scope_Id : Interfaces.Unsigned_32 := 0; + + when Family_Unix => + Sun_Family : Sockaddr_Length_And_Family; + -- Address family (and address length on some platforms) + + Sun_Path : C.char_array (1 .. Unix_Name_Length); + when Family_Unspec => null; end case; - end record; - pragma Unchecked_Union (Sockaddr); - pragma Convention (C, Sockaddr); + end record with Convention => C, Unchecked_Union; -- Internet socket address type Sockaddr_Access is access all Sockaddr; @@ -183,13 +194,15 @@ package GNAT.Sockets.Thin_Common is procedure Set_Address (Sin : Sockaddr_Access; - Address : Sock_Addr_Type); + Address : Sock_Addr_Type; + Length : out C.int); -- Initialise all necessary fields in Sin from Address. -- Set appropriate Family, Port, and either Sin.Sin_Addr or Sin.Sin6_Addr -- depend on family. + -- Set the Length out parameter to the valuable Sockaddr data length. - function Get_Address (Sin : Sockaddr) return Sock_Addr_Type; - -- Get Sock_Addr_Type from Sockaddr + function Get_Address (Sin : Sockaddr; Length : C.int) return Sock_Addr_Type; + -- Get Sock_Addr_Type from Sockaddr and its valuable data Length ------------------ -- Host entries -- diff --git a/gcc/ada/s-oscons-tmplt.c b/gcc/ada/s-oscons-tmplt.c index 655d68a..4c3ecc6 100644 --- a/gcc/ada/s-oscons-tmplt.c +++ b/gcc/ada/s-oscons-tmplt.c @@ -1053,6 +1053,11 @@ CND(AF_INET, "IPv4 address family") #endif CND(AF_INET6, "IPv6 address family") +#ifndef AF_UNIX +# define AF_UNIX -1 +#endif +CND(AF_UNIX, "Local unix family") + #ifndef AF_UNSPEC # define AF_UNSPEC -1 #else @@ -1701,6 +1706,19 @@ CND(SIZEOF_sockaddr_in, "struct sockaddr_in") #endif CND(SIZEOF_sockaddr_in6, "struct sockaddr_in6") +/** + ** The sockaddr_un structure is not defined in MINGW C headers + ** but Windows supports it from build 17063. + **/ +#if defined(__MINGW32__) +struct sockaddr_un { + ADDRESS_FAMILY sun_family; /* AF_UNIX */ + char sun_path[108]; /* Pathname */ +}; +#endif +#define SIZEOF_sockaddr_un (sizeof (struct sockaddr_un)) +CND(SIZEOF_sockaddr_un, "struct sockaddr_un") + #define SIZEOF_fd_set (sizeof (fd_set)) CND(SIZEOF_fd_set, "fd_set") CND(FD_SETSIZE, "Max fd value") -- cgit v1.1 From 2d319f3acef1e80d7bb288a6b5d1ae76f2968b45 Mon Sep 17 00:00:00 2001 From: Bob Duff Date: Tue, 17 Sep 2019 07:59:29 +0000 Subject: [Ada] Avoid touching potentially nonexistent memory ...in cases where the Val_2 might cross a page boundary, and the second page is now known to exist. Copy_Bitfield is still disabled in the compiler: no test possible. 2019-09-17 Bob Duff gcc/ada/ * libgnat/s-bituti.adb (Get_Val_2, Set_Val_2): Use new routines for getting and setting a Val_2, avoiding touching the second half when that half might not exist. * exp_ch5.adb (Expand_Assign_Array_Loop_Or_Bitfield): Correct tests for potential volatile or independent components. In particular, do not call Prefix unless we know it's a slice. From-SVN: r275771 --- gcc/ada/ChangeLog | 9 +++ gcc/ada/exp_ch5.adb | 29 +++++--- gcc/ada/libgnat/s-bituti.adb | 159 +++++++++++++++++++++++++++++++++++-------- 3 files changed, 158 insertions(+), 39 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index f5b72a0..7220566 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,12 @@ +2019-09-17 Bob Duff + + * libgnat/s-bituti.adb (Get_Val_2, Set_Val_2): Use new routines + for getting and setting a Val_2, avoiding touching the second + half when that half might not exist. + * exp_ch5.adb (Expand_Assign_Array_Loop_Or_Bitfield): Correct + tests for potential volatile or independent components. In + particular, do not call Prefix unless we know it's a slice. + 2019-09-17 Dmitriy Anisimkov * gsocket.h: Include sys/un.h. diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb index 7c2d632..76e97fc 100644 --- a/gcc/ada/exp_ch5.adb +++ b/gcc/ada/exp_ch5.adb @@ -1440,6 +1440,20 @@ package body Exp_Ch5 is is Slices : constant Boolean := Nkind (Name (N)) = N_Slice or else Nkind (Expression (N)) = N_Slice; + L_Prefix_Comp : constant Boolean := + -- True if the left-hand side is a slice of a component or slice + Nkind (Name (N)) = N_Slice + and then Nkind_In (Prefix (Name (N)), + N_Selected_Component, + N_Indexed_Component, + N_Slice); + R_Prefix_Comp : constant Boolean := + -- Likewise for the right-hand side + Nkind (Expression (N)) = N_Slice + and then Nkind_In (Prefix (Expression (N)), + N_Selected_Component, + N_Indexed_Component, + N_Slice); begin -- Determine whether Copy_Bitfield is appropriate (will work, and will -- be more efficient than component-by-component copy). Copy_Bitfield @@ -1447,11 +1461,10 @@ package body Exp_Ch5 is -- of bit-packed arrays. Copy_Bitfield can read and write bits that are -- not part of the objects being copied, so we don't want to use it if -- there are volatile or independent components. If the Prefix of the - -- slice is a selected component (etc, see below), then it might be a - -- component of an object with some other volatile or independent - -- components, so we disable the optimization in that case as well. - -- We could complicate this code by actually looking for such volatile - -- and independent components. + -- slice is a component or slice, then it might be a part of an object + -- with some other volatile or independent components, so we disable the + -- optimization in that case as well. We could complicate this code by + -- actually looking for such volatile and independent components. -- Note that Expand_Assign_Array_Bitfield is disabled for now. @@ -1468,10 +1481,8 @@ package body Exp_Ch5 is and then not Has_Volatile_Component (R_Type) and then not Has_Independent_Components (L_Type) and then not Has_Independent_Components (R_Type) - and then not Nkind_In (Prefix (Name (N)), - N_Selected_Component, - N_Indexed_Component, - N_Slice) + and then not L_Prefix_Comp + and then not R_Prefix_Comp then return Expand_Assign_Array_Bitfield (N, Larray, Rarray, L_Type, R_Type, Rev); diff --git a/gcc/ada/libgnat/s-bituti.adb b/gcc/ada/libgnat/s-bituti.adb index 511dc57..b425e9f 100644 --- a/gcc/ada/libgnat/s-bituti.adb +++ b/gcc/ada/libgnat/s-bituti.adb @@ -43,6 +43,31 @@ package body System.Bitfield_Utils is Val_Bytes : constant Address := Address (Val'Size / Storage_Unit); + -- A Val_2 can cross a memory page boundary (e.g. an 8-byte Val_2 that + -- starts 4 bytes before the end of a page). If the bit field also + -- crosses that boundary, then the second page is known to exist, and we + -- can safely load or store the Val_2. On the other hand, if the bit + -- field is entirely within the first half of the Val_2, then it is + -- possible (albeit highly unlikely) that the second page does not + -- exist, so we must load or store only the first half of the Val_2. + -- Get_Val_2 and Set_Val_2 take care of all this. + + function Get_Val_2 + (Src_Address : Address; + Src_Offset : Bit_Offset; + Size : Small_Size) + return Val_2; + -- Get the Val_2, taking care to only load the first half when + -- necessary. + + procedure Set_Val_2 + (Dest_Address : Address; + Dest_Offset : Bit_Offset; + V : Val_2; + Size : Small_Size); + -- Set the Val_2, taking care to only store the first half when + -- necessary. + -- Get_Bitfield and Set_Bitfield are helper functions that get/set small -- bit fields -- the value fits in Val, and the bit field is placed -- starting at some offset within the first half of a Val_2. @@ -56,11 +81,6 @@ package body System.Bitfield_Utils is -- Returns the bit field in Src starting at Src_Offset, of the given -- Size. If Size < Small_Size'Last, then high order bits are zero. - function Get_Full_Bitfield - (Src : Val_2; Src_Offset : Bit_Offset) return Val; - -- Same as Get_Bitfield, except the Size is hardwired to the maximum - -- allowed. - function Set_Bitfield (Src_Value : Val; Dest : Val_2; @@ -71,6 +91,13 @@ package body System.Bitfield_Utils is -- set to Src_Value. Src_Value must have high order bits (Size and -- above) zero. The result is returned as the function result. + procedure Set_Bitfield + (Src_Value : Val; + Dest_Address : Address; + Dest_Offset : Bit_Offset; + Size : Small_Size); + -- This version takes the bit address and size of the destination. + procedure Copy_Small_Bitfield (Src_Address : Address; Src_Offset : Bit_Offset; @@ -94,6 +121,69 @@ package body System.Bitfield_Utils is -- bit address, because it copies forward (from lower to higher -- bit addresses). + function Get_Val_2 + (Src_Address : Address; + Src_Offset : Bit_Offset; + Size : Small_Size) + return Val_2 is + begin + pragma Assert (Src_Address mod Val'Alignment = 0); + + -- Bit field fits in first half; fetch just one Val. On little + -- endian, we want that in the low half, but on big endian, we + -- want it in the high half. + + if Src_Offset + Size <= Val'Size then + declare + Result : aliased constant Val with + Import, Address => Src_Address; + begin + return (case Endian is + when Little => Val_2 (Result), + when Big => Shift_Left (Val_2 (Result), Val'Size)); + end; + + -- Bit field crosses into the second half, so it's safe to fetch the + -- whole Val_2. + + else + declare + Result : aliased constant Val_2 with + Import, Address => Src_Address; + begin + return Result; + end; + end if; + end Get_Val_2; + + procedure Set_Val_2 + (Dest_Address : Address; + Dest_Offset : Bit_Offset; + V : Val_2; + Size : Small_Size) is + begin + pragma Assert (Dest_Address mod Val'Alignment = 0); + + -- Comments in Get_Val_2 apply, except we're storing instead of + -- fetching. + + if Dest_Offset + Size <= Val'Size then + declare + Dest : aliased Val with Import, Address => Dest_Address; + begin + Dest := (case Endian is + when Little => Val'Mod (V), + when Big => Val (Shift_Right (V, Val'Size))); + end; + else + declare + Dest : aliased Val_2 with Import, Address => Dest_Address; + begin + Dest := V; + end; + end if; + end Set_Val_2; + function Get_Bitfield (Src : Val_2; Src_Offset : Bit_Offset; Size : Small_Size) return Val @@ -110,12 +200,6 @@ package body System.Bitfield_Utils is return Val (Temp2); end Get_Bitfield; - function Get_Full_Bitfield - (Src : Val_2; Src_Offset : Bit_Offset) return Val is - begin - return Get_Bitfield (Src, Src_Offset, Size => Val'Size); - end Get_Full_Bitfield; - function Set_Bitfield (Src_Value : Val; Dest : Val_2; @@ -138,6 +222,20 @@ package body System.Bitfield_Utils is return Result; end Set_Bitfield; + procedure Set_Bitfield + (Src_Value : Val; + Dest_Address : Address; + Dest_Offset : Bit_Offset; + Size : Small_Size) + is + Old_Dest : constant Val_2 := + Get_Val_2 (Dest_Address, Dest_Offset, Size); + New_Dest : constant Val_2 := + Set_Bitfield (Src_Value, Old_Dest, Dest_Offset, Size); + begin + Set_Val_2 (Dest_Address, Dest_Offset, New_Dest, Size); + end Set_Bitfield; + procedure Copy_Small_Bitfield (Src_Address : Address; Src_Offset : Bit_Offset; @@ -145,11 +243,10 @@ package body System.Bitfield_Utils is Dest_Offset : Bit_Offset; Size : Small_Size) is - Src : constant Val_2 with Import, Address => Src_Address; + Src : constant Val_2 := Get_Val_2 (Src_Address, Src_Offset, Size); V : constant Val := Get_Bitfield (Src, Src_Offset, Size); - Dest : Val_2 with Import, Address => Dest_Address; begin - Dest := Set_Bitfield (V, Dest, Dest_Offset, Size); + Set_Bitfield (V, Dest_Address, Dest_Offset, Size); end Copy_Small_Bitfield; -- Copy_Large_Bitfield does the main work. Copying aligned Vals is more @@ -168,9 +265,9 @@ package body System.Bitfield_Utils is -- Address). Get_Bitfield and Set_Bitfield are used here. -- -- Step 2: - -- Loop, copying Vals. Get_Full_Bitfield is used to fetch a - -- Val-sized bit field, but Set_Bitfield is not needed -- we can set - -- the aligned Val with an array indexing. + -- Loop, copying Vals. Get_Bitfield is used to fetch a Val-sized + -- bit field, but Set_Bitfield is not needed -- we can set the + -- aligned Val with an array indexing. -- -- Step 3: -- Copy remaining smaller-than-Val bits, if any @@ -216,13 +313,13 @@ package body System.Bitfield_Utils is declare Initial_Size : constant Small_Size := Val'Size - D_Off; - Initial_Val_2 : constant Val_2 with Import, Address => S_Addr; + Initial_Val_2 : constant Val_2 := + Get_Val_2 (S_Addr, S_Off, Initial_Size); Initial_Val : constant Val := Get_Bitfield (Initial_Val_2, S_Off, Initial_Size); - Initial_Dest : Val_2 with Import, Address => D_Addr; begin - Initial_Dest := Set_Bitfield - (Initial_Val, Initial_Dest, D_Off, Initial_Size); + Set_Bitfield + (Initial_Val, D_Addr, D_Off, Initial_Size); Sz := Sz - Initial_Size; declare @@ -253,8 +350,10 @@ package body System.Bitfield_Utils is pragma Assert (Dest_Comp in Val); pragma Warnings (On); pragma Assert (Dest_Comp'Valid); - Src_V_2 : constant Val_2 with Import, Address => S_Addr; - Full_V : constant Val := Get_Full_Bitfield (Src_V_2, S_Off); + Src_V_2 : constant Val_2 := + Get_Val_2 (S_Addr, S_Off, Val'Size); + Full_V : constant Val := + Get_Bitfield (Src_V_2, S_Off, Val'Size); begin Dest_Comp := Full_V; S_Addr := S_Addr + Val_Bytes; @@ -262,18 +361,18 @@ package body System.Bitfield_Utils is end; end loop; - if Sz mod Val'Size /= 0 then + Sz := Sz mod Val'Size; + if Sz /= 0 then -- Step 3: declare - Final_Val_2 : constant Val_2 with Import, Address => S_Addr; + Final_Val_2 : constant Val_2 := + Get_Val_2 (S_Addr, S_Off, Sz); Final_Val : constant Val := - Get_Bitfield (Final_Val_2, S_Off, Sz mod Val'Size); - Final_Dest : Val_2 with Import, - Address => D_Addr + Dest_Arr'Length * Val_Bytes; + Get_Bitfield (Final_Val_2, S_Off, Sz); begin - Final_Dest := Set_Bitfield - (Final_Val, Final_Dest, 0, Sz mod Val'Size); + Set_Bitfield + (Final_Val, D_Addr + Dest_Arr'Length * Val_Bytes, 0, Sz); end; end if; end; -- cgit v1.1 From 1ed19d98def3515e5b2fb9e68be34da4a78a7fdb Mon Sep 17 00:00:00 2001 From: Javier Miranda Date: Tue, 17 Sep 2019 07:59:33 +0000 Subject: [Ada] Adding assertions on extra formals for BIP function calls This patch adds assertions to ensure that the frontend passes to the backend the right number of extra parameters required for build in place function calls. No functional change. 2019-09-17 Javier Miranda gcc/ada/ * exp_ch6.ads (Needs_BIP_Task_Actuals): New subprogram. * exp_ch6.adb (Add_Task_Actuals_To_Build_In_Place_Call): Code cleanup. (Check_Number_Of_Actuals): New subprogram. (Make_Build_In_Place_Call_In_Allocator): Adding assertion. (Make_Build_In_Place_Call_In_Anonymous_Context): Adding assertion. (Make_Build_In_Place_Call_In_Assignment): Adding assertion. (Make_Build_In_Place_Call_In_Object_Declaration): Code cleanup plus assertion addition. (Needs_BIP_Task_Actuals): New subprogram. * sem_ch6.adb (Create_Extra_Formals): Rely on Needs_BIP_Task_Actuals() to check if the master of the tasks to be created, and the caller's activation chain formals are needed. From-SVN: r275772 --- gcc/ada/ChangeLog | 18 +++++++++++++++++ gcc/ada/exp_ch6.adb | 58 +++++++++++++++++++++++++++++++++++++++++++++++++---- gcc/ada/exp_ch6.ads | 3 +++ gcc/ada/sem_ch6.adb | 3 +-- 4 files changed, 76 insertions(+), 6 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 7220566..c44a16d 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,21 @@ +2019-09-17 Javier Miranda + + * exp_ch6.ads (Needs_BIP_Task_Actuals): New subprogram. + * exp_ch6.adb (Add_Task_Actuals_To_Build_In_Place_Call): Code + cleanup. + (Check_Number_Of_Actuals): New subprogram. + (Make_Build_In_Place_Call_In_Allocator): Adding assertion. + (Make_Build_In_Place_Call_In_Anonymous_Context): Adding + assertion. + (Make_Build_In_Place_Call_In_Assignment): Adding assertion. + (Make_Build_In_Place_Call_In_Object_Declaration): Code cleanup + plus assertion addition. + (Needs_BIP_Task_Actuals): New subprogram. + * sem_ch6.adb (Create_Extra_Formals): Rely on + Needs_BIP_Task_Actuals() to check if the master of the tasks to + be created, and the caller's activation chain formals are + needed. + 2019-09-17 Bob Duff * libgnat/s-bituti.adb (Get_Val_2, Set_Val_2): Use new routines diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb index e3109c2..3277b46 100644 --- a/gcc/ada/exp_ch6.adb +++ b/gcc/ada/exp_ch6.adb @@ -146,6 +146,12 @@ package body Exp_Ch6 is -- access discriminants do not require secondary stack use. Note we must -- always use the secondary stack for dispatching-on-result calls. + function Check_Number_Of_Actuals + (Subp_Call : Node_Id; + Subp_Id : Entity_Id) return Boolean; + -- Given a subprogram call to the given subprogram return True if the + -- number of actual parameters (including extra actuals) is correct. + procedure Check_Overriding_Operation (Subp : Entity_Id); -- Subp is a dispatching operation. Check whether it may override an -- inherited private operation, in which case its DT entry is that of @@ -543,8 +549,6 @@ package body Exp_Ch6 is Chain : Node_Id := Empty) is Loc : constant Source_Ptr := Sloc (Function_Call); - Result_Subt : constant Entity_Id := - Available_View (Etype (Function_Id)); Actual : Node_Id; Chain_Actual : Node_Id; Chain_Formal : Node_Id; @@ -553,7 +557,7 @@ package body Exp_Ch6 is begin -- No such extra parameters are needed if there are no tasks - if not Has_Task (Result_Subt) then + if not Needs_BIP_Task_Actuals (Function_Id) then return; end if; @@ -869,6 +873,33 @@ package body Exp_Ch6 is or else not Requires_Transient_Scope (Underlying_Type (Result_Subt)); end Caller_Known_Size; + ----------------------------- + -- Check_Number_Of_Actuals -- + ----------------------------- + + function Check_Number_Of_Actuals + (Subp_Call : Node_Id; + Subp_Id : Entity_Id) return Boolean + is + Formal : Entity_Id; + Actual : Node_Id; + + begin + pragma Assert (Nkind_In (Subp_Call, N_Entry_Call_Statement, + N_Function_Call, + N_Procedure_Call_Statement)); + + Formal := First_Formal_With_Extras (Subp_Id); + Actual := First_Actual (Subp_Call); + + while Present (Formal) and then Present (Actual) loop + Next_Formal_With_Extras (Formal); + Next_Actual (Actual); + end loop; + + return No (Formal) and then No (Actual); + end Check_Number_Of_Actuals; + -------------------------------- -- Check_Overriding_Operation -- -------------------------------- @@ -8335,6 +8366,7 @@ package body Exp_Ch6 is Rewrite (Allocator, New_Occurrence_Of (Return_Obj_Access, Loc)); Analyze_And_Resolve (Allocator, Acc_Type); + pragma Assert (Check_Number_Of_Actuals (Func_Call, Function_Id)); end Make_Build_In_Place_Call_In_Allocator; --------------------------------------------------- @@ -8456,6 +8488,8 @@ package body Exp_Ch6 is Add_Access_Actual_To_Build_In_Place_Call (Func_Call, Function_Id, New_Occurrence_Of (Return_Obj_Id, Loc)); + pragma Assert (Check_Number_Of_Actuals (Func_Call, Function_Id)); + -- When the result subtype is unconstrained, the function must allocate -- the return object in the secondary stack, so appropriate implicit -- parameters are added to the call to indicate that. A transient @@ -8479,6 +8513,8 @@ package body Exp_Ch6 is Add_Access_Actual_To_Build_In_Place_Call (Func_Call, Function_Id, Empty); + + pragma Assert (Check_Number_Of_Actuals (Func_Call, Function_Id)); end if; end Make_Build_In_Place_Call_In_Anonymous_Context; @@ -8584,6 +8620,7 @@ package body Exp_Ch6 is Insert_After_And_Analyze (Ptr_Typ_Decl, Obj_Decl); Rewrite (Assign, Make_Null_Statement (Loc)); + pragma Assert (Check_Number_Of_Actuals (Func_Call, Func_Id)); end Make_Build_In_Place_Call_In_Assignment; ---------------------------------------------------- @@ -8908,7 +8945,7 @@ package body Exp_Ch6 is Master_Exp => Fmaster_Actual); if Nkind (Parent (Obj_Decl)) = N_Extended_Return_Statement - and then Has_Task (Result_Subt) + and then Needs_BIP_Task_Actuals (Function_Id) then -- Here we're passing along the master that was passed in to this -- function. @@ -9025,6 +9062,8 @@ package body Exp_Ch6 is Replace_Renaming_Declaration_Id (Obj_Decl, Original_Node (Obj_Decl)); end if; + + pragma Assert (Check_Number_Of_Actuals (Func_Call, Function_Id)); end Make_Build_In_Place_Call_In_Object_Declaration; ------------------------------------------------- @@ -9296,6 +9335,17 @@ package body Exp_Ch6 is Analyze_And_Resolve (Allocator, Acc_Type); end Make_CPP_Constructor_Call_In_Allocator; + ---------------------------- + -- Needs_BIP_Task_Actuals -- + ---------------------------- + + function Needs_BIP_Task_Actuals (Func_Id : Entity_Id) return Boolean is + pragma Assert (Is_Build_In_Place_Function (Func_Id)); + Func_Typ : constant Entity_Id := Underlying_Type (Etype (Func_Id)); + begin + return Has_Task (Func_Typ); + end Needs_BIP_Task_Actuals; + ----------------------------------- -- Needs_BIP_Finalization_Master -- ----------------------------------- diff --git a/gcc/ada/exp_ch6.ads b/gcc/ada/exp_ch6.ads index bf453d9..13ccb2a 100644 --- a/gcc/ada/exp_ch6.ads +++ b/gcc/ada/exp_ch6.ads @@ -244,6 +244,9 @@ package Exp_Ch6 is -- functions with tagged result types, since they can be invoked via -- dispatching calls, and descendant types may require finalization. + function Needs_BIP_Task_Actuals (Func_Id : Entity_Id) return Boolean; + -- Return True if the function returns an object of a type that has tasks. + function Needs_Result_Accessibility_Level (Func_Id : Entity_Id) return Boolean; -- Ada 2012 (AI05-0234): Return True if the function needs an implicit diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb index fb50ec7..ddb12ec 100644 --- a/gcc/ada/sem_ch6.adb +++ b/gcc/ada/sem_ch6.adb @@ -8080,7 +8080,6 @@ package body Sem_Ch6 is if Is_Build_In_Place_Function (E) then declare Result_Subt : constant Entity_Id := Etype (E); - Full_Subt : constant Entity_Id := Available_View (Result_Subt); Formal_Typ : Entity_Id; Subp_Decl : Node_Id; Discard : Entity_Id; @@ -8130,7 +8129,7 @@ package body Sem_Ch6 is -- master of the tasks to be created, and the caller's activation -- chain. - if Has_Task (Full_Subt) then + if Needs_BIP_Task_Actuals (E) then Discard := Add_Extra_Formal (E, RTE (RE_Master_Id), -- cgit v1.1 From 5387a3f55fedbab8c99677c4021061fbaabec3ff Mon Sep 17 00:00:00 2001 From: Arnaud Charlet Date: Tue, 17 Sep 2019 07:59:38 +0000 Subject: [Ada] Refine change for bit-packed slices We use Long_Long_Integer'Size / 2 instead of 4 * 8 to support specifying a target configuration file where the largest integer is 32 bits instead of 64. 2019-09-17 Arnaud Charlet gcc/ada/ * libgnat/s-bitfie.ads (Val_Bits, Val_Bytes): Define from Long_Long_Integer'Size. From-SVN: r275773 --- gcc/ada/ChangeLog | 5 +++++ gcc/ada/libgnat/s-bitfie.ads | 8 ++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index c44a16d..9193e6f 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,8 @@ +2019-09-17 Arnaud Charlet + + * libgnat/s-bitfie.ads (Val_Bits, Val_Bytes): Define from + Long_Long_Integer'Size. + 2019-09-17 Javier Miranda * exp_ch6.ads (Needs_BIP_Task_Actuals): New subprogram. diff --git a/gcc/ada/libgnat/s-bitfie.ads b/gcc/ada/libgnat/s-bitfie.ads index 1b62b9d..a90605b 100644 --- a/gcc/ada/libgnat/s-bitfie.ads +++ b/gcc/ada/libgnat/s-bitfie.ads @@ -36,9 +36,13 @@ package System.Bitfields is -- Instances of the generic package in System.Bitfield_Utils. So far -- we have just one, which defaults to the natural endianness of the -- machine. We might someday want to support Scalar_Storage_Order. + -- Note: we use Long_Long_Integer'Size / 2 instead of 32 to support + -- specifying a target configuration file where the largest integer is + -- 32 bits instead of 64. + + Val_Bits : constant := Long_Long_Integer'Size / 2; + Val_Bytes : constant := Val_Bits / System.Storage_Unit; - Val_Bytes : constant := 4; - Val_Bits : constant := Val_Bytes * System.Storage_Unit; type Val_2 is mod 2**(Val_Bits * 2) with Alignment => Val_Bytes; pragma Provide_Shift_Operators (Val_2); type Val is mod 2**Val_Bits with Alignment => Val_Bytes; -- cgit v1.1 From 5c7cf10a6334dc9fcd8ad2362e809920ee205ff5 Mon Sep 17 00:00:00 2001 From: Arnaud Charlet Date: Tue, 17 Sep 2019 07:59:43 +0000 Subject: [Ada] PR ada/91268 Do not redefine macros This should fix PR ada/91268 by only defining macros if not already done. 2019-09-17 Arnaud Charlet gcc/ada/ * adaint.c (_REENTRANT, _THREAD_SAFE): Only define if needed. From-SVN: r275774 --- gcc/ada/ChangeLog | 4 ++++ gcc/ada/adaint.c | 6 ++++++ 2 files changed, 10 insertions(+) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 9193e6f..5b1a7d1 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,5 +1,9 @@ 2019-09-17 Arnaud Charlet + * adaint.c (_REENTRANT, _THREAD_SAFE): Only define if needed. + +2019-09-17 Arnaud Charlet + * libgnat/s-bitfie.ads (Val_Bits, Val_Bytes): Define from Long_Long_Integer'Size. diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c index 7290f7a..c76e9ad 100644 --- a/gcc/ada/adaint.c +++ b/gcc/ada/adaint.c @@ -35,8 +35,14 @@ library calls directly. This file contains all other routines. */ /* Ensure access to errno is thread safe. */ + +#ifndef _REENTRANT #define _REENTRANT +#endif + +#ifndef _THREAD_SAFE #define _THREAD_SAFE +#endif /* Use 64 bit Large File API */ #if defined (__QNX__) -- cgit v1.1 From 92167df3c9735de9c62bab9bf325618febc75198 Mon Sep 17 00:00:00 2001 From: Piotr Trojanek Date: Tue, 17 Sep 2019 07:59:48 +0000 Subject: [Ada] Ignore missing ALI files in GNATprove mode This change only affects GNATprove backend, where it avoids spurious errors on missing ALI files for units indirectly withed from the current unit and processed as part of a different .gpr project. No test provided, because only GNATprove is affected. 2019-09-17 Piotr Trojanek gcc/ada/ * ali.ads: Fix casing in comment. * ali-util.ads, ali-util.adb (Read_Withed_ALIs): Remove Ignore_Errors parameter; it was only set to non-default value of True when running in GNATprove_Mode and wrongly reset to False when calling this routine recursively. Now in GNATprove mode we want it to be always True, so in fact it is equivalent to GNATProve_Mode flag itself (which was already used in this routine). From-SVN: r275775 --- gcc/ada/ChangeLog | 11 +++++++++++ gcc/ada/ali-util.adb | 12 ++++-------- gcc/ada/ali-util.ads | 10 ++++------ gcc/ada/ali.ads | 2 +- 4 files changed, 20 insertions(+), 15 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 5b1a7d1..fb1f7f5 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,14 @@ +2019-09-17 Piotr Trojanek + + * ali.ads: Fix casing in comment. + * ali-util.ads, ali-util.adb (Read_Withed_ALIs): Remove + Ignore_Errors parameter; it was only set to non-default value of + True when running in GNATprove_Mode and wrongly reset to False + when calling this routine recursively. Now in GNATprove mode we + want it to be always True, so in fact it is equivalent to + GNATProve_Mode flag itself (which was already used in this + routine). + 2019-09-17 Arnaud Charlet * adaint.c (_REENTRANT, _THREAD_SAFE): Only define if needed. diff --git a/gcc/ada/ali-util.adb b/gcc/ada/ali-util.adb index 0d9a22a..1efad4d 100644 --- a/gcc/ada/ali-util.adb +++ b/gcc/ada/ali-util.adb @@ -215,10 +215,7 @@ package body ALI.Util is -- Read_Withed_ALIs -- ---------------------- - procedure Read_Withed_ALIs - (Id : ALI_Id; - Ignore_Errors : Boolean := False) - is + procedure Read_Withed_ALIs (Id : ALI_Id) is Afile : File_Name_Type; Text : Text_Buffer_Ptr; Idread : ALI_Id; @@ -240,14 +237,14 @@ package body ALI.Util is then Text := Read_Library_Info (Afile); - -- Unless Ignore_Errors is true, return with an error if source + -- Unless in GNATprove mode, return with an error if source -- cannot be found. We used to skip this check when we did not -- compile library generics separately, but we now always do, -- so there is no special case here anymore. if Text = null then - if not Ignore_Errors then + if not GNATprove_Mode then Error_Msg_File_1 := Afile; Error_Msg_File_2 := Withs.Table (W).Sfile; Error_Msg ("{ not found, { must be compiled"); @@ -268,7 +265,7 @@ package body ALI.Util is Free (Text); if ALIs.Table (Idread).Compile_Errors - and then not Ignore_Errors + and then not GNATprove_Mode then Error_Msg_File_1 := Withs.Table (W).Sfile; Error_Msg ("{ had errors, must be fixed, and recompiled"); @@ -279,7 +276,6 @@ package body ALI.Util is elsif ALIs.Table (Idread).No_Object and then not GNATprove_Mode - and then not Ignore_Errors then Error_Msg_File_1 := Withs.Table (W).Sfile; Error_Msg ("{ must be recompiled"); diff --git a/gcc/ada/ali-util.ads b/gcc/ada/ali-util.ads index 3023d00..7b3f9a5 100644 --- a/gcc/ada/ali-util.ads +++ b/gcc/ada/ali-util.ads @@ -107,15 +107,13 @@ package ALI.Util is -- Subprograms for Manipulating ALI Information -- -------------------------------------------------- - procedure Read_Withed_ALIs - (Id : ALI_Id; - Ignore_Errors : Boolean := False); + procedure Read_Withed_ALIs (Id : ALI_Id); -- Process an ALI file which has been read and scanned by looping through -- all withed units in the ALI file, checking if they have been processed. -- Each unit that has not yet been processed will be read, scanned, and - -- processed recursively. If Ignore_Errors is True, then failure to read an - -- ALI file is not reported as an error, and scanning continues with other - -- ALI files. + -- processed recursively. In GNATprove mode a failure to read an ALI file + -- is not reported as an error, and scanning continues with other ALI + -- files. procedure Set_Source_Table (A : ALI_Id); -- Build source table entry corresponding to the ALI file whose id is A diff --git a/gcc/ada/ali.ads b/gcc/ada/ali.ads index 5e2ec71..7e12c7b 100644 --- a/gcc/ada/ali.ads +++ b/gcc/ada/ali.ads @@ -1429,7 +1429,7 @@ package ALI is -- both. If both are provided then only the Read_Lines value is used, -- and the Ignore_Lines parameter is ignored. -- - -- Read_XREF is set True to read and acquire the cross-reference + -- Read_Xref is set True to read and acquire the cross-reference -- information. If Read_XREF is set to True, then the effect is to ignore -- all lines other than U, W, D and X lines and the Ignore_Lines and -- Read_Lines parameters are ignored (i.e. the use of True for Read_XREF -- cgit v1.1 From 327940801d612d563781e5b58063889d247058b4 Mon Sep 17 00:00:00 2001 From: Javier Miranda Date: Tue, 17 Sep 2019 07:59:53 +0000 Subject: [Ada] Ada 2020: Raise expressions in limited contexts (AI12-0172) This patch adds support for the use of raise expressions in more limited contexts (as described in the Ada Isssue AI12-0172). 2019-09-17 Javier Miranda gcc/ada/ * exp_ch3.adb (Build_Record_Init_Proc): Do not generate code to adjust the tag component when the record is initialized with a raise expression. * sem_aggr.adb (Valid_Limited_Ancestor): Return True for N_Raise_Expression nodes. (Valid_Ancestor_Type): Return True for raise expressions. * sem_ch3.adb (Analyze_Component_Declaration): Do not report an error when a component is initialized with a raise expression. * sem_ch4.adb (Analyze_Qualified_Expression): Do not report an error when the aggregate has a raise expression. gcc/testsuite/ * gnat.dg/limited4.adb: New testcase. From-SVN: r275776 --- gcc/ada/ChangeLog | 13 +++++++++ gcc/ada/exp_ch3.adb | 10 +++++-- gcc/ada/sem_aggr.adb | 10 +++++++ gcc/ada/sem_ch3.adb | 15 +++++++++- gcc/ada/sem_ch4.adb | 4 ++- gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gnat.dg/limited4.adb | 58 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/limited4.adb (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index fb1f7f5..2855751 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,16 @@ +2019-09-17 Javier Miranda + + * exp_ch3.adb (Build_Record_Init_Proc): Do not generate code to + adjust the tag component when the record is initialized with a + raise expression. + * sem_aggr.adb (Valid_Limited_Ancestor): Return True for + N_Raise_Expression nodes. + (Valid_Ancestor_Type): Return True for raise expressions. + * sem_ch3.adb (Analyze_Component_Declaration): Do not report an + error when a component is initialized with a raise expression. + * sem_ch4.adb (Analyze_Qualified_Expression): Do not report an + error when the aggregate has a raise expression. + 2019-09-17 Piotr Trojanek * ali.ads: Fix casing in comment. diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb index 8763600..b08f51c 100644 --- a/gcc/ada/exp_ch3.adb +++ b/gcc/ada/exp_ch3.adb @@ -1922,9 +1922,15 @@ package body Exp_Ch3 is -- Adjust the tag if tagged (because of possible view conversions). -- Suppress the tag adjustment when not Tagged_Type_Expansion because - -- tags are represented implicitly in objects. + -- tags are represented implicitly in objects, and when the record is + -- initialized with a raise expression. - if Is_Tagged_Type (Typ) and then Tagged_Type_Expansion then + if Is_Tagged_Type (Typ) + and then Tagged_Type_Expansion + and then Nkind (Exp) /= N_Raise_Expression + and then (Nkind (Exp) /= N_Qualified_Expression + or else Nkind (Expression (Exp)) /= N_Raise_Expression) + then Append_To (Res, Make_Assignment_Statement (Default_Loc, Name => diff --git a/gcc/ada/sem_aggr.adb b/gcc/ada/sem_aggr.adb index bc80121..87fe050 100644 --- a/gcc/ada/sem_aggr.adb +++ b/gcc/ada/sem_aggr.adb @@ -3158,6 +3158,9 @@ package body Sem_Aggr is elsif Nkind (Anc) = N_Qualified_Expression then return Valid_Limited_Ancestor (Expression (Anc)); + elsif Nkind (Anc) = N_Raise_Expression then + return True; + else return False; end if; @@ -3199,6 +3202,13 @@ package body Sem_Aggr is then return True; + -- The parent type may be a raise expression (which is legal in + -- any expression context). + + elsif A_Type = Raise_Type then + A_Type := Etype (Imm_Type); + return True; + else Imm_Type := Etype (Base_Type (Imm_Type)); end if; diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb index 6af9419..86b6e0d 100644 --- a/gcc/ada/sem_ch3.adb +++ b/gcc/ada/sem_ch3.adb @@ -2047,10 +2047,23 @@ package body Sem_Ch3 is end if; end if; + -- Avoid reporting spurious errors if the component is initialized with + -- a raise expression (which is legal in any expression context) + + if Present (E) + and then + (Nkind (E) = N_Raise_Expression + or else (Nkind (E) = N_Qualified_Expression + and then Nkind (Expression (E)) = N_Raise_Expression)) + then + null; + -- The parent type may be a private view with unknown discriminants, -- and thus unconstrained. Regular components must be constrained. - if not Is_Definite_Subtype (T) and then Chars (Id) /= Name_uParent then + elsif not Is_Definite_Subtype (T) + and then Chars (Id) /= Name_uParent + then if Is_Class_Wide_Type (T) then Error_Msg_N ("class-wide subtype with unknown discriminants" & diff --git a/gcc/ada/sem_ch4.adb b/gcc/ada/sem_ch4.adb index 0dccd33..313398a 100644 --- a/gcc/ada/sem_ch4.adb +++ b/gcc/ada/sem_ch4.adb @@ -4001,7 +4001,9 @@ package body Sem_Ch4 is if Is_Class_Wide_Type (T) then if not Is_Overloaded (Expr) then - if Base_Type (Etype (Expr)) /= Base_Type (T) then + if Base_Type (Etype (Expr)) /= Base_Type (T) + and then Etype (Expr) /= Raise_Type + then if Nkind (Expr) = N_Aggregate then Error_Msg_N ("type of aggregate cannot be class-wide", Expr); else diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b701f9e..30c75df 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-09-17 Javier Miranda + + * gnat.dg/limited4.adb: New testcase. + 2019-09-17 Eric Botcazou * gnat.dg/pack25.adb: New testcase. diff --git a/gcc/testsuite/gnat.dg/limited4.adb b/gcc/testsuite/gnat.dg/limited4.adb new file mode 100644 index 0000000..1a8ec97 --- /dev/null +++ b/gcc/testsuite/gnat.dg/limited4.adb @@ -0,0 +1,58 @@ +-- { dg-do compile } +procedure Limited4 is + TBD_Error : exception; + + type Lim_Rec is limited record + A : Integer; + B : Boolean; + end record; + + type Lim_Tagged is tagged limited record + R : Lim_Rec; + N : Natural; + end record; + + type Lim_Ext is new Lim_Tagged with record + G : Natural; + end record; + + -- a) initialization expression of a CW object_declaration + + Obj1 : Lim_Tagged'Class := (raise TBD_Error); + Obj2 : Lim_Tagged'Class := Lim_Tagged'Class'(raise TBD_Error); + + -- b) initialization expression of a CW component_declaration + + type Rec is record + Comp01 : Lim_Tagged'Class := (raise TBD_Error); + Comp02 : Lim_Tagged'Class := Lim_Tagged'Class'((raise TBD_Error)); + end record; + + -- c) the expression of a record_component_association + + Obj : Lim_Tagged := (R => raise TBD_Error, N => 4); + + -- d) the expression for an ancestor_part of an extension_aggregate + + Ext1 : Lim_Ext := ((raise TBD_Error) with G => 0); + Ext2 : Lim_Ext := (Lim_Tagged'(raise TBD_Error) with G => 0); + + -- e) default_expression or actual parameter for a formal object of + -- mode in + + function Do_Test1 (Obj : Lim_Tagged) return Boolean is + begin + return True; + end; + + function Do_Test2 + (Obj : Lim_Tagged := (raise TBD_Error)) return Boolean is + begin + return True; + end; + + Check : Boolean; +begin + Check := Do_Test1 (raise TBD_Error); + Check := Do_Test2; +end; \ No newline at end of file -- cgit v1.1 From 01e44bfa81a3423d55e5d624e2c7241daedf44e4 Mon Sep 17 00:00:00 2001 From: Javier Miranda Date: Tue, 17 Sep 2019 07:59:58 +0000 Subject: [Ada] Missing tagged type decoration in corresponding record subtypes The frontend silently skips propagating attribute Is_Tagged_Type to the constrained corresponding record subtype associated with a protected type or task type with discriminants. This change does not affect the functionality of the compiler; it leaves more clean the decoration of internal entities. 2019-09-17 Javier Miranda gcc/ada/ * sem_ch3.adb (Constrain_Corresponding_Record): Propagate attribute Is_Tagged_Type. From-SVN: r275777 --- gcc/ada/ChangeLog | 5 +++++ gcc/ada/sem_ch3.adb | 1 + 2 files changed, 6 insertions(+) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 2855751..1d728fe 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,5 +1,10 @@ 2019-09-17 Javier Miranda + * sem_ch3.adb (Constrain_Corresponding_Record): Propagate + attribute Is_Tagged_Type. + +2019-09-17 Javier Miranda + * exp_ch3.adb (Build_Record_Init_Proc): Do not generate code to adjust the tag component when the record is initialized with a raise expression. diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb index 86b6e0d..257761a 100644 --- a/gcc/ada/sem_ch3.adb +++ b/gcc/ada/sem_ch3.adb @@ -13750,6 +13750,7 @@ package body Sem_Ch3 is begin Set_Etype (T_Sub, Corr_Rec); Set_Has_Discriminants (T_Sub, Has_Discriminants (Prot_Subt)); + Set_Is_Tagged_Type (T_Sub, Is_Tagged_Type (Corr_Rec)); Set_Is_Constrained (T_Sub, True); Set_First_Entity (T_Sub, First_Entity (Corr_Rec)); Set_Last_Entity (T_Sub, Last_Entity (Corr_Rec)); -- cgit v1.1 From a9a08e6d331cb454741d2b089cdedaefedfd5271 Mon Sep 17 00:00:00 2001 From: Ed Schonberg Date: Tue, 17 Sep 2019 08:00:07 +0000 Subject: [Ada] In a generic use Presanalyze_Spec_Expression on Predicates When verifying that the meaning of an aspect has not changed between the freeze point of the entity and the end of the declarations, we analkyze a copy of the expression to verify its conformance to previous analysis. If the expression contains overloaded references, these have to be resolved, which is not done if the expression is only preanalyzed. This applies in particular to expressions in predicates. 2019-09-17 Ed Schonberg gcc/ada/ * sem_ch13.adb (Check_Aspect_At_End_Of_Declarations): In a generic context, for a Predicate aspect, use Preanalyze_Spec_Expression to verify conformance. gcc/testsuite/ * gnat.dg/predicate13.adb, gnat.dg/predicate13.ads: New testcase. From-SVN: r275778 --- gcc/ada/ChangeLog | 6 ++++++ gcc/ada/sem_ch13.adb | 2 +- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gnat.dg/predicate13.adb | 3 +++ gcc/testsuite/gnat.dg/predicate13.ads | 23 +++++++++++++++++++++++ 5 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gnat.dg/predicate13.adb create mode 100644 gcc/testsuite/gnat.dg/predicate13.ads (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 1d728fe..94877b2 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,9 @@ +2019-09-17 Ed Schonberg + + * sem_ch13.adb (Check_Aspect_At_End_Of_Declarations): In a + generic context, for a Predicate aspect, use + Preanalyze_Spec_Expression to verify conformance. + 2019-09-17 Javier Miranda * sem_ch3.adb (Constrain_Corresponding_Record): Propagate diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb index 2538c1d..ef9f965 100644 --- a/gcc/ada/sem_ch13.adb +++ b/gcc/ada/sem_ch13.adb @@ -9383,7 +9383,7 @@ package body Sem_Ch13 is or else A_Id = Aspect_Priority then Push_Type (Ent); - Preanalyze (Freeze_Expr); + Preanalyze_Spec_Expression (Freeze_Expr, T); Pop_Type (Ent); else Preanalyze (Freeze_Expr); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 30c75df..d5b3e5a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-17 Ed Schonberg + + * gnat.dg/predicate13.adb, gnat.dg/predicate13.ads: New + testcase. + 2019-09-17 Javier Miranda * gnat.dg/limited4.adb: New testcase. diff --git a/gcc/testsuite/gnat.dg/predicate13.adb b/gcc/testsuite/gnat.dg/predicate13.adb new file mode 100644 index 0000000..24b6918 --- /dev/null +++ b/gcc/testsuite/gnat.dg/predicate13.adb @@ -0,0 +1,3 @@ +package body Predicate13 is + procedure Dummy is null; +end Predicate13; \ No newline at end of file diff --git a/gcc/testsuite/gnat.dg/predicate13.ads b/gcc/testsuite/gnat.dg/predicate13.ads new file mode 100644 index 0000000..2e19d49 --- /dev/null +++ b/gcc/testsuite/gnat.dg/predicate13.ads @@ -0,0 +1,23 @@ +-- { dg-do compile } +generic +package Predicate13 is + + function Valid return Boolean is + (True); + + function Foo return Boolean is + (True); + + type State_Type is (Valid, Invalid); + type Context_Type is private; + + private + + type Context_Type is + record + State : State_Type; + end record with Dynamic_Predicate => (State = Valid); + + procedure Dummy; + +end Predicate13; -- cgit v1.1 From cbb0b55385692dca6898a2668766f17ea42c4d2e Mon Sep 17 00:00:00 2001 From: Yannick Moy Date: Tue, 17 Sep 2019 08:01:10 +0000 Subject: [Ada] Do not inline dispatching operations in GNATprove mode In GNATprove, local subprograms without contracts are candidates for inlining, so that they are only analyzed in the context of their calls. This does not apply to dispatching operations, which may be called through dispatching, in an unknown calling context. Hence such operations should not be considered as candidates for inlining. There is no test as this has no effect on compilation. 2019-09-17 Yannick Moy gcc/ada/ * inline.adb (Can_Be_Inlined_In_GNATprove_Mode): Add handling for dispatching operations. From-SVN: r275779 --- gcc/ada/ChangeLog | 5 +++++ gcc/ada/inline.adb | 6 ++++++ 2 files changed, 11 insertions(+) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 94877b2..a2f7e27 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,8 @@ +2019-09-17 Yannick Moy + + * inline.adb (Can_Be_Inlined_In_GNATprove_Mode): Add handling + for dispatching operations. + 2019-09-17 Ed Schonberg * sem_ch13.adb (Check_Aspect_At_End_Of_Declarations): In a diff --git a/gcc/ada/inline.adb b/gcc/ada/inline.adb index e5ecb55..6e345d6 100644 --- a/gcc/ada/inline.adb +++ b/gcc/ada/inline.adb @@ -1681,6 +1681,12 @@ package body Inline is elsif not In_Extended_Main_Code_Unit (Id) then return False; + -- Do not inline dispatching operations, as only their static calls + -- can be analyzed in context, and not their dispatching calls. + + elsif Is_Dispatching_Operation (Id) then + return False; + -- Do not inline subprograms marked No_Return, possibly used for -- signaling errors, which GNATprove handles specially. -- cgit v1.1 From ee7c961db9da34d3e437eba0088f7291a7a5dfb4 Mon Sep 17 00:00:00 2001 From: Piotr Trojanek Date: Tue, 17 Sep 2019 08:01:23 +0000 Subject: [Ada] A new utility routine for detecting attribute 'Old Add a utility routine for detecting attribute 'Old. It will be immediately reused in the GNATprove backend. 2019-09-17 Piotr Trojanek gcc/ada/ * sem_util.ads, sem_util.adb (Is_Attribute_Old): New utility routine. From-SVN: r275780 --- gcc/ada/ChangeLog | 5 +++++ gcc/ada/sem_util.adb | 10 ++++++++++ gcc/ada/sem_util.ads | 3 +++ 3 files changed, 18 insertions(+) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index a2f7e27..705756d 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,8 @@ +2019-09-17 Piotr Trojanek + + * sem_util.ads, sem_util.adb (Is_Attribute_Old): New utility + routine. + 2019-09-17 Yannick Moy * inline.adb (Can_Be_Inlined_In_GNATprove_Mode): Add handling diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb index 86ae740..b7d2895 100644 --- a/gcc/ada/sem_util.adb +++ b/gcc/ada/sem_util.adb @@ -13559,6 +13559,16 @@ package body Sem_Util is Is_Volatile_Full_Access (Etype (Entity (N))))); end Is_Atomic_Or_VFA_Object; + ---------------------- + -- Is_Attribute_Old -- + ---------------------- + + function Is_Attribute_Old (N : Node_Id) return Boolean is + begin + return Nkind (N) = N_Attribute_Reference + and then Attribute_Name (N) = Name_Old; + end Is_Attribute_Old; + ------------------------- -- Is_Attribute_Result -- ------------------------- diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads index c9065e5..2d1bcf0 100644 --- a/gcc/ada/sem_util.ads +++ b/gcc/ada/sem_util.ads @@ -1549,6 +1549,9 @@ package Sem_Util is -- Determine whether arbitrary node N denotes a reference to an object -- which is either atomic or Volatile_Full_Access. + function Is_Attribute_Old (N : Node_Id) return Boolean; + -- Determine whether node N denotes attribute 'Old + function Is_Attribute_Result (N : Node_Id) return Boolean; -- Determine whether node N denotes attribute 'Result -- cgit v1.1 From b9bfbf45419a641c0b92b1954b94b73cb3dfb935 Mon Sep 17 00:00:00 2001 From: Vadim Godunko Date: Tue, 17 Sep 2019 08:01:37 +0000 Subject: [Ada] Avoid to close irrelevant file descriptors 'Close' subprogram of GNAT.Expect can close irrelevant file descriptors when 'Expect' was terminated by Process_Died exception and any file open operations was done before call to 'Close'. 2019-09-17 Vadim Godunko gcc/ada/ * libgnat/g-expect.ads, libgnat/g-expect.adb (Close_Input): New subprogram. (Get_Command_Output): Call Close_Input to close input stream. (Expect_Internal): Likewise. (Close): Likewise. * libgnat/g-exptty.adb (Close): Likewise. gcc/testsuite/ * gnat.dg/expect3.adb: New testcase. From-SVN: r275781 --- gcc/ada/ChangeLog | 9 ++++++++ gcc/ada/libgnat/g-expect.adb | 43 +++++++++++++++++++++++++++++---------- gcc/ada/libgnat/g-expect.ads | 4 ++++ gcc/ada/libgnat/g-exptty.adb | 4 +--- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gnat.dg/expect3.adb | 33 ++++++++++++++++++++++++++++++ 6 files changed, 83 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/expect3.adb (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 705756d..c952898 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,12 @@ +2019-09-17 Vadim Godunko + + * libgnat/g-expect.ads, libgnat/g-expect.adb (Close_Input): New + subprogram. + (Get_Command_Output): Call Close_Input to close input stream. + (Expect_Internal): Likewise. + (Close): Likewise. + * libgnat/g-exptty.adb (Close): Likewise. + 2019-09-17 Piotr Trojanek * sem_util.ads, sem_util.adb (Is_Attribute_Old): New utility diff --git a/gcc/ada/libgnat/g-expect.adb b/gcc/ada/libgnat/g-expect.adb index 21c7913..b44c7a5 100644 --- a/gcc/ada/libgnat/g-expect.adb +++ b/gcc/ada/libgnat/g-expect.adb @@ -222,15 +222,17 @@ package body GNAT.Expect is Next_Filter : Filter_List; begin - if Descriptor.Input_Fd /= Invalid_FD then - Close (Descriptor.Input_Fd); - end if; + Close_Input (Descriptor); - if Descriptor.Error_Fd /= Descriptor.Output_Fd then + if Descriptor.Error_Fd /= Descriptor.Output_Fd + and then Descriptor.Error_Fd /= Invalid_FD + then Close (Descriptor.Error_Fd); end if; - Close (Descriptor.Output_Fd); + if Descriptor.Output_Fd /= Invalid_FD then + Close (Descriptor.Output_Fd); + end if; -- ??? Should have timeouts for different signals @@ -267,6 +269,27 @@ package body GNAT.Expect is Close (Descriptor, Status); end Close; + ----------------- + -- Close_Input -- + ----------------- + + procedure Close_Input (Pid : in out Process_Descriptor) is + begin + if Pid.Input_Fd /= Invalid_FD then + Close (Pid.Input_Fd); + end if; + + if Pid.Output_Fd = Pid.Input_Fd then + Pid.Output_Fd := Invalid_FD; + end if; + + if Pid.Error_Fd = Pid.Input_Fd then + Pid.Error_Fd := Invalid_FD; + end if; + + Pid.Input_Fd := Invalid_FD; + end Close_Input; + ------------ -- Expect -- ------------ @@ -667,8 +690,7 @@ package body GNAT.Expect is Result := Expect_Internal_Error; if D /= 0 then - Close (Descriptors (D).Input_Fd); - Descriptors (D).Input_Fd := Invalid_FD; + Close_Input (Descriptors (D).all); end if; return; @@ -707,9 +729,9 @@ package body GNAT.Expect is -- Error or End of file if N <= 0 then - Close (Descriptors (D).Input_Fd); - Descriptors (D).Input_Fd := Invalid_FD; + Close_Input (Descriptors (D).all); Result := Expect_Process_Died; + return; else @@ -931,8 +953,7 @@ package body GNAT.Expect is Send (Process, Input); end if; - Close (Process.Input_Fd); - Process.Input_Fd := Invalid_FD; + Close_Input (Process); declare Result : Expect_Match; diff --git a/gcc/ada/libgnat/g-expect.ads b/gcc/ada/libgnat/g-expect.ads index ae84f84..77bb579 100644 --- a/gcc/ada/libgnat/g-expect.ads +++ b/gcc/ada/libgnat/g-expect.ads @@ -613,6 +613,10 @@ private -- spawns the child process (based on Cmd). On systems that support fork, -- this procedure is executed inside the newly created process. + procedure Close_Input (Pid : in out Process_Descriptor); + -- Closes input file descriptor. Set Input_Fd to Invalid_Fd as well as + -- Output_Fd and Error_Fd when they share same file descriptor. + type Process_Descriptor is tagged record Pid : aliased Process_Id := Invalid_Pid; Input_Fd : GNAT.OS_Lib.File_Descriptor := GNAT.OS_Lib.Invalid_FD; diff --git a/gcc/ada/libgnat/g-exptty.adb b/gcc/ada/libgnat/g-exptty.adb index 728c5c6..4f0300f 100644 --- a/gcc/ada/libgnat/g-exptty.adb +++ b/gcc/ada/libgnat/g-exptty.adb @@ -93,9 +93,7 @@ package body GNAT.Expect.TTY is -- signal, so this needs to be done while the file descriptors are -- still open (it used to be after the closes and that was wrong). - if Descriptor.Input_Fd /= Invalid_FD then - Close (Descriptor.Input_Fd); - end if; + Close_Input (Descriptor); if Descriptor.Error_Fd /= Descriptor.Output_Fd and then Descriptor.Error_Fd /= Invalid_FD diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d5b3e5a..caed11b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-09-17 Vadim Godunko + + * gnat.dg/expect3.adb: New testcase. + 2019-09-17 Ed Schonberg * gnat.dg/predicate13.adb, gnat.dg/predicate13.ads: New diff --git a/gcc/testsuite/gnat.dg/expect3.adb b/gcc/testsuite/gnat.dg/expect3.adb new file mode 100644 index 0000000..a833ea9 --- /dev/null +++ b/gcc/testsuite/gnat.dg/expect3.adb @@ -0,0 +1,33 @@ +-- { dg-do run } + +with Ada.Text_IO; + +with GNAT.Expect.TTY; +with GNAT.OS_Lib; + +procedure Expect3 is + Pid : GNAT.Expect.TTY.TTY_Process_Descriptor; + Args : GNAT.OS_Lib.Argument_List (1 .. 0); + Result : GNAT.Expect.Expect_Match; + +begin + Pid.Non_Blocking_Spawn ("true", Args); + + begin + Pid.Expect (Result, ".*"); + + raise Program_Error; + + exception + when GNAT.Expect.Process_Died => + declare + File : Ada.Text_IO.File_Type; + + begin + Ada.Text_IO.Create (File); + Pid.Close; + Ada.Text_IO.Put_Line (File, "Test of write operation"); + Ada.Text_IO.Close (File); + end; + end; +end Expect3; \ No newline at end of file -- cgit v1.1 From 19716ceb1676e1a947527b3ae1d59dce646dd76c Mon Sep 17 00:00:00 2001 From: Vadim Godunko Date: Tue, 17 Sep 2019 08:01:42 +0000 Subject: [Ada] GNAT.Expect (Expect_Internal): Try to call 'poll' few times 'poll' returns -1 in case of any error (including interruption by a signal), so call need to be repeated few times to avoid false failures. 2019-09-17 Vadim Godunko gcc/ada/ * libgnat/g-expect.adb (Expect_Internal): Try to call 'poll' few times. From-SVN: r275782 --- gcc/ada/ChangeLog | 5 +++++ gcc/ada/libgnat/g-expect.adb | 13 +++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index c952898..ab8c8a5 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,5 +1,10 @@ 2019-09-17 Vadim Godunko + * libgnat/g-expect.adb (Expect_Internal): Try to call 'poll' few + times. + +2019-09-17 Vadim Godunko + * libgnat/g-expect.ads, libgnat/g-expect.adb (Close_Input): New subprogram. (Get_Command_Output): Call Close_Input to close input stream. diff --git a/gcc/ada/libgnat/g-expect.adb b/gcc/ada/libgnat/g-expect.adb index b44c7a5..0ee010e 100644 --- a/gcc/ada/libgnat/g-expect.adb +++ b/gcc/ada/libgnat/g-expect.adb @@ -679,8 +679,17 @@ package body GNAT.Expect is -- Loop until we match or we have a timeout loop - Num_Descriptors := - Poll (Fds'Address, Fds_Count, Timeout, D'Access, Is_Set'Address); + -- Poll may be interrupted on Linux by a signal and need to be + -- repeated. We don't want to check for errno = EINTER, so just + -- attempt to call Poll a few times. + + for J in 1 .. 3 loop + Num_Descriptors := + Poll + (Fds'Address, Fds_Count, Timeout, D'Access, Is_Set'Address); + + exit when Num_Descriptors /= -1; + end loop; case Num_Descriptors is -- cgit v1.1 From 94c44a8a3000348707a456f8ebc1b1d67b688ea4 Mon Sep 17 00:00:00 2001 From: Vadim Godunko Date: Tue, 17 Sep 2019 08:01:48 +0000 Subject: [Ada] Close file descriptors allocated for tty only once 2019-09-17 Vadim Godunko gcc/ada/ * libgnat/g-exptty.ads (Close_Input): New subprogram. * libgnat/g-exptty.adb (Close_Input): New subprogram. (Close): Move close of TTY to Close_Input. * terminals.c (__gnat_close_tty): Set file descriptors to invalid value after close. From-SVN: r275783 --- gcc/ada/ChangeLog | 8 ++++++++ gcc/ada/libgnat/g-exptty.adb | 48 +++++++++++++++++++++++++++++++++++++------- gcc/ada/libgnat/g-exptty.ads | 2 ++ gcc/ada/terminals.c | 4 ++-- 4 files changed, 53 insertions(+), 9 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index ab8c8a5..1ef2c62 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,5 +1,13 @@ 2019-09-17 Vadim Godunko + * libgnat/g-exptty.ads (Close_Input): New subprogram. + * libgnat/g-exptty.adb (Close_Input): New subprogram. + (Close): Move close of TTY to Close_Input. + * terminals.c (__gnat_close_tty): Set file descriptors to + invalid value after close. + +2019-09-17 Vadim Godunko + * libgnat/g-expect.adb (Expect_Internal): Try to call 'poll' few times. diff --git a/gcc/ada/libgnat/g-exptty.adb b/gcc/ada/libgnat/g-exptty.adb index 4f0300f..b193448 100644 --- a/gcc/ada/libgnat/g-exptty.adb +++ b/gcc/ada/libgnat/g-exptty.adb @@ -74,9 +74,6 @@ package body GNAT.Expect.TTY is procedure Free_Process (Process : System.Address); pragma Import (C, Free_Process, "__gnat_free_process"); - procedure Close_TTY (Process : System.Address); - pragma Import (C, Close_TTY, "__gnat_close_tty"); - begin -- If we haven't already closed the process @@ -123,10 +120,6 @@ package body GNAT.Expect.TTY is Status := Descriptor.Exit_Status; end if; - if not On_Windows then - Close_TTY (Descriptor.Process); - end if; - Free_Process (Descriptor.Process'Address); Descriptor.Process := System.Null_Address; @@ -141,6 +134,47 @@ package body GNAT.Expect.TTY is Close (Descriptor, Status); end Close; + ----------------- + -- Close_Input -- + ----------------- + + overriding procedure Close_Input + (Descriptor : in out TTY_Process_Descriptor) + is + function TTY_FD + (Handle : System.Address) return GNAT.OS_Lib.File_Descriptor; + pragma Import (C, TTY_FD, "__gnat_tty_fd"); + + procedure Close_TTY (Process : System.Address); + pragma Import (C, Close_TTY, "__gnat_close_tty"); + + begin + if not On_Windows and then Descriptor.Process /= System.Null_Address then + -- Check whether input/output/error streams use master descriptor and + -- reset corresponding members. + + if Descriptor.Input_Fd = TTY_FD (Descriptor.Process) then + Descriptor.Input_Fd := Invalid_FD; + end if; + + if Descriptor.Output_Fd = TTY_FD (Descriptor.Process) then + Descriptor.Output_Fd := Invalid_FD; + end if; + + if Descriptor.Error_Fd = TTY_FD (Descriptor.Process) then + Descriptor.Error_Fd := Invalid_FD; + end if; + + -- Close master descriptor. + + Close_TTY (Descriptor.Process); + end if; + + -- Call parent's implementation to close all remaining descriptors. + + Process_Descriptor (Descriptor).Close_Input; + end Close_Input; + ----------------------------- -- Close_Pseudo_Descriptor -- ----------------------------- diff --git a/gcc/ada/libgnat/g-exptty.ads b/gcc/ada/libgnat/g-exptty.ads index 57aa8d7..81068a6 100644 --- a/gcc/ada/libgnat/g-exptty.ads +++ b/gcc/ada/libgnat/g-exptty.ads @@ -134,6 +134,8 @@ private Cmd : String; Args : System.Address); + procedure Close_Input (Descriptor : in out TTY_Process_Descriptor); + Still_Active : constant Integer := -1; type TTY_Process_Descriptor is new Process_Descriptor with record diff --git a/gcc/ada/terminals.c b/gcc/ada/terminals.c index 320ad28..0ce3fb7 100644 --- a/gcc/ada/terminals.c +++ b/gcc/ada/terminals.c @@ -1648,8 +1648,8 @@ __gnat_new_tty (void) */ void __gnat_close_tty (pty_desc* desc) { - if (desc->master_fd >= 0) close (desc->master_fd); - if (desc->slave_fd >= 0) close (desc->slave_fd); + if (desc->master_fd >= 0) { close (desc->master_fd); desc->master_fd = -1; } + if (desc->slave_fd >= 0) { close (desc->slave_fd); desc->slave_fd = -1; } } /* __gnat_tty_name - return slave side device name -- cgit v1.1 From 402b91503e266ad8337be9cf05ea967fbe4cbe3c Mon Sep 17 00:00:00 2001 From: Ed Falis Date: Tue, 17 Sep 2019 08:01:53 +0000 Subject: [Ada] Remove section on pragma No_Run_Time This pragma has been long obsolescent and confuses users. 2019-09-17 Ed Falis gcc/ada/ * doc/gnat_rm/implementation_defined_pragmas.rst: Remove section. * gnat_rm.texi, gnat_ugn.texi: Regenerate. From-SVN: r275784 --- gcc/ada/ChangeLog | 6 + .../doc/gnat_rm/implementation_defined_pragmas.rst | 16 - gcc/ada/gnat_rm.texi | 1408 ++++++++++---------- gcc/ada/gnat_ugn.texi | 4 +- 4 files changed, 703 insertions(+), 731 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 1ef2c62..7ccb70f 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,9 @@ +2019-09-17 Ed Falis + + * doc/gnat_rm/implementation_defined_pragmas.rst: Remove + section. + * gnat_rm.texi, gnat_ugn.texi: Regenerate. + 2019-09-17 Vadim Godunko * libgnat/g-exptty.ads (Close_Input): New subprogram. diff --git a/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst b/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst index 625a38f..1498475 100644 --- a/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst +++ b/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst @@ -4049,22 +4049,6 @@ Note that in Ada 2005 mode, this pragma is part of the language. It is available in all earlier versions of Ada as an implementation-defined pragma. -Pragma No_Run_Time -================== - -Syntax: - - -.. code-block:: ada - - pragma No_Run_Time; - - -This is an obsolete configuration pragma that historically was used to -set up a runtime library with no object code. It is now used only for -internal testing. The pragma has been superseded by the reconfigurable -runtime capability of GNAT. - Pragma No_Strict_Aliasing ========================= diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi index d5aa396..23b822c 100644 --- a/gcc/ada/gnat_rm.texi +++ b/gcc/ada/gnat_rm.texi @@ -21,7 +21,7 @@ @copying @quotation -GNAT Reference Manual , Aug 01, 2019 +GNAT Reference Manual , Sep 13, 2019 AdaCore @@ -214,7 +214,6 @@ Implementation Defined Pragmas * Pragma No_Heap_Finalization:: * Pragma No_Inline:: * Pragma No_Return:: -* Pragma No_Run_Time:: * Pragma No_Strict_Aliasing:: * Pragma No_Tagged_Streams:: * Pragma Normalize_Scalars:: @@ -1292,7 +1291,6 @@ consideration, the use of these pragmas should be minimized. * Pragma No_Heap_Finalization:: * Pragma No_Inline:: * Pragma No_Return:: -* Pragma No_Run_Time:: * Pragma No_Strict_Aliasing:: * Pragma No_Tagged_Streams:: * Pragma Normalize_Scalars:: @@ -5524,7 +5522,7 @@ in particular it is not subject to the use of option @emph{-gnatn} or @emph{-gnatN}. It is illegal to specify both pragma @code{No_Inline} and pragma @code{Inline_Always} for the same @code{NAME}. -@node Pragma No_Return,Pragma No_Run_Time,Pragma No_Inline,Implementation Defined Pragmas +@node Pragma No_Return,Pragma No_Strict_Aliasing,Pragma No_Inline,Implementation Defined Pragmas @anchor{gnat_rm/implementation_defined_pragmas pragma-no-return}@anchor{aa} @section Pragma No_Return @@ -5551,24 +5549,8 @@ Note that in Ada 2005 mode, this pragma is part of the language. It is available in all earlier versions of Ada as an implementation-defined pragma. -@node Pragma No_Run_Time,Pragma No_Strict_Aliasing,Pragma No_Return,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-no-run-time}@anchor{ab} -@section Pragma No_Run_Time - - -Syntax: - -@example -pragma No_Run_Time; -@end example - -This is an obsolete configuration pragma that historically was used to -set up a runtime library with no object code. It is now used only for -internal testing. The pragma has been superseded by the reconfigurable -runtime capability of GNAT. - -@node Pragma No_Strict_Aliasing,Pragma No_Tagged_Streams,Pragma No_Run_Time,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-no-strict-aliasing}@anchor{ac} +@node Pragma No_Strict_Aliasing,Pragma No_Tagged_Streams,Pragma No_Return,Implementation Defined Pragmas +@anchor{gnat_rm/implementation_defined_pragmas pragma-no-strict-aliasing}@anchor{ab} @section Pragma No_Strict_Aliasing @@ -5590,7 +5572,7 @@ in the @cite{GNAT User's Guide}. This pragma currently has no effects on access to unconstrained array types. @node Pragma No_Tagged_Streams,Pragma Normalize_Scalars,Pragma No_Strict_Aliasing,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-no-tagged-streams}@anchor{ad}@anchor{gnat_rm/implementation_defined_pragmas id26}@anchor{ae} +@anchor{gnat_rm/implementation_defined_pragmas pragma-no-tagged-streams}@anchor{ac}@anchor{gnat_rm/implementation_defined_pragmas id26}@anchor{ad} @section Pragma No_Tagged_Streams @@ -5629,7 +5611,7 @@ with empty strings. This is useful to avoid exposing entity names at binary level but has a negative impact on the debuggability of tagged types. @node Pragma Normalize_Scalars,Pragma Obsolescent,Pragma No_Tagged_Streams,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-normalize-scalars}@anchor{af} +@anchor{gnat_rm/implementation_defined_pragmas pragma-normalize-scalars}@anchor{ae} @section Pragma Normalize_Scalars @@ -5711,7 +5693,7 @@ will always generate an invalid value if one exists. @end table @node Pragma Obsolescent,Pragma Optimize_Alignment,Pragma Normalize_Scalars,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-obsolescent}@anchor{b0}@anchor{gnat_rm/implementation_defined_pragmas id27}@anchor{b1} +@anchor{gnat_rm/implementation_defined_pragmas pragma-obsolescent}@anchor{af}@anchor{gnat_rm/implementation_defined_pragmas id27}@anchor{b0} @section Pragma Obsolescent @@ -5807,7 +5789,7 @@ So if you specify @code{Entity =>} for the @code{Entity} argument, and a @code{M argument is present, it must be preceded by @code{Message =>}. @node Pragma Optimize_Alignment,Pragma Ordered,Pragma Obsolescent,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-optimize-alignment}@anchor{b2} +@anchor{gnat_rm/implementation_defined_pragmas pragma-optimize-alignment}@anchor{b1} @section Pragma Optimize_Alignment @@ -5893,7 +5875,7 @@ latter are compiled by default in pragma Optimize_Alignment (Off) mode if no pragma appears at the start of the file. @node Pragma Ordered,Pragma Overflow_Mode,Pragma Optimize_Alignment,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-ordered}@anchor{b3} +@anchor{gnat_rm/implementation_defined_pragmas pragma-ordered}@anchor{b2} @section Pragma Ordered @@ -5985,7 +5967,7 @@ For additional information please refer to the description of the @emph{-gnatw.u} switch in the GNAT User's Guide. @node Pragma Overflow_Mode,Pragma Overriding_Renamings,Pragma Ordered,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-overflow-mode}@anchor{b4} +@anchor{gnat_rm/implementation_defined_pragmas pragma-overflow-mode}@anchor{b3} @section Pragma Overflow_Mode @@ -6024,7 +6006,7 @@ The pragma @code{Unsuppress (Overflow_Check)} unsuppresses (enables) overflow checking, but does not affect the overflow mode. @node Pragma Overriding_Renamings,Pragma Partition_Elaboration_Policy,Pragma Overflow_Mode,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-overriding-renamings}@anchor{b5} +@anchor{gnat_rm/implementation_defined_pragmas pragma-overriding-renamings}@anchor{b4} @section Pragma Overriding_Renamings @@ -6059,7 +6041,7 @@ RM 8.3 (15) stipulates that an overridden operation is not visible within the declaration of the overriding operation. @node Pragma Partition_Elaboration_Policy,Pragma Part_Of,Pragma Overriding_Renamings,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-partition-elaboration-policy}@anchor{b6} +@anchor{gnat_rm/implementation_defined_pragmas pragma-partition-elaboration-policy}@anchor{b5} @section Pragma Partition_Elaboration_Policy @@ -6076,7 +6058,7 @@ versions of Ada as an implementation-defined pragma. See Ada 2012 Reference Manual for details. @node Pragma Part_Of,Pragma Passive,Pragma Partition_Elaboration_Policy,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id28}@anchor{b7}@anchor{gnat_rm/implementation_defined_pragmas pragma-part-of}@anchor{b8} +@anchor{gnat_rm/implementation_defined_pragmas id28}@anchor{b6}@anchor{gnat_rm/implementation_defined_pragmas pragma-part-of}@anchor{b7} @section Pragma Part_Of @@ -6092,7 +6074,7 @@ For the semantics of this pragma, see the entry for aspect @code{Part_Of} in the SPARK 2014 Reference Manual, section 7.2.6. @node Pragma Passive,Pragma Persistent_BSS,Pragma Part_Of,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-passive}@anchor{b9} +@anchor{gnat_rm/implementation_defined_pragmas pragma-passive}@anchor{b8} @section Pragma Passive @@ -6116,7 +6098,7 @@ For more information on the subject of passive tasks, see the section 'Passive Task Optimization' in the GNAT Users Guide. @node Pragma Persistent_BSS,Pragma Polling,Pragma Passive,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id29}@anchor{ba}@anchor{gnat_rm/implementation_defined_pragmas pragma-persistent-bss}@anchor{bb} +@anchor{gnat_rm/implementation_defined_pragmas id29}@anchor{b9}@anchor{gnat_rm/implementation_defined_pragmas pragma-persistent-bss}@anchor{ba} @section Pragma Persistent_BSS @@ -6147,7 +6129,7 @@ If this pragma is used on a target where this feature is not supported, then the pragma will be ignored. See also @code{pragma Linker_Section}. @node Pragma Polling,Pragma Post,Pragma Persistent_BSS,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-polling}@anchor{bc} +@anchor{gnat_rm/implementation_defined_pragmas pragma-polling}@anchor{bb} @section Pragma Polling @@ -6189,7 +6171,7 @@ Note that polling can also be enabled by use of the @emph{-gnatP} switch. See the section on switches for gcc in the @cite{GNAT User's Guide}. @node Pragma Post,Pragma Postcondition,Pragma Polling,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-post}@anchor{bd} +@anchor{gnat_rm/implementation_defined_pragmas pragma-post}@anchor{bc} @section Pragma Post @@ -6214,7 +6196,7 @@ appear at the start of the declarations in a subprogram body (preceded only by other pragmas). @node Pragma Postcondition,Pragma Post_Class,Pragma Post,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-postcondition}@anchor{be} +@anchor{gnat_rm/implementation_defined_pragmas pragma-postcondition}@anchor{bd} @section Pragma Postcondition @@ -6379,7 +6361,7 @@ Ada 2012, and has been retained in its original form for compatibility purposes. @node Pragma Post_Class,Pragma Rename_Pragma,Pragma Postcondition,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-post-class}@anchor{bf} +@anchor{gnat_rm/implementation_defined_pragmas pragma-post-class}@anchor{be} @section Pragma Post_Class @@ -6414,7 +6396,7 @@ policy that controls this pragma is @code{Post'Class}, not @code{Post_Class}. @node Pragma Rename_Pragma,Pragma Pre,Pragma Post_Class,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-rename-pragma}@anchor{c0} +@anchor{gnat_rm/implementation_defined_pragmas pragma-rename-pragma}@anchor{bf} @section Pragma Rename_Pragma @@ -6453,7 +6435,7 @@ Pragma Inline_Only will not necessarily mean the same thing as the other Ada compiler; it's up to you to make sure the semantics are close enough. @node Pragma Pre,Pragma Precondition,Pragma Rename_Pragma,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-pre}@anchor{c1} +@anchor{gnat_rm/implementation_defined_pragmas pragma-pre}@anchor{c0} @section Pragma Pre @@ -6478,7 +6460,7 @@ appear at the start of the declarations in a subprogram body (preceded only by other pragmas). @node Pragma Precondition,Pragma Predicate,Pragma Pre,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-precondition}@anchor{c2} +@anchor{gnat_rm/implementation_defined_pragmas pragma-precondition}@anchor{c1} @section Pragma Precondition @@ -6537,7 +6519,7 @@ Ada 2012, and has been retained in its original form for compatibility purposes. @node Pragma Predicate,Pragma Predicate_Failure,Pragma Precondition,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-predicate}@anchor{c3}@anchor{gnat_rm/implementation_defined_pragmas id30}@anchor{c4} +@anchor{gnat_rm/implementation_defined_pragmas pragma-predicate}@anchor{c2}@anchor{gnat_rm/implementation_defined_pragmas id30}@anchor{c3} @section Pragma Predicate @@ -6591,7 +6573,7 @@ defined for subtype B). When following this approach, the use of predicates should be avoided. @node Pragma Predicate_Failure,Pragma Preelaborable_Initialization,Pragma Predicate,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-predicate-failure}@anchor{c5} +@anchor{gnat_rm/implementation_defined_pragmas pragma-predicate-failure}@anchor{c4} @section Pragma Predicate_Failure @@ -6608,7 +6590,7 @@ the language-defined @code{Predicate_Failure} aspect, and shares its restrictions and semantics. @node Pragma Preelaborable_Initialization,Pragma Prefix_Exception_Messages,Pragma Predicate_Failure,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-preelaborable-initialization}@anchor{c6} +@anchor{gnat_rm/implementation_defined_pragmas pragma-preelaborable-initialization}@anchor{c5} @section Pragma Preelaborable_Initialization @@ -6623,7 +6605,7 @@ versions of Ada as an implementation-defined pragma. See Ada 2012 Reference Manual for details. @node Pragma Prefix_Exception_Messages,Pragma Pre_Class,Pragma Preelaborable_Initialization,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-prefix-exception-messages}@anchor{c7} +@anchor{gnat_rm/implementation_defined_pragmas pragma-prefix-exception-messages}@anchor{c6} @section Pragma Prefix_Exception_Messages @@ -6654,7 +6636,7 @@ prefixing in this case, you can always call @code{GNAT.Source_Info.Enclosing_Entity} and prepend the string manually. @node Pragma Pre_Class,Pragma Priority_Specific_Dispatching,Pragma Prefix_Exception_Messages,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-pre-class}@anchor{c8} +@anchor{gnat_rm/implementation_defined_pragmas pragma-pre-class}@anchor{c7} @section Pragma Pre_Class @@ -6689,7 +6671,7 @@ policy that controls this pragma is @code{Pre'Class}, not @code{Pre_Class}. @node Pragma Priority_Specific_Dispatching,Pragma Profile,Pragma Pre_Class,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-priority-specific-dispatching}@anchor{c9} +@anchor{gnat_rm/implementation_defined_pragmas pragma-priority-specific-dispatching}@anchor{c8} @section Pragma Priority_Specific_Dispatching @@ -6713,7 +6695,7 @@ versions of Ada as an implementation-defined pragma. See Ada 2012 Reference Manual for details. @node Pragma Profile,Pragma Profile_Warnings,Pragma Priority_Specific_Dispatching,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-profile}@anchor{ca} +@anchor{gnat_rm/implementation_defined_pragmas pragma-profile}@anchor{c9} @section Pragma Profile @@ -6987,7 +6969,7 @@ conforming Ada constructs. The profile enables the following three pragmas: @end itemize @node Pragma Profile_Warnings,Pragma Propagate_Exceptions,Pragma Profile,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-profile-warnings}@anchor{cb} +@anchor{gnat_rm/implementation_defined_pragmas pragma-profile-warnings}@anchor{ca} @section Pragma Profile_Warnings @@ -7005,7 +6987,7 @@ violations of the profile generate warning messages instead of error messages. @node Pragma Propagate_Exceptions,Pragma Provide_Shift_Operators,Pragma Profile_Warnings,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-propagate-exceptions}@anchor{cc} +@anchor{gnat_rm/implementation_defined_pragmas pragma-propagate-exceptions}@anchor{cb} @section Pragma Propagate_Exceptions @@ -7024,7 +7006,7 @@ purposes. It used to be used in connection with optimization of a now-obsolete mechanism for implementation of exceptions. @node Pragma Provide_Shift_Operators,Pragma Psect_Object,Pragma Propagate_Exceptions,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-provide-shift-operators}@anchor{cd} +@anchor{gnat_rm/implementation_defined_pragmas pragma-provide-shift-operators}@anchor{cc} @section Pragma Provide_Shift_Operators @@ -7044,7 +7026,7 @@ including the function declarations for these five operators, together with the pragma Import (Intrinsic, ...) statements. @node Pragma Psect_Object,Pragma Pure_Function,Pragma Provide_Shift_Operators,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-psect-object}@anchor{ce} +@anchor{gnat_rm/implementation_defined_pragmas pragma-psect-object}@anchor{cd} @section Pragma Psect_Object @@ -7064,7 +7046,7 @@ EXTERNAL_SYMBOL ::= This pragma is identical in effect to pragma @code{Common_Object}. @node Pragma Pure_Function,Pragma Rational,Pragma Psect_Object,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-pure-function}@anchor{cf}@anchor{gnat_rm/implementation_defined_pragmas id31}@anchor{d0} +@anchor{gnat_rm/implementation_defined_pragmas pragma-pure-function}@anchor{ce}@anchor{gnat_rm/implementation_defined_pragmas id31}@anchor{cf} @section Pragma Pure_Function @@ -7126,7 +7108,7 @@ unit is not a Pure unit in the categorization sense. So for example, a function thus marked is free to @code{with} non-pure units. @node Pragma Rational,Pragma Ravenscar,Pragma Pure_Function,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-rational}@anchor{d1} +@anchor{gnat_rm/implementation_defined_pragmas pragma-rational}@anchor{d0} @section Pragma Rational @@ -7144,7 +7126,7 @@ pragma Profile (Rational); @end example @node Pragma Ravenscar,Pragma Refined_Depends,Pragma Rational,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-ravenscar}@anchor{d2} +@anchor{gnat_rm/implementation_defined_pragmas pragma-ravenscar}@anchor{d1} @section Pragma Ravenscar @@ -7164,7 +7146,7 @@ pragma Profile (Ravenscar); which is the preferred method of setting the @code{Ravenscar} profile. @node Pragma Refined_Depends,Pragma Refined_Global,Pragma Ravenscar,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-depends}@anchor{d3}@anchor{gnat_rm/implementation_defined_pragmas id32}@anchor{d4} +@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-depends}@anchor{d2}@anchor{gnat_rm/implementation_defined_pragmas id32}@anchor{d3} @section Pragma Refined_Depends @@ -7197,7 +7179,7 @@ For the semantics of this pragma, see the entry for aspect @code{Refined_Depends the SPARK 2014 Reference Manual, section 6.1.5. @node Pragma Refined_Global,Pragma Refined_Post,Pragma Refined_Depends,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-global}@anchor{d5}@anchor{gnat_rm/implementation_defined_pragmas id33}@anchor{d6} +@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-global}@anchor{d4}@anchor{gnat_rm/implementation_defined_pragmas id33}@anchor{d5} @section Pragma Refined_Global @@ -7222,7 +7204,7 @@ For the semantics of this pragma, see the entry for aspect @code{Refined_Global} the SPARK 2014 Reference Manual, section 6.1.4. @node Pragma Refined_Post,Pragma Refined_State,Pragma Refined_Global,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-post}@anchor{d7}@anchor{gnat_rm/implementation_defined_pragmas id34}@anchor{d8} +@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-post}@anchor{d6}@anchor{gnat_rm/implementation_defined_pragmas id34}@anchor{d7} @section Pragma Refined_Post @@ -7236,7 +7218,7 @@ For the semantics of this pragma, see the entry for aspect @code{Refined_Post} i the SPARK 2014 Reference Manual, section 7.2.7. @node Pragma Refined_State,Pragma Relative_Deadline,Pragma Refined_Post,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-state}@anchor{d9}@anchor{gnat_rm/implementation_defined_pragmas id35}@anchor{da} +@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-state}@anchor{d8}@anchor{gnat_rm/implementation_defined_pragmas id35}@anchor{d9} @section Pragma Refined_State @@ -7262,7 +7244,7 @@ For the semantics of this pragma, see the entry for aspect @code{Refined_State} the SPARK 2014 Reference Manual, section 7.2.2. @node Pragma Relative_Deadline,Pragma Remote_Access_Type,Pragma Refined_State,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-relative-deadline}@anchor{db} +@anchor{gnat_rm/implementation_defined_pragmas pragma-relative-deadline}@anchor{da} @section Pragma Relative_Deadline @@ -7277,7 +7259,7 @@ versions of Ada as an implementation-defined pragma. See Ada 2012 Reference Manual for details. @node Pragma Remote_Access_Type,Pragma Restricted_Run_Time,Pragma Relative_Deadline,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id36}@anchor{dc}@anchor{gnat_rm/implementation_defined_pragmas pragma-remote-access-type}@anchor{dd} +@anchor{gnat_rm/implementation_defined_pragmas id36}@anchor{db}@anchor{gnat_rm/implementation_defined_pragmas pragma-remote-access-type}@anchor{dc} @section Pragma Remote_Access_Type @@ -7303,7 +7285,7 @@ pertaining to remote access to class-wide types. At instantiation, the actual type must be a remote access to class-wide type. @node Pragma Restricted_Run_Time,Pragma Restriction_Warnings,Pragma Remote_Access_Type,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-restricted-run-time}@anchor{de} +@anchor{gnat_rm/implementation_defined_pragmas pragma-restricted-run-time}@anchor{dd} @section Pragma Restricted_Run_Time @@ -7324,7 +7306,7 @@ which is the preferred method of setting the restricted run time profile. @node Pragma Restriction_Warnings,Pragma Reviewable,Pragma Restricted_Run_Time,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-restriction-warnings}@anchor{df} +@anchor{gnat_rm/implementation_defined_pragmas pragma-restriction-warnings}@anchor{de} @section Pragma Restriction_Warnings @@ -7362,7 +7344,7 @@ generating a warning, but any other use of implementation defined pragmas will cause a warning to be generated. @node Pragma Reviewable,Pragma Secondary_Stack_Size,Pragma Restriction_Warnings,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-reviewable}@anchor{e0} +@anchor{gnat_rm/implementation_defined_pragmas pragma-reviewable}@anchor{df} @section Pragma Reviewable @@ -7466,7 +7448,7 @@ comprehensive messages identifying possible problems based on this information. @node Pragma Secondary_Stack_Size,Pragma Share_Generic,Pragma Reviewable,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id37}@anchor{e1}@anchor{gnat_rm/implementation_defined_pragmas pragma-secondary-stack-size}@anchor{e2} +@anchor{gnat_rm/implementation_defined_pragmas id37}@anchor{e0}@anchor{gnat_rm/implementation_defined_pragmas pragma-secondary-stack-size}@anchor{e1} @section Pragma Secondary_Stack_Size @@ -7502,7 +7484,7 @@ Note the pragma cannot appear when the restriction @code{No_Secondary_Stack} is in effect. @node Pragma Share_Generic,Pragma Shared,Pragma Secondary_Stack_Size,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-share-generic}@anchor{e3} +@anchor{gnat_rm/implementation_defined_pragmas pragma-share-generic}@anchor{e2} @section Pragma Share_Generic @@ -7520,7 +7502,7 @@ than to check that the given names are all names of generic units or generic instances. @node Pragma Shared,Pragma Short_Circuit_And_Or,Pragma Share_Generic,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id38}@anchor{e4}@anchor{gnat_rm/implementation_defined_pragmas pragma-shared}@anchor{e5} +@anchor{gnat_rm/implementation_defined_pragmas id38}@anchor{e3}@anchor{gnat_rm/implementation_defined_pragmas pragma-shared}@anchor{e4} @section Pragma Shared @@ -7528,7 +7510,7 @@ This pragma is provided for compatibility with Ada 83. The syntax and semantics are identical to pragma Atomic. @node Pragma Short_Circuit_And_Or,Pragma Short_Descriptors,Pragma Shared,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-short-circuit-and-or}@anchor{e6} +@anchor{gnat_rm/implementation_defined_pragmas pragma-short-circuit-and-or}@anchor{e5} @section Pragma Short_Circuit_And_Or @@ -7547,7 +7529,7 @@ within the file being compiled, it applies only to the file being compiled. There is no requirement that all units in a partition use this option. @node Pragma Short_Descriptors,Pragma Simple_Storage_Pool_Type,Pragma Short_Circuit_And_Or,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-short-descriptors}@anchor{e7} +@anchor{gnat_rm/implementation_defined_pragmas pragma-short-descriptors}@anchor{e6} @section Pragma Short_Descriptors @@ -7561,7 +7543,7 @@ This pragma is provided for compatibility with other Ada implementations. It is recognized but ignored by all current versions of GNAT. @node Pragma Simple_Storage_Pool_Type,Pragma Source_File_Name,Pragma Short_Descriptors,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-simple-storage-pool-type}@anchor{e8}@anchor{gnat_rm/implementation_defined_pragmas id39}@anchor{e9} +@anchor{gnat_rm/implementation_defined_pragmas pragma-simple-storage-pool-type}@anchor{e7}@anchor{gnat_rm/implementation_defined_pragmas id39}@anchor{e8} @section Pragma Simple_Storage_Pool_Type @@ -7615,7 +7597,7 @@ storage-management discipline). An object of a simple storage pool type can be associated with an access type by specifying the attribute -@ref{ea,,Simple_Storage_Pool}. For example: +@ref{e9,,Simple_Storage_Pool}. For example: @example My_Pool : My_Simple_Storage_Pool_Type; @@ -7625,11 +7607,11 @@ type Acc is access My_Data_Type; for Acc'Simple_Storage_Pool use My_Pool; @end example -See attribute @ref{ea,,Simple_Storage_Pool} +See attribute @ref{e9,,Simple_Storage_Pool} for further details. @node Pragma Source_File_Name,Pragma Source_File_Name_Project,Pragma Simple_Storage_Pool_Type,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-source-file-name}@anchor{eb}@anchor{gnat_rm/implementation_defined_pragmas id40}@anchor{ec} +@anchor{gnat_rm/implementation_defined_pragmas pragma-source-file-name}@anchor{ea}@anchor{gnat_rm/implementation_defined_pragmas id40}@anchor{eb} @section Pragma Source_File_Name @@ -7721,19 +7703,19 @@ aware of these pragmas, and so other tools that use the projet file would not be aware of the intended naming conventions. If you are using project files, file naming is controlled by Source_File_Name_Project pragmas, which are usually supplied automatically by the project manager. A pragma -Source_File_Name cannot appear after a @ref{ed,,Pragma Source_File_Name_Project}. +Source_File_Name cannot appear after a @ref{ec,,Pragma Source_File_Name_Project}. For more details on the use of the @code{Source_File_Name} pragma, see the sections on @code{Using Other File Names} and @cite{Alternative File Naming Schemes' in the :title:`GNAT User's Guide}. @node Pragma Source_File_Name_Project,Pragma Source_Reference,Pragma Source_File_Name,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-source-file-name-project}@anchor{ed}@anchor{gnat_rm/implementation_defined_pragmas id41}@anchor{ee} +@anchor{gnat_rm/implementation_defined_pragmas pragma-source-file-name-project}@anchor{ec}@anchor{gnat_rm/implementation_defined_pragmas id41}@anchor{ed} @section Pragma Source_File_Name_Project This pragma has the same syntax and semantics as pragma Source_File_Name. It is only allowed as a stand-alone configuration pragma. -It cannot appear after a @ref{eb,,Pragma Source_File_Name}, and +It cannot appear after a @ref{ea,,Pragma Source_File_Name}, and most importantly, once pragma Source_File_Name_Project appears, no further Source_File_Name pragmas are allowed. @@ -7745,7 +7727,7 @@ Source_File_Name or Source_File_Name_Project pragmas (which would not be known to the project manager). @node Pragma Source_Reference,Pragma SPARK_Mode,Pragma Source_File_Name_Project,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-source-reference}@anchor{ef} +@anchor{gnat_rm/implementation_defined_pragmas pragma-source-reference}@anchor{ee} @section Pragma Source_Reference @@ -7769,7 +7751,7 @@ string expression other than a string literal. This is because its value is needed for error messages issued by all phases of the compiler. @node Pragma SPARK_Mode,Pragma Static_Elaboration_Desired,Pragma Source_Reference,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-spark-mode}@anchor{f0}@anchor{gnat_rm/implementation_defined_pragmas id42}@anchor{f1} +@anchor{gnat_rm/implementation_defined_pragmas pragma-spark-mode}@anchor{ef}@anchor{gnat_rm/implementation_defined_pragmas id42}@anchor{f0} @section Pragma SPARK_Mode @@ -7851,7 +7833,7 @@ SPARK_Mode (@code{Off}), then that pragma will need to be repeated in the package body. @node Pragma Static_Elaboration_Desired,Pragma Stream_Convert,Pragma SPARK_Mode,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-static-elaboration-desired}@anchor{f2} +@anchor{gnat_rm/implementation_defined_pragmas pragma-static-elaboration-desired}@anchor{f1} @section Pragma Static_Elaboration_Desired @@ -7875,7 +7857,7 @@ construction of larger aggregates with static components that include an others choice.) @node Pragma Stream_Convert,Pragma Style_Checks,Pragma Static_Elaboration_Desired,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-stream-convert}@anchor{f3} +@anchor{gnat_rm/implementation_defined_pragmas pragma-stream-convert}@anchor{f2} @section Pragma Stream_Convert @@ -7952,7 +7934,7 @@ the pragma is silently ignored, and the default implementation of the stream attributes is used instead. @node Pragma Style_Checks,Pragma Subtitle,Pragma Stream_Convert,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-style-checks}@anchor{f4} +@anchor{gnat_rm/implementation_defined_pragmas pragma-style-checks}@anchor{f3} @section Pragma Style_Checks @@ -8025,7 +8007,7 @@ Rf2 : Integer := ARG; -- OK, no error @end example @node Pragma Subtitle,Pragma Suppress,Pragma Style_Checks,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-subtitle}@anchor{f5} +@anchor{gnat_rm/implementation_defined_pragmas pragma-subtitle}@anchor{f4} @section Pragma Subtitle @@ -8039,7 +8021,7 @@ This pragma is recognized for compatibility with other Ada compilers but is ignored by GNAT. @node Pragma Suppress,Pragma Suppress_All,Pragma Subtitle,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress}@anchor{f6} +@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress}@anchor{f5} @section Pragma Suppress @@ -8112,7 +8094,7 @@ Of course, run-time checks are omitted whenever the compiler can prove that they will not fail, whether or not checks are suppressed. @node Pragma Suppress_All,Pragma Suppress_Debug_Info,Pragma Suppress,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress-all}@anchor{f7} +@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress-all}@anchor{f6} @section Pragma Suppress_All @@ -8131,7 +8113,7 @@ The use of the standard Ada pragma @code{Suppress (All_Checks)} as a normal configuration pragma is the preferred usage in GNAT. @node Pragma Suppress_Debug_Info,Pragma Suppress_Exception_Locations,Pragma Suppress_All,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress-debug-info}@anchor{f8}@anchor{gnat_rm/implementation_defined_pragmas id43}@anchor{f9} +@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress-debug-info}@anchor{f7}@anchor{gnat_rm/implementation_defined_pragmas id43}@anchor{f8} @section Pragma Suppress_Debug_Info @@ -8146,7 +8128,7 @@ for the specified entity. It is intended primarily for use in debugging the debugger, and navigating around debugger problems. @node Pragma Suppress_Exception_Locations,Pragma Suppress_Initialization,Pragma Suppress_Debug_Info,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress-exception-locations}@anchor{fa} +@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress-exception-locations}@anchor{f9} @section Pragma Suppress_Exception_Locations @@ -8169,7 +8151,7 @@ a partition, so it is fine to have some units within a partition compiled with this pragma and others compiled in normal mode without it. @node Pragma Suppress_Initialization,Pragma Task_Name,Pragma Suppress_Exception_Locations,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id44}@anchor{fb}@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress-initialization}@anchor{fc} +@anchor{gnat_rm/implementation_defined_pragmas id44}@anchor{fa}@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress-initialization}@anchor{fb} @section Pragma Suppress_Initialization @@ -8214,7 +8196,7 @@ is suppressed, just as though its subtype had been given in a pragma Suppress_Initialization, as described above. @node Pragma Task_Name,Pragma Task_Storage,Pragma Suppress_Initialization,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-task-name}@anchor{fd} +@anchor{gnat_rm/implementation_defined_pragmas pragma-task-name}@anchor{fc} @section Pragma Task_Name @@ -8270,7 +8252,7 @@ end; @end example @node Pragma Task_Storage,Pragma Test_Case,Pragma Task_Name,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-task-storage}@anchor{fe} +@anchor{gnat_rm/implementation_defined_pragmas pragma-task-storage}@anchor{fd} @section Pragma Task_Storage @@ -8290,7 +8272,7 @@ created, depending on the target. This pragma can appear anywhere a type. @node Pragma Test_Case,Pragma Thread_Local_Storage,Pragma Task_Storage,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-test-case}@anchor{ff}@anchor{gnat_rm/implementation_defined_pragmas id45}@anchor{100} +@anchor{gnat_rm/implementation_defined_pragmas pragma-test-case}@anchor{fe}@anchor{gnat_rm/implementation_defined_pragmas id45}@anchor{ff} @section Pragma Test_Case @@ -8346,7 +8328,7 @@ postcondition. Mode @code{Robustness} indicates that the precondition and postcondition of the subprogram should be ignored for this test case. @node Pragma Thread_Local_Storage,Pragma Time_Slice,Pragma Test_Case,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-thread-local-storage}@anchor{101}@anchor{gnat_rm/implementation_defined_pragmas id46}@anchor{102} +@anchor{gnat_rm/implementation_defined_pragmas pragma-thread-local-storage}@anchor{100}@anchor{gnat_rm/implementation_defined_pragmas id46}@anchor{101} @section Pragma Thread_Local_Storage @@ -8384,7 +8366,7 @@ If this pragma is used on a system where @code{TLS} is not supported, then an error message will be generated and the program will be rejected. @node Pragma Time_Slice,Pragma Title,Pragma Thread_Local_Storage,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-time-slice}@anchor{103} +@anchor{gnat_rm/implementation_defined_pragmas pragma-time-slice}@anchor{102} @section Pragma Time_Slice @@ -8400,7 +8382,7 @@ It is ignored if it is used in a system that does not allow this control, or if it appears in other than the main program unit. @node Pragma Title,Pragma Type_Invariant,Pragma Time_Slice,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-title}@anchor{104} +@anchor{gnat_rm/implementation_defined_pragmas pragma-title}@anchor{103} @section Pragma Title @@ -8425,7 +8407,7 @@ notation is used, and named and positional notation can be mixed following the normal rules for procedure calls in Ada. @node Pragma Type_Invariant,Pragma Type_Invariant_Class,Pragma Title,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-type-invariant}@anchor{105} +@anchor{gnat_rm/implementation_defined_pragmas pragma-type-invariant}@anchor{104} @section Pragma Type_Invariant @@ -8446,7 +8428,7 @@ controlled by the assertion identifier @code{Type_Invariant} rather than @code{Invariant}. @node Pragma Type_Invariant_Class,Pragma Unchecked_Union,Pragma Type_Invariant,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id47}@anchor{106}@anchor{gnat_rm/implementation_defined_pragmas pragma-type-invariant-class}@anchor{107} +@anchor{gnat_rm/implementation_defined_pragmas id47}@anchor{105}@anchor{gnat_rm/implementation_defined_pragmas pragma-type-invariant-class}@anchor{106} @section Pragma Type_Invariant_Class @@ -8473,7 +8455,7 @@ policy that controls this pragma is @code{Type_Invariant'Class}, not @code{Type_Invariant_Class}. @node Pragma Unchecked_Union,Pragma Unevaluated_Use_Of_Old,Pragma Type_Invariant_Class,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-unchecked-union}@anchor{108} +@anchor{gnat_rm/implementation_defined_pragmas pragma-unchecked-union}@anchor{107} @section Pragma Unchecked_Union @@ -8493,7 +8475,7 @@ version in all language modes (Ada 83, Ada 95, and Ada 2005). For full details, consult the Ada 2012 Reference Manual, section B.3.3. @node Pragma Unevaluated_Use_Of_Old,Pragma Unimplemented_Unit,Pragma Unchecked_Union,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-unevaluated-use-of-old}@anchor{109} +@anchor{gnat_rm/implementation_defined_pragmas pragma-unevaluated-use-of-old}@anchor{108} @section Pragma Unevaluated_Use_Of_Old @@ -8548,7 +8530,7 @@ uses up to the end of the corresponding statement sequence or sequence of package declarations. @node Pragma Unimplemented_Unit,Pragma Universal_Aliasing,Pragma Unevaluated_Use_Of_Old,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-unimplemented-unit}@anchor{10a} +@anchor{gnat_rm/implementation_defined_pragmas pragma-unimplemented-unit}@anchor{109} @section Pragma Unimplemented_Unit @@ -8568,7 +8550,7 @@ The abort only happens if code is being generated. Thus you can use specs of unimplemented packages in syntax or semantic checking mode. @node Pragma Universal_Aliasing,Pragma Universal_Data,Pragma Unimplemented_Unit,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-universal-aliasing}@anchor{10b}@anchor{gnat_rm/implementation_defined_pragmas id48}@anchor{10c} +@anchor{gnat_rm/implementation_defined_pragmas pragma-universal-aliasing}@anchor{10a}@anchor{gnat_rm/implementation_defined_pragmas id48}@anchor{10b} @section Pragma Universal_Aliasing @@ -8587,7 +8569,7 @@ situations in which it must be suppressed, see the section on @code{Optimization and Strict Aliasing} in the @cite{GNAT User's Guide}. @node Pragma Universal_Data,Pragma Unmodified,Pragma Universal_Aliasing,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-universal-data}@anchor{10d}@anchor{gnat_rm/implementation_defined_pragmas id49}@anchor{10e} +@anchor{gnat_rm/implementation_defined_pragmas pragma-universal-data}@anchor{10c}@anchor{gnat_rm/implementation_defined_pragmas id49}@anchor{10d} @section Pragma Universal_Data @@ -8611,7 +8593,7 @@ of this pragma is also available by applying the -univ switch on the compilations of units where universal addressing of the data is desired. @node Pragma Unmodified,Pragma Unreferenced,Pragma Universal_Data,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id50}@anchor{10f}@anchor{gnat_rm/implementation_defined_pragmas pragma-unmodified}@anchor{110} +@anchor{gnat_rm/implementation_defined_pragmas id50}@anchor{10e}@anchor{gnat_rm/implementation_defined_pragmas pragma-unmodified}@anchor{10f} @section Pragma Unmodified @@ -8645,7 +8627,7 @@ Thus it is never necessary to use @code{pragma Unmodified} for such variables, though it is harmless to do so. @node Pragma Unreferenced,Pragma Unreferenced_Objects,Pragma Unmodified,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-unreferenced}@anchor{111}@anchor{gnat_rm/implementation_defined_pragmas id51}@anchor{112} +@anchor{gnat_rm/implementation_defined_pragmas pragma-unreferenced}@anchor{110}@anchor{gnat_rm/implementation_defined_pragmas id51}@anchor{111} @section Pragma Unreferenced @@ -8689,7 +8671,7 @@ Note that if a warning is desired for all calls to a given subprogram, regardless of whether they occur in the same unit as the subprogram declaration, then this pragma should not be used (calls from another unit would not be flagged); pragma Obsolescent can be used instead -for this purpose, see @ref{b0,,Pragma Obsolescent}. +for this purpose, see @ref{af,,Pragma Obsolescent}. The second form of pragma @code{Unreferenced} is used within a context clause. In this case the arguments must be unit names of units previously @@ -8705,7 +8687,7 @@ Thus it is never necessary to use @code{pragma Unreferenced} for such variables, though it is harmless to do so. @node Pragma Unreferenced_Objects,Pragma Unreserve_All_Interrupts,Pragma Unreferenced,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-unreferenced-objects}@anchor{113}@anchor{gnat_rm/implementation_defined_pragmas id52}@anchor{114} +@anchor{gnat_rm/implementation_defined_pragmas pragma-unreferenced-objects}@anchor{112}@anchor{gnat_rm/implementation_defined_pragmas id52}@anchor{113} @section Pragma Unreferenced_Objects @@ -8730,7 +8712,7 @@ compiler will automatically suppress unwanted warnings about these variables not being referenced. @node Pragma Unreserve_All_Interrupts,Pragma Unsuppress,Pragma Unreferenced_Objects,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-unreserve-all-interrupts}@anchor{115} +@anchor{gnat_rm/implementation_defined_pragmas pragma-unreserve-all-interrupts}@anchor{114} @section Pragma Unreserve_All_Interrupts @@ -8766,7 +8748,7 @@ handled, see pragma @code{Interrupt_State}, which subsumes the functionality of the @code{Unreserve_All_Interrupts} pragma. @node Pragma Unsuppress,Pragma Use_VADS_Size,Pragma Unreserve_All_Interrupts,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-unsuppress}@anchor{116} +@anchor{gnat_rm/implementation_defined_pragmas pragma-unsuppress}@anchor{115} @section Pragma Unsuppress @@ -8802,7 +8784,7 @@ number of implementation-defined check names. See the description of pragma @code{Suppress} for full details. @node Pragma Use_VADS_Size,Pragma Unused,Pragma Unsuppress,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-use-vads-size}@anchor{117} +@anchor{gnat_rm/implementation_defined_pragmas pragma-use-vads-size}@anchor{116} @section Pragma Use_VADS_Size @@ -8826,7 +8808,7 @@ as implemented in the VADS compiler. See description of the VADS_Size attribute for further details. @node Pragma Unused,Pragma Validity_Checks,Pragma Use_VADS_Size,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-unused}@anchor{118}@anchor{gnat_rm/implementation_defined_pragmas id53}@anchor{119} +@anchor{gnat_rm/implementation_defined_pragmas pragma-unused}@anchor{117}@anchor{gnat_rm/implementation_defined_pragmas id53}@anchor{118} @section Pragma Unused @@ -8860,7 +8842,7 @@ Thus it is never necessary to use @code{pragma Unmodified} for such variables, though it is harmless to do so. @node Pragma Validity_Checks,Pragma Volatile,Pragma Unused,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-validity-checks}@anchor{11a} +@anchor{gnat_rm/implementation_defined_pragmas pragma-validity-checks}@anchor{119} @section Pragma Validity_Checks @@ -8916,7 +8898,7 @@ A := C; -- C will be validity checked @end example @node Pragma Volatile,Pragma Volatile_Full_Access,Pragma Validity_Checks,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id54}@anchor{11b}@anchor{gnat_rm/implementation_defined_pragmas pragma-volatile}@anchor{11c} +@anchor{gnat_rm/implementation_defined_pragmas id54}@anchor{11a}@anchor{gnat_rm/implementation_defined_pragmas pragma-volatile}@anchor{11b} @section Pragma Volatile @@ -8934,7 +8916,7 @@ implementation of pragma Volatile is upwards compatible with the implementation in DEC Ada 83. @node Pragma Volatile_Full_Access,Pragma Volatile_Function,Pragma Volatile,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id55}@anchor{11d}@anchor{gnat_rm/implementation_defined_pragmas pragma-volatile-full-access}@anchor{11e} +@anchor{gnat_rm/implementation_defined_pragmas id55}@anchor{11c}@anchor{gnat_rm/implementation_defined_pragmas pragma-volatile-full-access}@anchor{11d} @section Pragma Volatile_Full_Access @@ -8966,7 +8948,7 @@ It is not permissible to specify @code{Volatile_Full_Access} for a composite (record or array) type or object that has at least one @code{Aliased} component. @node Pragma Volatile_Function,Pragma Warning_As_Error,Pragma Volatile_Full_Access,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id56}@anchor{11f}@anchor{gnat_rm/implementation_defined_pragmas pragma-volatile-function}@anchor{120} +@anchor{gnat_rm/implementation_defined_pragmas id56}@anchor{11e}@anchor{gnat_rm/implementation_defined_pragmas pragma-volatile-function}@anchor{11f} @section Pragma Volatile_Function @@ -8980,7 +8962,7 @@ For the semantics of this pragma, see the entry for aspect @code{Volatile_Functi in the SPARK 2014 Reference Manual, section 7.1.2. @node Pragma Warning_As_Error,Pragma Warnings,Pragma Volatile_Function,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-warning-as-error}@anchor{121} +@anchor{gnat_rm/implementation_defined_pragmas pragma-warning-as-error}@anchor{120} @section Pragma Warning_As_Error @@ -9018,7 +9000,7 @@ as shown in the example below, to treat a class of warnings as errors. The above use of patterns to match the message applies only to warning messages generated by the front end. This pragma can also be applied to -warnings provided by the back end and mentioned in @ref{122,,Pragma Warnings}. +warnings provided by the back end and mentioned in @ref{121,,Pragma Warnings}. By using a single full @emph{-Wxxx} switch in the pragma, such warnings can also be treated as errors. @@ -9068,7 +9050,7 @@ the tag is changed from "warning:" to "error:" and the string "[warning-as-error]" is appended to the end of the message. @node Pragma Warnings,Pragma Weak_External,Pragma Warning_As_Error,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas id57}@anchor{123}@anchor{gnat_rm/implementation_defined_pragmas pragma-warnings}@anchor{122} +@anchor{gnat_rm/implementation_defined_pragmas id57}@anchor{122}@anchor{gnat_rm/implementation_defined_pragmas pragma-warnings}@anchor{121} @section Pragma Warnings @@ -9224,7 +9206,7 @@ selectively for each tool, and as a consequence to detect useless pragma Warnings with switch @code{-gnatw.w}. @node Pragma Weak_External,Pragma Wide_Character_Encoding,Pragma Warnings,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-weak-external}@anchor{124} +@anchor{gnat_rm/implementation_defined_pragmas pragma-weak-external}@anchor{123} @section Pragma Weak_External @@ -9275,7 +9257,7 @@ end External_Module; @end example @node Pragma Wide_Character_Encoding,,Pragma Weak_External,Implementation Defined Pragmas -@anchor{gnat_rm/implementation_defined_pragmas pragma-wide-character-encoding}@anchor{125} +@anchor{gnat_rm/implementation_defined_pragmas pragma-wide-character-encoding}@anchor{124} @section Pragma Wide_Character_Encoding @@ -9306,7 +9288,7 @@ encoding within that file, and does not affect withed units, specs, or subunits. @node Implementation Defined Aspects,Implementation Defined Attributes,Implementation Defined Pragmas,Top -@anchor{gnat_rm/implementation_defined_aspects implementation-defined-aspects}@anchor{126}@anchor{gnat_rm/implementation_defined_aspects doc}@anchor{127}@anchor{gnat_rm/implementation_defined_aspects id1}@anchor{128} +@anchor{gnat_rm/implementation_defined_aspects implementation-defined-aspects}@anchor{125}@anchor{gnat_rm/implementation_defined_aspects doc}@anchor{126}@anchor{gnat_rm/implementation_defined_aspects id1}@anchor{127} @chapter Implementation Defined Aspects @@ -9425,7 +9407,7 @@ or attribute definition clause. @end menu @node Aspect Abstract_State,Aspect Annotate,,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-abstract-state}@anchor{129} +@anchor{gnat_rm/implementation_defined_aspects aspect-abstract-state}@anchor{128} @section Aspect Abstract_State @@ -9434,7 +9416,7 @@ or attribute definition clause. This aspect is equivalent to @ref{1c,,pragma Abstract_State}. @node Aspect Annotate,Aspect Async_Readers,Aspect Abstract_State,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-annotate}@anchor{12a} +@anchor{gnat_rm/implementation_defined_aspects aspect-annotate}@anchor{129} @section Aspect Annotate @@ -9461,7 +9443,7 @@ Equivalent to @code{pragma Annotate (ID, ID @{, ARG@}, Entity => Name);} @end table @node Aspect Async_Readers,Aspect Async_Writers,Aspect Annotate,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-async-readers}@anchor{12b} +@anchor{gnat_rm/implementation_defined_aspects aspect-async-readers}@anchor{12a} @section Aspect Async_Readers @@ -9470,7 +9452,7 @@ Equivalent to @code{pragma Annotate (ID, ID @{, ARG@}, Entity => Name);} This boolean aspect is equivalent to @ref{31,,pragma Async_Readers}. @node Aspect Async_Writers,Aspect Constant_After_Elaboration,Aspect Async_Readers,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-async-writers}@anchor{12c} +@anchor{gnat_rm/implementation_defined_aspects aspect-async-writers}@anchor{12b} @section Aspect Async_Writers @@ -9479,7 +9461,7 @@ This boolean aspect is equivalent to @ref{31,,pragma Async_Readers}. This boolean aspect is equivalent to @ref{34,,pragma Async_Writers}. @node Aspect Constant_After_Elaboration,Aspect Contract_Cases,Aspect Async_Writers,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-constant-after-elaboration}@anchor{12d} +@anchor{gnat_rm/implementation_defined_aspects aspect-constant-after-elaboration}@anchor{12c} @section Aspect Constant_After_Elaboration @@ -9488,7 +9470,7 @@ This boolean aspect is equivalent to @ref{34,,pragma Async_Writers}. This aspect is equivalent to @ref{45,,pragma Constant_After_Elaboration}. @node Aspect Contract_Cases,Aspect Depends,Aspect Constant_After_Elaboration,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-contract-cases}@anchor{12e} +@anchor{gnat_rm/implementation_defined_aspects aspect-contract-cases}@anchor{12d} @section Aspect Contract_Cases @@ -9499,7 +9481,7 @@ of clauses being enclosed in parentheses so that syntactically it is an aggregate. @node Aspect Depends,Aspect Default_Initial_Condition,Aspect Contract_Cases,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-depends}@anchor{12f} +@anchor{gnat_rm/implementation_defined_aspects aspect-depends}@anchor{12e} @section Aspect Depends @@ -9508,7 +9490,7 @@ aggregate. This aspect is equivalent to @ref{56,,pragma Depends}. @node Aspect Default_Initial_Condition,Aspect Dimension,Aspect Depends,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-default-initial-condition}@anchor{130} +@anchor{gnat_rm/implementation_defined_aspects aspect-default-initial-condition}@anchor{12f} @section Aspect Default_Initial_Condition @@ -9517,7 +9499,7 @@ This aspect is equivalent to @ref{56,,pragma Depends}. This aspect is equivalent to @ref{51,,pragma Default_Initial_Condition}. @node Aspect Dimension,Aspect Dimension_System,Aspect Default_Initial_Condition,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-dimension}@anchor{131} +@anchor{gnat_rm/implementation_defined_aspects aspect-dimension}@anchor{130} @section Aspect Dimension @@ -9553,7 +9535,7 @@ Note that when the dimensioned type is an integer type, then any dimension value must be an integer literal. @node Aspect Dimension_System,Aspect Disable_Controlled,Aspect Dimension,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-dimension-system}@anchor{132} +@anchor{gnat_rm/implementation_defined_aspects aspect-dimension-system}@anchor{131} @section Aspect Dimension_System @@ -9613,7 +9595,7 @@ See section 'Performing Dimensionality Analysis in GNAT' in the GNAT Users Guide for detailed examples of use of the dimension system. @node Aspect Disable_Controlled,Aspect Effective_Reads,Aspect Dimension_System,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-disable-controlled}@anchor{133} +@anchor{gnat_rm/implementation_defined_aspects aspect-disable-controlled}@anchor{132} @section Aspect Disable_Controlled @@ -9626,7 +9608,7 @@ where for example you might want a record to be controlled or not depending on whether some run-time check is enabled or suppressed. @node Aspect Effective_Reads,Aspect Effective_Writes,Aspect Disable_Controlled,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-effective-reads}@anchor{134} +@anchor{gnat_rm/implementation_defined_aspects aspect-effective-reads}@anchor{133} @section Aspect Effective_Reads @@ -9635,7 +9617,7 @@ whether some run-time check is enabled or suppressed. This aspect is equivalent to @ref{5c,,pragma Effective_Reads}. @node Aspect Effective_Writes,Aspect Extensions_Visible,Aspect Effective_Reads,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-effective-writes}@anchor{135} +@anchor{gnat_rm/implementation_defined_aspects aspect-effective-writes}@anchor{134} @section Aspect Effective_Writes @@ -9644,7 +9626,7 @@ This aspect is equivalent to @ref{5c,,pragma Effective_Reads}. This aspect is equivalent to @ref{5e,,pragma Effective_Writes}. @node Aspect Extensions_Visible,Aspect Favor_Top_Level,Aspect Effective_Writes,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-extensions-visible}@anchor{136} +@anchor{gnat_rm/implementation_defined_aspects aspect-extensions-visible}@anchor{135} @section Aspect Extensions_Visible @@ -9653,7 +9635,7 @@ This aspect is equivalent to @ref{5e,,pragma Effective_Writes}. This aspect is equivalent to @ref{6a,,pragma Extensions_Visible}. @node Aspect Favor_Top_Level,Aspect Ghost,Aspect Extensions_Visible,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-favor-top-level}@anchor{137} +@anchor{gnat_rm/implementation_defined_aspects aspect-favor-top-level}@anchor{136} @section Aspect Favor_Top_Level @@ -9662,7 +9644,7 @@ This aspect is equivalent to @ref{6a,,pragma Extensions_Visible}. This boolean aspect is equivalent to @ref{6f,,pragma Favor_Top_Level}. @node Aspect Ghost,Aspect Global,Aspect Favor_Top_Level,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-ghost}@anchor{138} +@anchor{gnat_rm/implementation_defined_aspects aspect-ghost}@anchor{137} @section Aspect Ghost @@ -9671,7 +9653,7 @@ This boolean aspect is equivalent to @ref{6f,,pragma Favor_Top_Level}. This aspect is equivalent to @ref{72,,pragma Ghost}. @node Aspect Global,Aspect Initial_Condition,Aspect Ghost,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-global}@anchor{139} +@anchor{gnat_rm/implementation_defined_aspects aspect-global}@anchor{138} @section Aspect Global @@ -9680,7 +9662,7 @@ This aspect is equivalent to @ref{72,,pragma Ghost}. This aspect is equivalent to @ref{74,,pragma Global}. @node Aspect Initial_Condition,Aspect Initializes,Aspect Global,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-initial-condition}@anchor{13a} +@anchor{gnat_rm/implementation_defined_aspects aspect-initial-condition}@anchor{139} @section Aspect Initial_Condition @@ -9689,7 +9671,7 @@ This aspect is equivalent to @ref{74,,pragma Global}. This aspect is equivalent to @ref{82,,pragma Initial_Condition}. @node Aspect Initializes,Aspect Inline_Always,Aspect Initial_Condition,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-initializes}@anchor{13b} +@anchor{gnat_rm/implementation_defined_aspects aspect-initializes}@anchor{13a} @section Aspect Initializes @@ -9698,7 +9680,7 @@ This aspect is equivalent to @ref{82,,pragma Initial_Condition}. This aspect is equivalent to @ref{84,,pragma Initializes}. @node Aspect Inline_Always,Aspect Invariant,Aspect Initializes,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-inline-always}@anchor{13c} +@anchor{gnat_rm/implementation_defined_aspects aspect-inline-always}@anchor{13b} @section Aspect Inline_Always @@ -9707,7 +9689,7 @@ This aspect is equivalent to @ref{84,,pragma Initializes}. This boolean aspect is equivalent to @ref{87,,pragma Inline_Always}. @node Aspect Invariant,Aspect Invariant'Class,Aspect Inline_Always,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-invariant}@anchor{13d} +@anchor{gnat_rm/implementation_defined_aspects aspect-invariant}@anchor{13c} @section Aspect Invariant @@ -9718,18 +9700,18 @@ synonym for the language defined aspect @code{Type_Invariant} except that it is separately controllable using pragma @code{Assertion_Policy}. @node Aspect Invariant'Class,Aspect Iterable,Aspect Invariant,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-invariant-class}@anchor{13e} +@anchor{gnat_rm/implementation_defined_aspects aspect-invariant-class}@anchor{13d} @section Aspect Invariant'Class @geindex Invariant'Class -This aspect is equivalent to @ref{107,,pragma Type_Invariant_Class}. It is a +This aspect is equivalent to @ref{106,,pragma Type_Invariant_Class}. It is a synonym for the language defined aspect @code{Type_Invariant'Class} except that it is separately controllable using pragma @code{Assertion_Policy}. @node Aspect Iterable,Aspect Linker_Section,Aspect Invariant'Class,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-iterable}@anchor{13f} +@anchor{gnat_rm/implementation_defined_aspects aspect-iterable}@anchor{13e} @section Aspect Iterable @@ -9809,7 +9791,7 @@ function Get_Element (Cont : Container; Position : Cursor) return Element_Type; This aspect is used in the GNAT-defined formal container packages. @node Aspect Linker_Section,Aspect Lock_Free,Aspect Iterable,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-linker-section}@anchor{140} +@anchor{gnat_rm/implementation_defined_aspects aspect-linker-section}@anchor{13f} @section Aspect Linker_Section @@ -9818,7 +9800,7 @@ This aspect is used in the GNAT-defined formal container packages. This aspect is equivalent to @ref{96,,pragma Linker_Section}. @node Aspect Lock_Free,Aspect Max_Queue_Length,Aspect Linker_Section,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-lock-free}@anchor{141} +@anchor{gnat_rm/implementation_defined_aspects aspect-lock-free}@anchor{140} @section Aspect Lock_Free @@ -9827,7 +9809,7 @@ This aspect is equivalent to @ref{96,,pragma Linker_Section}. This boolean aspect is equivalent to @ref{98,,pragma Lock_Free}. @node Aspect Max_Queue_Length,Aspect No_Caching,Aspect Lock_Free,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-max-queue-length}@anchor{142} +@anchor{gnat_rm/implementation_defined_aspects aspect-max-queue-length}@anchor{141} @section Aspect Max_Queue_Length @@ -9836,7 +9818,7 @@ This boolean aspect is equivalent to @ref{98,,pragma Lock_Free}. This aspect is equivalent to @ref{a0,,pragma Max_Queue_Length}. @node Aspect No_Caching,Aspect No_Elaboration_Code_All,Aspect Max_Queue_Length,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-no-caching}@anchor{143} +@anchor{gnat_rm/implementation_defined_aspects aspect-no-caching}@anchor{142} @section Aspect No_Caching @@ -9845,7 +9827,7 @@ This aspect is equivalent to @ref{a0,,pragma Max_Queue_Length}. This boolean aspect is equivalent to @ref{a2,,pragma No_Caching}. @node Aspect No_Elaboration_Code_All,Aspect No_Inline,Aspect No_Caching,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-no-elaboration-code-all}@anchor{144} +@anchor{gnat_rm/implementation_defined_aspects aspect-no-elaboration-code-all}@anchor{143} @section Aspect No_Elaboration_Code_All @@ -9855,7 +9837,7 @@ This aspect is equivalent to @ref{a6,,pragma No_Elaboration_Code_All} for a program unit. @node Aspect No_Inline,Aspect No_Tagged_Streams,Aspect No_Elaboration_Code_All,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-no-inline}@anchor{145} +@anchor{gnat_rm/implementation_defined_aspects aspect-no-inline}@anchor{144} @section Aspect No_Inline @@ -9864,62 +9846,62 @@ for a program unit. This boolean aspect is equivalent to @ref{a9,,pragma No_Inline}. @node Aspect No_Tagged_Streams,Aspect Object_Size,Aspect No_Inline,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-no-tagged-streams}@anchor{146} +@anchor{gnat_rm/implementation_defined_aspects aspect-no-tagged-streams}@anchor{145} @section Aspect No_Tagged_Streams @geindex No_Tagged_Streams -This aspect is equivalent to @ref{ad,,pragma No_Tagged_Streams} with an +This aspect is equivalent to @ref{ac,,pragma No_Tagged_Streams} with an argument specifying a root tagged type (thus this aspect can only be applied to such a type). @node Aspect Object_Size,Aspect Obsolescent,Aspect No_Tagged_Streams,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-object-size}@anchor{147} +@anchor{gnat_rm/implementation_defined_aspects aspect-object-size}@anchor{146} @section Aspect Object_Size @geindex Object_Size -This aspect is equivalent to @ref{148,,attribute Object_Size}. +This aspect is equivalent to @ref{147,,attribute Object_Size}. @node Aspect Obsolescent,Aspect Part_Of,Aspect Object_Size,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-obsolescent}@anchor{149} +@anchor{gnat_rm/implementation_defined_aspects aspect-obsolescent}@anchor{148} @section Aspect Obsolescent @geindex Obsolsecent -This aspect is equivalent to @ref{b0,,pragma Obsolescent}. Note that the +This aspect is equivalent to @ref{af,,pragma Obsolescent}. Note that the evaluation of this aspect happens at the point of occurrence, it is not delayed until the freeze point. @node Aspect Part_Of,Aspect Persistent_BSS,Aspect Obsolescent,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-part-of}@anchor{14a} +@anchor{gnat_rm/implementation_defined_aspects aspect-part-of}@anchor{149} @section Aspect Part_Of @geindex Part_Of -This aspect is equivalent to @ref{b8,,pragma Part_Of}. +This aspect is equivalent to @ref{b7,,pragma Part_Of}. @node Aspect Persistent_BSS,Aspect Predicate,Aspect Part_Of,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-persistent-bss}@anchor{14b} +@anchor{gnat_rm/implementation_defined_aspects aspect-persistent-bss}@anchor{14a} @section Aspect Persistent_BSS @geindex Persistent_BSS -This boolean aspect is equivalent to @ref{bb,,pragma Persistent_BSS}. +This boolean aspect is equivalent to @ref{ba,,pragma Persistent_BSS}. @node Aspect Predicate,Aspect Pure_Function,Aspect Persistent_BSS,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-predicate}@anchor{14c} +@anchor{gnat_rm/implementation_defined_aspects aspect-predicate}@anchor{14b} @section Aspect Predicate @geindex Predicate -This aspect is equivalent to @ref{c3,,pragma Predicate}. It is thus +This aspect is equivalent to @ref{c2,,pragma Predicate}. It is thus similar to the language defined aspects @code{Dynamic_Predicate} and @code{Static_Predicate} except that whether the resulting predicate is static or dynamic is controlled by the form of the @@ -9927,239 +9909,239 @@ expression. It is also separately controllable using pragma @code{Assertion_Policy}. @node Aspect Pure_Function,Aspect Refined_Depends,Aspect Predicate,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-pure-function}@anchor{14d} +@anchor{gnat_rm/implementation_defined_aspects aspect-pure-function}@anchor{14c} @section Aspect Pure_Function @geindex Pure_Function -This boolean aspect is equivalent to @ref{cf,,pragma Pure_Function}. +This boolean aspect is equivalent to @ref{ce,,pragma Pure_Function}. @node Aspect Refined_Depends,Aspect Refined_Global,Aspect Pure_Function,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-refined-depends}@anchor{14e} +@anchor{gnat_rm/implementation_defined_aspects aspect-refined-depends}@anchor{14d} @section Aspect Refined_Depends @geindex Refined_Depends -This aspect is equivalent to @ref{d3,,pragma Refined_Depends}. +This aspect is equivalent to @ref{d2,,pragma Refined_Depends}. @node Aspect Refined_Global,Aspect Refined_Post,Aspect Refined_Depends,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-refined-global}@anchor{14f} +@anchor{gnat_rm/implementation_defined_aspects aspect-refined-global}@anchor{14e} @section Aspect Refined_Global @geindex Refined_Global -This aspect is equivalent to @ref{d5,,pragma Refined_Global}. +This aspect is equivalent to @ref{d4,,pragma Refined_Global}. @node Aspect Refined_Post,Aspect Refined_State,Aspect Refined_Global,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-refined-post}@anchor{150} +@anchor{gnat_rm/implementation_defined_aspects aspect-refined-post}@anchor{14f} @section Aspect Refined_Post @geindex Refined_Post -This aspect is equivalent to @ref{d7,,pragma Refined_Post}. +This aspect is equivalent to @ref{d6,,pragma Refined_Post}. @node Aspect Refined_State,Aspect Remote_Access_Type,Aspect Refined_Post,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-refined-state}@anchor{151} +@anchor{gnat_rm/implementation_defined_aspects aspect-refined-state}@anchor{150} @section Aspect Refined_State @geindex Refined_State -This aspect is equivalent to @ref{d9,,pragma Refined_State}. +This aspect is equivalent to @ref{d8,,pragma Refined_State}. @node Aspect Remote_Access_Type,Aspect Secondary_Stack_Size,Aspect Refined_State,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-remote-access-type}@anchor{152} +@anchor{gnat_rm/implementation_defined_aspects aspect-remote-access-type}@anchor{151} @section Aspect Remote_Access_Type @geindex Remote_Access_Type -This aspect is equivalent to @ref{dd,,pragma Remote_Access_Type}. +This aspect is equivalent to @ref{dc,,pragma Remote_Access_Type}. @node Aspect Secondary_Stack_Size,Aspect Scalar_Storage_Order,Aspect Remote_Access_Type,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-secondary-stack-size}@anchor{153} +@anchor{gnat_rm/implementation_defined_aspects aspect-secondary-stack-size}@anchor{152} @section Aspect Secondary_Stack_Size @geindex Secondary_Stack_Size -This aspect is equivalent to @ref{e2,,pragma Secondary_Stack_Size}. +This aspect is equivalent to @ref{e1,,pragma Secondary_Stack_Size}. @node Aspect Scalar_Storage_Order,Aspect Shared,Aspect Secondary_Stack_Size,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-scalar-storage-order}@anchor{154} +@anchor{gnat_rm/implementation_defined_aspects aspect-scalar-storage-order}@anchor{153} @section Aspect Scalar_Storage_Order @geindex Scalar_Storage_Order -This aspect is equivalent to a @ref{155,,attribute Scalar_Storage_Order}. +This aspect is equivalent to a @ref{154,,attribute Scalar_Storage_Order}. @node Aspect Shared,Aspect Simple_Storage_Pool,Aspect Scalar_Storage_Order,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-shared}@anchor{156} +@anchor{gnat_rm/implementation_defined_aspects aspect-shared}@anchor{155} @section Aspect Shared @geindex Shared -This boolean aspect is equivalent to @ref{e5,,pragma Shared} +This boolean aspect is equivalent to @ref{e4,,pragma Shared} and is thus a synonym for aspect @code{Atomic}. @node Aspect Simple_Storage_Pool,Aspect Simple_Storage_Pool_Type,Aspect Shared,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-simple-storage-pool}@anchor{157} +@anchor{gnat_rm/implementation_defined_aspects aspect-simple-storage-pool}@anchor{156} @section Aspect Simple_Storage_Pool @geindex Simple_Storage_Pool -This aspect is equivalent to @ref{ea,,attribute Simple_Storage_Pool}. +This aspect is equivalent to @ref{e9,,attribute Simple_Storage_Pool}. @node Aspect Simple_Storage_Pool_Type,Aspect SPARK_Mode,Aspect Simple_Storage_Pool,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-simple-storage-pool-type}@anchor{158} +@anchor{gnat_rm/implementation_defined_aspects aspect-simple-storage-pool-type}@anchor{157} @section Aspect Simple_Storage_Pool_Type @geindex Simple_Storage_Pool_Type -This boolean aspect is equivalent to @ref{e8,,pragma Simple_Storage_Pool_Type}. +This boolean aspect is equivalent to @ref{e7,,pragma Simple_Storage_Pool_Type}. @node Aspect SPARK_Mode,Aspect Suppress_Debug_Info,Aspect Simple_Storage_Pool_Type,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-spark-mode}@anchor{159} +@anchor{gnat_rm/implementation_defined_aspects aspect-spark-mode}@anchor{158} @section Aspect SPARK_Mode @geindex SPARK_Mode -This aspect is equivalent to @ref{f0,,pragma SPARK_Mode} and +This aspect is equivalent to @ref{ef,,pragma SPARK_Mode} and may be specified for either or both of the specification and body of a subprogram or package. @node Aspect Suppress_Debug_Info,Aspect Suppress_Initialization,Aspect SPARK_Mode,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-suppress-debug-info}@anchor{15a} +@anchor{gnat_rm/implementation_defined_aspects aspect-suppress-debug-info}@anchor{159} @section Aspect Suppress_Debug_Info @geindex Suppress_Debug_Info -This boolean aspect is equivalent to @ref{f8,,pragma Suppress_Debug_Info}. +This boolean aspect is equivalent to @ref{f7,,pragma Suppress_Debug_Info}. @node Aspect Suppress_Initialization,Aspect Test_Case,Aspect Suppress_Debug_Info,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-suppress-initialization}@anchor{15b} +@anchor{gnat_rm/implementation_defined_aspects aspect-suppress-initialization}@anchor{15a} @section Aspect Suppress_Initialization @geindex Suppress_Initialization -This boolean aspect is equivalent to @ref{fc,,pragma Suppress_Initialization}. +This boolean aspect is equivalent to @ref{fb,,pragma Suppress_Initialization}. @node Aspect Test_Case,Aspect Thread_Local_Storage,Aspect Suppress_Initialization,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-test-case}@anchor{15c} +@anchor{gnat_rm/implementation_defined_aspects aspect-test-case}@anchor{15b} @section Aspect Test_Case @geindex Test_Case -This aspect is equivalent to @ref{ff,,pragma Test_Case}. +This aspect is equivalent to @ref{fe,,pragma Test_Case}. @node Aspect Thread_Local_Storage,Aspect Universal_Aliasing,Aspect Test_Case,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-thread-local-storage}@anchor{15d} +@anchor{gnat_rm/implementation_defined_aspects aspect-thread-local-storage}@anchor{15c} @section Aspect Thread_Local_Storage @geindex Thread_Local_Storage -This boolean aspect is equivalent to @ref{101,,pragma Thread_Local_Storage}. +This boolean aspect is equivalent to @ref{100,,pragma Thread_Local_Storage}. @node Aspect Universal_Aliasing,Aspect Universal_Data,Aspect Thread_Local_Storage,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-universal-aliasing}@anchor{15e} +@anchor{gnat_rm/implementation_defined_aspects aspect-universal-aliasing}@anchor{15d} @section Aspect Universal_Aliasing @geindex Universal_Aliasing -This boolean aspect is equivalent to @ref{10b,,pragma Universal_Aliasing}. +This boolean aspect is equivalent to @ref{10a,,pragma Universal_Aliasing}. @node Aspect Universal_Data,Aspect Unmodified,Aspect Universal_Aliasing,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-universal-data}@anchor{15f} +@anchor{gnat_rm/implementation_defined_aspects aspect-universal-data}@anchor{15e} @section Aspect Universal_Data @geindex Universal_Data -This aspect is equivalent to @ref{10d,,pragma Universal_Data}. +This aspect is equivalent to @ref{10c,,pragma Universal_Data}. @node Aspect Unmodified,Aspect Unreferenced,Aspect Universal_Data,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-unmodified}@anchor{160} +@anchor{gnat_rm/implementation_defined_aspects aspect-unmodified}@anchor{15f} @section Aspect Unmodified @geindex Unmodified -This boolean aspect is equivalent to @ref{110,,pragma Unmodified}. +This boolean aspect is equivalent to @ref{10f,,pragma Unmodified}. @node Aspect Unreferenced,Aspect Unreferenced_Objects,Aspect Unmodified,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-unreferenced}@anchor{161} +@anchor{gnat_rm/implementation_defined_aspects aspect-unreferenced}@anchor{160} @section Aspect Unreferenced @geindex Unreferenced -This boolean aspect is equivalent to @ref{111,,pragma Unreferenced}. Note that +This boolean aspect is equivalent to @ref{110,,pragma Unreferenced}. Note that in the case of formal parameters, it is not permitted to have aspects for a formal parameter, so in this case the pragma form must be used. @node Aspect Unreferenced_Objects,Aspect Value_Size,Aspect Unreferenced,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-unreferenced-objects}@anchor{162} +@anchor{gnat_rm/implementation_defined_aspects aspect-unreferenced-objects}@anchor{161} @section Aspect Unreferenced_Objects @geindex Unreferenced_Objects -This boolean aspect is equivalent to @ref{113,,pragma Unreferenced_Objects}. +This boolean aspect is equivalent to @ref{112,,pragma Unreferenced_Objects}. @node Aspect Value_Size,Aspect Volatile_Full_Access,Aspect Unreferenced_Objects,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-value-size}@anchor{163} +@anchor{gnat_rm/implementation_defined_aspects aspect-value-size}@anchor{162} @section Aspect Value_Size @geindex Value_Size -This aspect is equivalent to @ref{164,,attribute Value_Size}. +This aspect is equivalent to @ref{163,,attribute Value_Size}. @node Aspect Volatile_Full_Access,Aspect Volatile_Function,Aspect Value_Size,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-volatile-full-access}@anchor{165} +@anchor{gnat_rm/implementation_defined_aspects aspect-volatile-full-access}@anchor{164} @section Aspect Volatile_Full_Access @geindex Volatile_Full_Access -This boolean aspect is equivalent to @ref{11e,,pragma Volatile_Full_Access}. +This boolean aspect is equivalent to @ref{11d,,pragma Volatile_Full_Access}. @node Aspect Volatile_Function,Aspect Warnings,Aspect Volatile_Full_Access,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-volatile-function}@anchor{166} +@anchor{gnat_rm/implementation_defined_aspects aspect-volatile-function}@anchor{165} @section Aspect Volatile_Function @geindex Volatile_Function -This boolean aspect is equivalent to @ref{120,,pragma Volatile_Function}. +This boolean aspect is equivalent to @ref{11f,,pragma Volatile_Function}. @node Aspect Warnings,,Aspect Volatile_Function,Implementation Defined Aspects -@anchor{gnat_rm/implementation_defined_aspects aspect-warnings}@anchor{167} +@anchor{gnat_rm/implementation_defined_aspects aspect-warnings}@anchor{166} @section Aspect Warnings @geindex Warnings -This aspect is equivalent to the two argument form of @ref{122,,pragma Warnings}, +This aspect is equivalent to the two argument form of @ref{121,,pragma Warnings}, where the first argument is @code{ON} or @code{OFF} and the second argument is the entity. @node Implementation Defined Attributes,Standard and Implementation Defined Restrictions,Implementation Defined Aspects,Top -@anchor{gnat_rm/implementation_defined_attributes doc}@anchor{168}@anchor{gnat_rm/implementation_defined_attributes implementation-defined-attributes}@anchor{8}@anchor{gnat_rm/implementation_defined_attributes id1}@anchor{169} +@anchor{gnat_rm/implementation_defined_attributes doc}@anchor{167}@anchor{gnat_rm/implementation_defined_attributes implementation-defined-attributes}@anchor{8}@anchor{gnat_rm/implementation_defined_attributes id1}@anchor{168} @chapter Implementation Defined Attributes @@ -10260,7 +10242,7 @@ consideration, you should minimize the use of these attributes. @end menu @node Attribute Abort_Signal,Attribute Address_Size,,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-abort-signal}@anchor{16a} +@anchor{gnat_rm/implementation_defined_attributes attribute-abort-signal}@anchor{169} @section Attribute Abort_Signal @@ -10274,7 +10256,7 @@ completely outside the normal semantics of Ada, for a user program to intercept the abort exception). @node Attribute Address_Size,Attribute Asm_Input,Attribute Abort_Signal,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-address-size}@anchor{16b} +@anchor{gnat_rm/implementation_defined_attributes attribute-address-size}@anchor{16a} @section Attribute Address_Size @@ -10290,7 +10272,7 @@ reference to System.Address'Size is nonstatic because Address is a private type. @node Attribute Asm_Input,Attribute Asm_Output,Attribute Address_Size,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-asm-input}@anchor{16c} +@anchor{gnat_rm/implementation_defined_attributes attribute-asm-input}@anchor{16b} @section Attribute Asm_Input @@ -10304,10 +10286,10 @@ to be a static expression, and is the constraint for the parameter, value to be used as the input argument. The possible values for the constant are the same as those used in the RTL, and are dependent on the configuration file used to built the GCC back end. -@ref{16d,,Machine Code Insertions} +@ref{16c,,Machine Code Insertions} @node Attribute Asm_Output,Attribute Atomic_Always_Lock_Free,Attribute Asm_Input,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-asm-output}@anchor{16e} +@anchor{gnat_rm/implementation_defined_attributes attribute-asm-output}@anchor{16d} @section Attribute Asm_Output @@ -10323,10 +10305,10 @@ result. The possible values for constraint are the same as those used in the RTL, and are dependent on the configuration file used to build the GCC back end. If there are no output operands, then this argument may either be omitted, or explicitly given as @code{No_Output_Operands}. -@ref{16d,,Machine Code Insertions} +@ref{16c,,Machine Code Insertions} @node Attribute Atomic_Always_Lock_Free,Attribute Bit,Attribute Asm_Output,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-atomic-always-lock-free}@anchor{16f} +@anchor{gnat_rm/implementation_defined_attributes attribute-atomic-always-lock-free}@anchor{16e} @section Attribute Atomic_Always_Lock_Free @@ -10338,7 +10320,7 @@ and False otherwise. The result indicate whether atomic operations are supported by the target for the given type. @node Attribute Bit,Attribute Bit_Position,Attribute Atomic_Always_Lock_Free,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-bit}@anchor{170} +@anchor{gnat_rm/implementation_defined_attributes attribute-bit}@anchor{16f} @section Attribute Bit @@ -10369,7 +10351,7 @@ This attribute is designed to be compatible with the DEC Ada 83 definition and implementation of the @code{Bit} attribute. @node Attribute Bit_Position,Attribute Code_Address,Attribute Bit,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-bit-position}@anchor{171} +@anchor{gnat_rm/implementation_defined_attributes attribute-bit-position}@anchor{170} @section Attribute Bit_Position @@ -10384,7 +10366,7 @@ type @emph{universal_integer}. The value depends only on the field the containing record @code{R}. @node Attribute Code_Address,Attribute Compiler_Version,Attribute Bit_Position,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-code-address}@anchor{172} +@anchor{gnat_rm/implementation_defined_attributes attribute-code-address}@anchor{171} @section Attribute Code_Address @@ -10427,7 +10409,7 @@ the same value as is returned by the corresponding @code{'Address} attribute. @node Attribute Compiler_Version,Attribute Constrained,Attribute Code_Address,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-compiler-version}@anchor{173} +@anchor{gnat_rm/implementation_defined_attributes attribute-compiler-version}@anchor{172} @section Attribute Compiler_Version @@ -10438,7 +10420,7 @@ prefix) yields a static string identifying the version of the compiler being used to compile the unit containing the attribute reference. @node Attribute Constrained,Attribute Default_Bit_Order,Attribute Compiler_Version,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-constrained}@anchor{174} +@anchor{gnat_rm/implementation_defined_attributes attribute-constrained}@anchor{173} @section Attribute Constrained @@ -10453,7 +10435,7 @@ record type without discriminants is always @code{True}. This usage is compatible with older Ada compilers, including notably DEC Ada. @node Attribute Default_Bit_Order,Attribute Default_Scalar_Storage_Order,Attribute Constrained,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-default-bit-order}@anchor{175} +@anchor{gnat_rm/implementation_defined_attributes attribute-default-bit-order}@anchor{174} @section Attribute Default_Bit_Order @@ -10470,7 +10452,7 @@ as a @code{Pos} value (0 for @code{High_Order_First}, 1 for @code{Default_Bit_Order} in package @code{System}. @node Attribute Default_Scalar_Storage_Order,Attribute Deref,Attribute Default_Bit_Order,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-default-scalar-storage-order}@anchor{176} +@anchor{gnat_rm/implementation_defined_attributes attribute-default-scalar-storage-order}@anchor{175} @section Attribute Default_Scalar_Storage_Order @@ -10487,7 +10469,7 @@ equal to @code{Default_Bit_Order} if unspecified) as a @code{System.Bit_Order} value. This is a static attribute. @node Attribute Deref,Attribute Descriptor_Size,Attribute Default_Scalar_Storage_Order,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-deref}@anchor{177} +@anchor{gnat_rm/implementation_defined_attributes attribute-deref}@anchor{176} @section Attribute Deref @@ -10500,7 +10482,7 @@ a named access-to-@cite{typ} type, except that it yields a variable, so it can b used on the left side of an assignment. @node Attribute Descriptor_Size,Attribute Elaborated,Attribute Deref,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-descriptor-size}@anchor{178} +@anchor{gnat_rm/implementation_defined_attributes attribute-descriptor-size}@anchor{177} @section Attribute Descriptor_Size @@ -10527,7 +10509,7 @@ In the example above, the descriptor contains two values of type a size of 31 bits and an alignment of 4, the descriptor size is @code{2 * Positive'Size + 2} or 64 bits. @node Attribute Elaborated,Attribute Elab_Body,Attribute Descriptor_Size,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-elaborated}@anchor{179} +@anchor{gnat_rm/implementation_defined_attributes attribute-elaborated}@anchor{178} @section Attribute Elaborated @@ -10542,7 +10524,7 @@ units has been completed. An exception is for units which need no elaboration, the value is always False for such units. @node Attribute Elab_Body,Attribute Elab_Spec,Attribute Elaborated,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-elab-body}@anchor{17a} +@anchor{gnat_rm/implementation_defined_attributes attribute-elab-body}@anchor{179} @section Attribute Elab_Body @@ -10558,7 +10540,7 @@ e.g., if it is necessary to do selective re-elaboration to fix some error. @node Attribute Elab_Spec,Attribute Elab_Subp_Body,Attribute Elab_Body,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-elab-spec}@anchor{17b} +@anchor{gnat_rm/implementation_defined_attributes attribute-elab-spec}@anchor{17a} @section Attribute Elab_Spec @@ -10574,7 +10556,7 @@ Ada code, e.g., if it is necessary to do selective re-elaboration to fix some error. @node Attribute Elab_Subp_Body,Attribute Emax,Attribute Elab_Spec,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-elab-subp-body}@anchor{17c} +@anchor{gnat_rm/implementation_defined_attributes attribute-elab-subp-body}@anchor{17b} @section Attribute Elab_Subp_Body @@ -10588,7 +10570,7 @@ elaboration procedure by the binder in CodePeer mode only and is unrecognized otherwise. @node Attribute Emax,Attribute Enabled,Attribute Elab_Subp_Body,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-emax}@anchor{17d} +@anchor{gnat_rm/implementation_defined_attributes attribute-emax}@anchor{17c} @section Attribute Emax @@ -10601,7 +10583,7 @@ the Ada 83 reference manual for an exact description of the semantics of this attribute. @node Attribute Enabled,Attribute Enum_Rep,Attribute Emax,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-enabled}@anchor{17e} +@anchor{gnat_rm/implementation_defined_attributes attribute-enabled}@anchor{17d} @section Attribute Enabled @@ -10625,7 +10607,7 @@ a @code{pragma Suppress} or @code{pragma Unsuppress} before instantiating the package or subprogram, controlling whether the check will be present. @node Attribute Enum_Rep,Attribute Enum_Val,Attribute Enabled,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-enum-rep}@anchor{17f} +@anchor{gnat_rm/implementation_defined_attributes attribute-enum-rep}@anchor{17e} @section Attribute Enum_Rep @@ -10662,7 +10644,7 @@ integer calculation is done at run time, then the call to @code{Enum_Rep} may raise @code{Constraint_Error}. @node Attribute Enum_Val,Attribute Epsilon,Attribute Enum_Rep,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-enum-val}@anchor{180} +@anchor{gnat_rm/implementation_defined_attributes attribute-enum-val}@anchor{17f} @section Attribute Enum_Val @@ -10685,7 +10667,7 @@ absence of an enumeration representation clause. This is a static attribute (i.e., the result is static if the argument is static). @node Attribute Epsilon,Attribute Fast_Math,Attribute Enum_Val,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-epsilon}@anchor{181} +@anchor{gnat_rm/implementation_defined_attributes attribute-epsilon}@anchor{180} @section Attribute Epsilon @@ -10698,7 +10680,7 @@ the Ada 83 reference manual for an exact description of the semantics of this attribute. @node Attribute Fast_Math,Attribute Finalization_Size,Attribute Epsilon,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-fast-math}@anchor{182} +@anchor{gnat_rm/implementation_defined_attributes attribute-fast-math}@anchor{181} @section Attribute Fast_Math @@ -10709,7 +10691,7 @@ prefix) yields a static Boolean value that is True if pragma @code{Fast_Math} is active, and False otherwise. @node Attribute Finalization_Size,Attribute Fixed_Value,Attribute Fast_Math,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-finalization-size}@anchor{183} +@anchor{gnat_rm/implementation_defined_attributes attribute-finalization-size}@anchor{182} @section Attribute Finalization_Size @@ -10727,7 +10709,7 @@ class-wide type whose tag denotes a type with no controlled parts. Note that only heap-allocated objects contain finalization data. @node Attribute Fixed_Value,Attribute From_Any,Attribute Finalization_Size,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-fixed-value}@anchor{184} +@anchor{gnat_rm/implementation_defined_attributes attribute-fixed-value}@anchor{183} @section Attribute Fixed_Value @@ -10754,7 +10736,7 @@ This attribute is primarily intended for use in implementation of the input-output functions for fixed-point values. @node Attribute From_Any,Attribute Has_Access_Values,Attribute Fixed_Value,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-from-any}@anchor{185} +@anchor{gnat_rm/implementation_defined_attributes attribute-from-any}@anchor{184} @section Attribute From_Any @@ -10764,7 +10746,7 @@ This internal attribute is used for the generation of remote subprogram stubs in the context of the Distributed Systems Annex. @node Attribute Has_Access_Values,Attribute Has_Discriminants,Attribute From_Any,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-has-access-values}@anchor{186} +@anchor{gnat_rm/implementation_defined_attributes attribute-has-access-values}@anchor{185} @section Attribute Has_Access_Values @@ -10782,7 +10764,7 @@ definitions. If the attribute is applied to a generic private type, it indicates whether or not the corresponding actual type has access values. @node Attribute Has_Discriminants,Attribute Img,Attribute Has_Access_Values,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-has-discriminants}@anchor{187} +@anchor{gnat_rm/implementation_defined_attributes attribute-has-discriminants}@anchor{186} @section Attribute Has_Discriminants @@ -10798,7 +10780,7 @@ definitions. If the attribute is applied to a generic private type, it indicates whether or not the corresponding actual type has discriminants. @node Attribute Img,Attribute Integer_Value,Attribute Has_Discriminants,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-img}@anchor{188} +@anchor{gnat_rm/implementation_defined_attributes attribute-img}@anchor{187} @section Attribute Img @@ -10828,7 +10810,7 @@ that returns the appropriate string when called. This means that in an instantiation as a function parameter. @node Attribute Integer_Value,Attribute Invalid_Value,Attribute Img,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-integer-value}@anchor{189} +@anchor{gnat_rm/implementation_defined_attributes attribute-integer-value}@anchor{188} @section Attribute Integer_Value @@ -10856,7 +10838,7 @@ This attribute is primarily intended for use in implementation of the standard input-output functions for fixed-point values. @node Attribute Invalid_Value,Attribute Iterable,Attribute Integer_Value,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-invalid-value}@anchor{18a} +@anchor{gnat_rm/implementation_defined_attributes attribute-invalid-value}@anchor{189} @section Attribute Invalid_Value @@ -10870,7 +10852,7 @@ including the ability to modify the value with the binder -Sxx flag and relevant environment variables at run time. @node Attribute Iterable,Attribute Large,Attribute Invalid_Value,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-iterable}@anchor{18b} +@anchor{gnat_rm/implementation_defined_attributes attribute-iterable}@anchor{18a} @section Attribute Iterable @@ -10879,7 +10861,7 @@ relevant environment variables at run time. Equivalent to Aspect Iterable. @node Attribute Large,Attribute Library_Level,Attribute Iterable,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-large}@anchor{18c} +@anchor{gnat_rm/implementation_defined_attributes attribute-large}@anchor{18b} @section Attribute Large @@ -10892,7 +10874,7 @@ the Ada 83 reference manual for an exact description of the semantics of this attribute. @node Attribute Library_Level,Attribute Lock_Free,Attribute Large,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-library-level}@anchor{18d} +@anchor{gnat_rm/implementation_defined_attributes attribute-library-level}@anchor{18c} @section Attribute Library_Level @@ -10918,7 +10900,7 @@ end Gen; @end example @node Attribute Lock_Free,Attribute Loop_Entry,Attribute Library_Level,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-lock-free}@anchor{18e} +@anchor{gnat_rm/implementation_defined_attributes attribute-lock-free}@anchor{18d} @section Attribute Lock_Free @@ -10928,7 +10910,7 @@ end Gen; pragma @code{Lock_Free} applies to P. @node Attribute Loop_Entry,Attribute Machine_Size,Attribute Lock_Free,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-loop-entry}@anchor{18f} +@anchor{gnat_rm/implementation_defined_attributes attribute-loop-entry}@anchor{18e} @section Attribute Loop_Entry @@ -10958,7 +10940,7 @@ entry. This copy is not performed if the loop is not entered, or if the corresponding pragmas are ignored or disabled. @node Attribute Machine_Size,Attribute Mantissa,Attribute Loop_Entry,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-machine-size}@anchor{190} +@anchor{gnat_rm/implementation_defined_attributes attribute-machine-size}@anchor{18f} @section Attribute Machine_Size @@ -10968,7 +10950,7 @@ This attribute is identical to the @code{Object_Size} attribute. It is provided for compatibility with the DEC Ada 83 attribute of this name. @node Attribute Mantissa,Attribute Maximum_Alignment,Attribute Machine_Size,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-mantissa}@anchor{191} +@anchor{gnat_rm/implementation_defined_attributes attribute-mantissa}@anchor{190} @section Attribute Mantissa @@ -10981,7 +10963,7 @@ the Ada 83 reference manual for an exact description of the semantics of this attribute. @node Attribute Maximum_Alignment,Attribute Mechanism_Code,Attribute Mantissa,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-maximum-alignment}@anchor{192}@anchor{gnat_rm/implementation_defined_attributes id2}@anchor{193} +@anchor{gnat_rm/implementation_defined_attributes attribute-maximum-alignment}@anchor{191}@anchor{gnat_rm/implementation_defined_attributes id2}@anchor{192} @section Attribute Maximum_Alignment @@ -10997,7 +10979,7 @@ for an object, guaranteeing that it is properly aligned in all cases. @node Attribute Mechanism_Code,Attribute Null_Parameter,Attribute Maximum_Alignment,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-mechanism-code}@anchor{194} +@anchor{gnat_rm/implementation_defined_attributes attribute-mechanism-code}@anchor{193} @section Attribute Mechanism_Code @@ -11028,7 +11010,7 @@ by reference @end table @node Attribute Null_Parameter,Attribute Object_Size,Attribute Mechanism_Code,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-null-parameter}@anchor{195} +@anchor{gnat_rm/implementation_defined_attributes attribute-null-parameter}@anchor{194} @section Attribute Null_Parameter @@ -11053,7 +11035,7 @@ There is no way of indicating this without the @code{Null_Parameter} attribute. @node Attribute Object_Size,Attribute Old,Attribute Null_Parameter,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-object-size}@anchor{148}@anchor{gnat_rm/implementation_defined_attributes id3}@anchor{196} +@anchor{gnat_rm/implementation_defined_attributes attribute-object-size}@anchor{147}@anchor{gnat_rm/implementation_defined_attributes id3}@anchor{195} @section Attribute Object_Size @@ -11123,7 +11105,7 @@ Similar additional checks are performed in other contexts requiring statically matching subtypes. @node Attribute Old,Attribute Passed_By_Reference,Attribute Object_Size,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-old}@anchor{197} +@anchor{gnat_rm/implementation_defined_attributes attribute-old}@anchor{196} @section Attribute Old @@ -11138,7 +11120,7 @@ definition are allowed under control of implementation defined pragma @code{Unevaluated_Use_Of_Old}. @node Attribute Passed_By_Reference,Attribute Pool_Address,Attribute Old,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-passed-by-reference}@anchor{198} +@anchor{gnat_rm/implementation_defined_attributes attribute-passed-by-reference}@anchor{197} @section Attribute Passed_By_Reference @@ -11154,7 +11136,7 @@ passed by copy in calls. For scalar types, the result is always @code{False} and is static. For non-scalar types, the result is nonstatic. @node Attribute Pool_Address,Attribute Range_Length,Attribute Passed_By_Reference,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-pool-address}@anchor{199} +@anchor{gnat_rm/implementation_defined_attributes attribute-pool-address}@anchor{198} @section Attribute Pool_Address @@ -11179,7 +11161,7 @@ For an object created by @code{new}, @code{Ptr.all'Pool_Address} is what is passed to @code{Allocate} and returned from @code{Deallocate}. @node Attribute Range_Length,Attribute Restriction_Set,Attribute Pool_Address,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-range-length}@anchor{19a} +@anchor{gnat_rm/implementation_defined_attributes attribute-range-length}@anchor{199} @section Attribute Range_Length @@ -11192,7 +11174,7 @@ applied to the index subtype of a one dimensional array always gives the same result as @code{Length} applied to the array itself. @node Attribute Restriction_Set,Attribute Result,Attribute Range_Length,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-restriction-set}@anchor{19b} +@anchor{gnat_rm/implementation_defined_attributes attribute-restriction-set}@anchor{19a} @section Attribute Restriction_Set @@ -11262,7 +11244,7 @@ Restrictions pragma, they are not analyzed semantically, so they do not have a type. @node Attribute Result,Attribute Safe_Emax,Attribute Restriction_Set,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-result}@anchor{19c} +@anchor{gnat_rm/implementation_defined_attributes attribute-result}@anchor{19b} @section Attribute Result @@ -11275,7 +11257,7 @@ For a further discussion of the use of this attribute and examples of its use, see the description of pragma Postcondition. @node Attribute Safe_Emax,Attribute Safe_Large,Attribute Result,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-safe-emax}@anchor{19d} +@anchor{gnat_rm/implementation_defined_attributes attribute-safe-emax}@anchor{19c} @section Attribute Safe_Emax @@ -11288,7 +11270,7 @@ the Ada 83 reference manual for an exact description of the semantics of this attribute. @node Attribute Safe_Large,Attribute Safe_Small,Attribute Safe_Emax,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-safe-large}@anchor{19e} +@anchor{gnat_rm/implementation_defined_attributes attribute-safe-large}@anchor{19d} @section Attribute Safe_Large @@ -11301,7 +11283,7 @@ the Ada 83 reference manual for an exact description of the semantics of this attribute. @node Attribute Safe_Small,Attribute Scalar_Storage_Order,Attribute Safe_Large,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-safe-small}@anchor{19f} +@anchor{gnat_rm/implementation_defined_attributes attribute-safe-small}@anchor{19e} @section Attribute Safe_Small @@ -11314,7 +11296,7 @@ the Ada 83 reference manual for an exact description of the semantics of this attribute. @node Attribute Scalar_Storage_Order,Attribute Simple_Storage_Pool,Attribute Safe_Small,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes id4}@anchor{1a0}@anchor{gnat_rm/implementation_defined_attributes attribute-scalar-storage-order}@anchor{155} +@anchor{gnat_rm/implementation_defined_attributes id4}@anchor{19f}@anchor{gnat_rm/implementation_defined_attributes attribute-scalar-storage-order}@anchor{154} @section Attribute Scalar_Storage_Order @@ -11437,7 +11419,7 @@ Note that debuggers may be unable to display the correct value of scalar components of a type for which the opposite storage order is specified. @node Attribute Simple_Storage_Pool,Attribute Small,Attribute Scalar_Storage_Order,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-simple-storage-pool}@anchor{ea}@anchor{gnat_rm/implementation_defined_attributes id5}@anchor{1a1} +@anchor{gnat_rm/implementation_defined_attributes attribute-simple-storage-pool}@anchor{e9}@anchor{gnat_rm/implementation_defined_attributes id5}@anchor{1a0} @section Attribute Simple_Storage_Pool @@ -11500,7 +11482,7 @@ as defined in section 13.11.2 of the Ada Reference Manual, except that the term @emph{simple storage pool} is substituted for @emph{storage pool}. @node Attribute Small,Attribute Storage_Unit,Attribute Simple_Storage_Pool,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-small}@anchor{1a2} +@anchor{gnat_rm/implementation_defined_attributes attribute-small}@anchor{1a1} @section Attribute Small @@ -11516,7 +11498,7 @@ the Ada 83 reference manual for an exact description of the semantics of this attribute when applied to floating-point types. @node Attribute Storage_Unit,Attribute Stub_Type,Attribute Small,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-storage-unit}@anchor{1a3} +@anchor{gnat_rm/implementation_defined_attributes attribute-storage-unit}@anchor{1a2} @section Attribute Storage_Unit @@ -11526,7 +11508,7 @@ this attribute when applied to floating-point types. prefix) provides the same value as @code{System.Storage_Unit}. @node Attribute Stub_Type,Attribute System_Allocator_Alignment,Attribute Storage_Unit,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-stub-type}@anchor{1a4} +@anchor{gnat_rm/implementation_defined_attributes attribute-stub-type}@anchor{1a3} @section Attribute Stub_Type @@ -11550,7 +11532,7 @@ unit @code{System.Partition_Interface}. Use of this attribute will create an implicit dependency on this unit. @node Attribute System_Allocator_Alignment,Attribute Target_Name,Attribute Stub_Type,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-system-allocator-alignment}@anchor{1a5} +@anchor{gnat_rm/implementation_defined_attributes attribute-system-allocator-alignment}@anchor{1a4} @section Attribute System_Allocator_Alignment @@ -11567,7 +11549,7 @@ with alignment too large or to enable a realignment circuitry if the alignment request is larger than this value. @node Attribute Target_Name,Attribute To_Address,Attribute System_Allocator_Alignment,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-target-name}@anchor{1a6} +@anchor{gnat_rm/implementation_defined_attributes attribute-target-name}@anchor{1a5} @section Attribute Target_Name @@ -11580,7 +11562,7 @@ standard gcc target name without the terminating slash (for example, GNAT 5.0 on windows yields "i586-pc-mingw32msv"). @node Attribute To_Address,Attribute To_Any,Attribute Target_Name,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-to-address}@anchor{1a7} +@anchor{gnat_rm/implementation_defined_attributes attribute-to-address}@anchor{1a6} @section Attribute To_Address @@ -11603,7 +11585,7 @@ modular manner (e.g., -1 means the same as 16#FFFF_FFFF# on a 32 bits machine). @node Attribute To_Any,Attribute Type_Class,Attribute To_Address,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-to-any}@anchor{1a8} +@anchor{gnat_rm/implementation_defined_attributes attribute-to-any}@anchor{1a7} @section Attribute To_Any @@ -11613,7 +11595,7 @@ This internal attribute is used for the generation of remote subprogram stubs in the context of the Distributed Systems Annex. @node Attribute Type_Class,Attribute Type_Key,Attribute To_Any,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-type-class}@anchor{1a9} +@anchor{gnat_rm/implementation_defined_attributes attribute-type-class}@anchor{1a8} @section Attribute Type_Class @@ -11643,7 +11625,7 @@ applies to all concurrent types. This attribute is designed to be compatible with the DEC Ada 83 attribute of the same name. @node Attribute Type_Key,Attribute TypeCode,Attribute Type_Class,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-type-key}@anchor{1aa} +@anchor{gnat_rm/implementation_defined_attributes attribute-type-key}@anchor{1a9} @section Attribute Type_Key @@ -11655,7 +11637,7 @@ about the type or subtype. This provides improved compatibility with other implementations that support this attribute. @node Attribute TypeCode,Attribute Unconstrained_Array,Attribute Type_Key,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-typecode}@anchor{1ab} +@anchor{gnat_rm/implementation_defined_attributes attribute-typecode}@anchor{1aa} @section Attribute TypeCode @@ -11665,7 +11647,7 @@ This internal attribute is used for the generation of remote subprogram stubs in the context of the Distributed Systems Annex. @node Attribute Unconstrained_Array,Attribute Universal_Literal_String,Attribute TypeCode,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-unconstrained-array}@anchor{1ac} +@anchor{gnat_rm/implementation_defined_attributes attribute-unconstrained-array}@anchor{1ab} @section Attribute Unconstrained_Array @@ -11679,7 +11661,7 @@ still static, and yields the result of applying this test to the generic actual. @node Attribute Universal_Literal_String,Attribute Unrestricted_Access,Attribute Unconstrained_Array,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-universal-literal-string}@anchor{1ad} +@anchor{gnat_rm/implementation_defined_attributes attribute-universal-literal-string}@anchor{1ac} @section Attribute Universal_Literal_String @@ -11707,7 +11689,7 @@ end; @end example @node Attribute Unrestricted_Access,Attribute Update,Attribute Universal_Literal_String,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-unrestricted-access}@anchor{1ae} +@anchor{gnat_rm/implementation_defined_attributes attribute-unrestricted-access}@anchor{1ad} @section Attribute Unrestricted_Access @@ -11894,7 +11876,7 @@ In general this is a risky approach. It may appear to "work" but such uses of of GNAT to another, so are best avoided if possible. @node Attribute Update,Attribute Valid_Scalars,Attribute Unrestricted_Access,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-update}@anchor{1af} +@anchor{gnat_rm/implementation_defined_attributes attribute-update}@anchor{1ae} @section Attribute Update @@ -11975,7 +11957,7 @@ A := A'Update ((1, 2) => 20, (3, 4) => 30); which changes element (1,2) to 20 and (3,4) to 30. @node Attribute Valid_Scalars,Attribute VADS_Size,Attribute Update,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-valid-scalars}@anchor{1b0} +@anchor{gnat_rm/implementation_defined_attributes attribute-valid-scalars}@anchor{1af} @section Attribute Valid_Scalars @@ -12009,7 +11991,7 @@ write a function with a single use of the attribute, and then call that function from multiple places. @node Attribute VADS_Size,Attribute Value_Size,Attribute Valid_Scalars,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-vads-size}@anchor{1b1} +@anchor{gnat_rm/implementation_defined_attributes attribute-vads-size}@anchor{1b0} @section Attribute VADS_Size @@ -12029,7 +12011,7 @@ gives the result that would be obtained by applying the attribute to the corresponding type. @node Attribute Value_Size,Attribute Wchar_T_Size,Attribute VADS_Size,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes id6}@anchor{1b2}@anchor{gnat_rm/implementation_defined_attributes attribute-value-size}@anchor{164} +@anchor{gnat_rm/implementation_defined_attributes id6}@anchor{1b1}@anchor{gnat_rm/implementation_defined_attributes attribute-value-size}@anchor{163} @section Attribute Value_Size @@ -12043,7 +12025,7 @@ a value of the given subtype. It is the same as @code{type'Size}, but, unlike @code{Size}, may be set for non-first subtypes. @node Attribute Wchar_T_Size,Attribute Word_Size,Attribute Value_Size,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-wchar-t-size}@anchor{1b3} +@anchor{gnat_rm/implementation_defined_attributes attribute-wchar-t-size}@anchor{1b2} @section Attribute Wchar_T_Size @@ -12055,7 +12037,7 @@ primarily for constructing the definition of this type in package @code{Interfaces.C}. The result is a static constant. @node Attribute Word_Size,,Attribute Wchar_T_Size,Implementation Defined Attributes -@anchor{gnat_rm/implementation_defined_attributes attribute-word-size}@anchor{1b4} +@anchor{gnat_rm/implementation_defined_attributes attribute-word-size}@anchor{1b3} @section Attribute Word_Size @@ -12066,7 +12048,7 @@ prefix) provides the value @code{System.Word_Size}. The result is a static constant. @node Standard and Implementation Defined Restrictions,Implementation Advice,Implementation Defined Attributes,Top -@anchor{gnat_rm/standard_and_implementation_defined_restrictions standard-and-implementation-defined-restrictions}@anchor{9}@anchor{gnat_rm/standard_and_implementation_defined_restrictions doc}@anchor{1b5}@anchor{gnat_rm/standard_and_implementation_defined_restrictions id1}@anchor{1b6} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions standard-and-implementation-defined-restrictions}@anchor{9}@anchor{gnat_rm/standard_and_implementation_defined_restrictions doc}@anchor{1b4}@anchor{gnat_rm/standard_and_implementation_defined_restrictions id1}@anchor{1b5} @chapter Standard and Implementation Defined Restrictions @@ -12095,7 +12077,7 @@ language defined or GNAT-specific, are listed in the following. @end menu @node Partition-Wide Restrictions,Program Unit Level Restrictions,,Standard and Implementation Defined Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions partition-wide-restrictions}@anchor{1b7}@anchor{gnat_rm/standard_and_implementation_defined_restrictions id2}@anchor{1b8} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions partition-wide-restrictions}@anchor{1b6}@anchor{gnat_rm/standard_and_implementation_defined_restrictions id2}@anchor{1b7} @section Partition-Wide Restrictions @@ -12184,7 +12166,7 @@ then all compilation units in the partition must obey the restriction). @end menu @node Immediate_Reclamation,Max_Asynchronous_Select_Nesting,,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions immediate-reclamation}@anchor{1b9} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions immediate-reclamation}@anchor{1b8} @subsection Immediate_Reclamation @@ -12196,7 +12178,7 @@ deallocation, any storage reserved at run time for an object is immediately reclaimed when the object no longer exists. @node Max_Asynchronous_Select_Nesting,Max_Entry_Queue_Length,Immediate_Reclamation,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-asynchronous-select-nesting}@anchor{1ba} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-asynchronous-select-nesting}@anchor{1b9} @subsection Max_Asynchronous_Select_Nesting @@ -12208,7 +12190,7 @@ detected at compile time. Violations of this restriction with values other than zero cause Storage_Error to be raised. @node Max_Entry_Queue_Length,Max_Protected_Entries,Max_Asynchronous_Select_Nesting,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-entry-queue-length}@anchor{1bb} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-entry-queue-length}@anchor{1ba} @subsection Max_Entry_Queue_Length @@ -12229,7 +12211,7 @@ compatibility purposes (and a warning will be generated for its use if warnings on obsolescent features are activated). @node Max_Protected_Entries,Max_Select_Alternatives,Max_Entry_Queue_Length,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-protected-entries}@anchor{1bc} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-protected-entries}@anchor{1bb} @subsection Max_Protected_Entries @@ -12240,7 +12222,7 @@ bounds of every entry family of a protected unit shall be static, or shall be defined by a discriminant of a subtype whose corresponding bound is static. @node Max_Select_Alternatives,Max_Storage_At_Blocking,Max_Protected_Entries,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-select-alternatives}@anchor{1bd} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-select-alternatives}@anchor{1bc} @subsection Max_Select_Alternatives @@ -12249,7 +12231,7 @@ defined by a discriminant of a subtype whose corresponding bound is static. [RM D.7] Specifies the maximum number of alternatives in a selective accept. @node Max_Storage_At_Blocking,Max_Task_Entries,Max_Select_Alternatives,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-storage-at-blocking}@anchor{1be} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-storage-at-blocking}@anchor{1bd} @subsection Max_Storage_At_Blocking @@ -12260,7 +12242,7 @@ Storage_Size that can be retained by a blocked task. A violation of this restriction causes Storage_Error to be raised. @node Max_Task_Entries,Max_Tasks,Max_Storage_At_Blocking,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-task-entries}@anchor{1bf} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-task-entries}@anchor{1be} @subsection Max_Task_Entries @@ -12273,7 +12255,7 @@ defined by a discriminant of a subtype whose corresponding bound is static. @node Max_Tasks,No_Abort_Statements,Max_Task_Entries,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-tasks}@anchor{1c0} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-tasks}@anchor{1bf} @subsection Max_Tasks @@ -12286,7 +12268,7 @@ time. Violations of this restriction with values other than zero cause Storage_Error to be raised. @node No_Abort_Statements,No_Access_Parameter_Allocators,Max_Tasks,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-abort-statements}@anchor{1c1} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-abort-statements}@anchor{1c0} @subsection No_Abort_Statements @@ -12296,7 +12278,7 @@ Storage_Error to be raised. no calls to Task_Identification.Abort_Task. @node No_Access_Parameter_Allocators,No_Access_Subprograms,No_Abort_Statements,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-access-parameter-allocators}@anchor{1c2} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-access-parameter-allocators}@anchor{1c1} @subsection No_Access_Parameter_Allocators @@ -12307,7 +12289,7 @@ occurrences of an allocator as the actual parameter to an access parameter. @node No_Access_Subprograms,No_Allocators,No_Access_Parameter_Allocators,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-access-subprograms}@anchor{1c3} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-access-subprograms}@anchor{1c2} @subsection No_Access_Subprograms @@ -12317,7 +12299,7 @@ parameter. declarations of access-to-subprogram types. @node No_Allocators,No_Anonymous_Allocators,No_Access_Subprograms,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-allocators}@anchor{1c4} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-allocators}@anchor{1c3} @subsection No_Allocators @@ -12327,7 +12309,7 @@ declarations of access-to-subprogram types. occurrences of an allocator. @node No_Anonymous_Allocators,No_Asynchronous_Control,No_Allocators,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-anonymous-allocators}@anchor{1c5} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-anonymous-allocators}@anchor{1c4} @subsection No_Anonymous_Allocators @@ -12337,7 +12319,7 @@ occurrences of an allocator. occurrences of an allocator of anonymous access type. @node No_Asynchronous_Control,No_Calendar,No_Anonymous_Allocators,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-asynchronous-control}@anchor{1c6} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-asynchronous-control}@anchor{1c5} @subsection No_Asynchronous_Control @@ -12347,7 +12329,7 @@ occurrences of an allocator of anonymous access type. dependences on the predefined package Asynchronous_Task_Control. @node No_Calendar,No_Coextensions,No_Asynchronous_Control,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-calendar}@anchor{1c7} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-calendar}@anchor{1c6} @subsection No_Calendar @@ -12357,7 +12339,7 @@ dependences on the predefined package Asynchronous_Task_Control. dependences on package Calendar. @node No_Coextensions,No_Default_Initialization,No_Calendar,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-coextensions}@anchor{1c8} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-coextensions}@anchor{1c7} @subsection No_Coextensions @@ -12367,7 +12349,7 @@ dependences on package Calendar. coextensions. See 3.10.2. @node No_Default_Initialization,No_Delay,No_Coextensions,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-default-initialization}@anchor{1c9} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-default-initialization}@anchor{1c8} @subsection No_Default_Initialization @@ -12384,7 +12366,7 @@ is to prohibit all cases of variables declared without a specific initializer (including the case of OUT scalar parameters). @node No_Delay,No_Dependence,No_Default_Initialization,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-delay}@anchor{1ca} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-delay}@anchor{1c9} @subsection No_Delay @@ -12394,7 +12376,7 @@ initializer (including the case of OUT scalar parameters). delay statements and no semantic dependences on package Calendar. @node No_Dependence,No_Direct_Boolean_Operators,No_Delay,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dependence}@anchor{1cb} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dependence}@anchor{1ca} @subsection No_Dependence @@ -12404,7 +12386,7 @@ delay statements and no semantic dependences on package Calendar. dependences on a library unit. @node No_Direct_Boolean_Operators,No_Dispatch,No_Dependence,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-direct-boolean-operators}@anchor{1cc} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-direct-boolean-operators}@anchor{1cb} @subsection No_Direct_Boolean_Operators @@ -12417,7 +12399,7 @@ protocol requires the use of short-circuit (and then, or else) forms for all composite boolean operations. @node No_Dispatch,No_Dispatching_Calls,No_Direct_Boolean_Operators,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dispatch}@anchor{1cd} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dispatch}@anchor{1cc} @subsection No_Dispatch @@ -12427,7 +12409,7 @@ composite boolean operations. occurrences of @code{T'Class}, for any (tagged) subtype @code{T}. @node No_Dispatching_Calls,No_Dynamic_Attachment,No_Dispatch,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dispatching-calls}@anchor{1ce} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dispatching-calls}@anchor{1cd} @subsection No_Dispatching_Calls @@ -12488,7 +12470,7 @@ end Example; @end example @node No_Dynamic_Attachment,No_Dynamic_Priorities,No_Dispatching_Calls,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dynamic-attachment}@anchor{1cf} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dynamic-attachment}@anchor{1ce} @subsection No_Dynamic_Attachment @@ -12507,7 +12489,7 @@ compatibility purposes (and a warning will be generated for its use if warnings on obsolescent features are activated). @node No_Dynamic_Priorities,No_Entry_Calls_In_Elaboration_Code,No_Dynamic_Attachment,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dynamic-priorities}@anchor{1d0} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dynamic-priorities}@anchor{1cf} @subsection No_Dynamic_Priorities @@ -12516,7 +12498,7 @@ warnings on obsolescent features are activated). [RM D.7] There are no semantic dependencies on the package Dynamic_Priorities. @node No_Entry_Calls_In_Elaboration_Code,No_Enumeration_Maps,No_Dynamic_Priorities,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-entry-calls-in-elaboration-code}@anchor{1d1} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-entry-calls-in-elaboration-code}@anchor{1d0} @subsection No_Entry_Calls_In_Elaboration_Code @@ -12528,7 +12510,7 @@ restriction, the compiler can assume that no code past an accept statement in a task can be executed at elaboration time. @node No_Enumeration_Maps,No_Exception_Handlers,No_Entry_Calls_In_Elaboration_Code,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-enumeration-maps}@anchor{1d2} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-enumeration-maps}@anchor{1d1} @subsection No_Enumeration_Maps @@ -12539,7 +12521,7 @@ enumeration maps are used (that is Image and Value attributes applied to enumeration types). @node No_Exception_Handlers,No_Exception_Propagation,No_Enumeration_Maps,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-exception-handlers}@anchor{1d3} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-exception-handlers}@anchor{1d2} @subsection No_Exception_Handlers @@ -12564,7 +12546,7 @@ statement generated by the compiler). The Line parameter when nonzero represents the line number in the source program where the raise occurs. @node No_Exception_Propagation,No_Exception_Registration,No_Exception_Handlers,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-exception-propagation}@anchor{1d4} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-exception-propagation}@anchor{1d3} @subsection No_Exception_Propagation @@ -12581,7 +12563,7 @@ the package GNAT.Current_Exception is not permitted, and reraise statements (raise with no operand) are not permitted. @node No_Exception_Registration,No_Exceptions,No_Exception_Propagation,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-exception-registration}@anchor{1d5} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-exception-registration}@anchor{1d4} @subsection No_Exception_Registration @@ -12595,7 +12577,7 @@ code is simplified by omitting the otherwise-required global registration of exceptions when they are declared. @node No_Exceptions,No_Finalization,No_Exception_Registration,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-exceptions}@anchor{1d6} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-exceptions}@anchor{1d5} @subsection No_Exceptions @@ -12606,7 +12588,7 @@ raise statements and no exception handlers and also suppresses the generation of language-defined run-time checks. @node No_Finalization,No_Fixed_Point,No_Exceptions,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-finalization}@anchor{1d7} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-finalization}@anchor{1d6} @subsection No_Finalization @@ -12647,7 +12629,7 @@ object or a nested component, either declared on the stack or on the heap. The deallocation of a controlled object no longer finalizes its contents. @node No_Fixed_Point,No_Floating_Point,No_Finalization,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-fixed-point}@anchor{1d8} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-fixed-point}@anchor{1d7} @subsection No_Fixed_Point @@ -12657,7 +12639,7 @@ deallocation of a controlled object no longer finalizes its contents. occurrences of fixed point types and operations. @node No_Floating_Point,No_Implicit_Conditionals,No_Fixed_Point,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-floating-point}@anchor{1d9} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-floating-point}@anchor{1d8} @subsection No_Floating_Point @@ -12667,7 +12649,7 @@ occurrences of fixed point types and operations. occurrences of floating point types and operations. @node No_Implicit_Conditionals,No_Implicit_Dynamic_Code,No_Floating_Point,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-conditionals}@anchor{1da} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-conditionals}@anchor{1d9} @subsection No_Implicit_Conditionals @@ -12683,7 +12665,7 @@ normal manner. Constructs generating implicit conditionals include comparisons of composite objects and the Max/Min attributes. @node No_Implicit_Dynamic_Code,No_Implicit_Heap_Allocations,No_Implicit_Conditionals,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-dynamic-code}@anchor{1db} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-dynamic-code}@anchor{1da} @subsection No_Implicit_Dynamic_Code @@ -12713,7 +12695,7 @@ foreign-language convention; primitive operations of nested tagged types. @node No_Implicit_Heap_Allocations,No_Implicit_Protected_Object_Allocations,No_Implicit_Dynamic_Code,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-heap-allocations}@anchor{1dc} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-heap-allocations}@anchor{1db} @subsection No_Implicit_Heap_Allocations @@ -12722,7 +12704,7 @@ types. [RM D.7] No constructs are allowed to cause implicit heap allocation. @node No_Implicit_Protected_Object_Allocations,No_Implicit_Task_Allocations,No_Implicit_Heap_Allocations,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-protected-object-allocations}@anchor{1dd} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-protected-object-allocations}@anchor{1dc} @subsection No_Implicit_Protected_Object_Allocations @@ -12732,7 +12714,7 @@ types. protected object. @node No_Implicit_Task_Allocations,No_Initialize_Scalars,No_Implicit_Protected_Object_Allocations,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-task-allocations}@anchor{1de} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-task-allocations}@anchor{1dd} @subsection No_Implicit_Task_Allocations @@ -12741,7 +12723,7 @@ protected object. [GNAT] No constructs are allowed to cause implicit heap allocation of a task. @node No_Initialize_Scalars,No_IO,No_Implicit_Task_Allocations,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-initialize-scalars}@anchor{1df} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-initialize-scalars}@anchor{1de} @subsection No_Initialize_Scalars @@ -12753,7 +12735,7 @@ code, and in particular eliminates dummy null initialization routines that are otherwise generated for some record and array types. @node No_IO,No_Local_Allocators,No_Initialize_Scalars,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-io}@anchor{1e0} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-io}@anchor{1df} @subsection No_IO @@ -12764,7 +12746,7 @@ dependences on any of the library units Sequential_IO, Direct_IO, Text_IO, Wide_Text_IO, Wide_Wide_Text_IO, or Stream_IO. @node No_Local_Allocators,No_Local_Protected_Objects,No_IO,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-local-allocators}@anchor{1e1} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-local-allocators}@anchor{1e0} @subsection No_Local_Allocators @@ -12775,7 +12757,7 @@ occurrences of an allocator in subprograms, generic subprograms, tasks, and entry bodies. @node No_Local_Protected_Objects,No_Local_Timing_Events,No_Local_Allocators,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-local-protected-objects}@anchor{1e2} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-local-protected-objects}@anchor{1e1} @subsection No_Local_Protected_Objects @@ -12785,7 +12767,7 @@ and entry bodies. only declared at the library level. @node No_Local_Timing_Events,No_Long_Long_Integers,No_Local_Protected_Objects,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-local-timing-events}@anchor{1e3} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-local-timing-events}@anchor{1e2} @subsection No_Local_Timing_Events @@ -12795,7 +12777,7 @@ only declared at the library level. declared at the library level. @node No_Long_Long_Integers,No_Multiple_Elaboration,No_Local_Timing_Events,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-long-long-integers}@anchor{1e4} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-long-long-integers}@anchor{1e3} @subsection No_Long_Long_Integers @@ -12807,7 +12789,7 @@ implicit base type is Long_Long_Integer, and modular types whose size exceeds Long_Integer'Size. @node No_Multiple_Elaboration,No_Nested_Finalization,No_Long_Long_Integers,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-multiple-elaboration}@anchor{1e5} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-multiple-elaboration}@anchor{1e4} @subsection No_Multiple_Elaboration @@ -12823,7 +12805,7 @@ possible, including non-Ada main programs and Stand Alone libraries, are not permitted and will be diagnosed by the binder. @node No_Nested_Finalization,No_Protected_Type_Allocators,No_Multiple_Elaboration,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-nested-finalization}@anchor{1e6} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-nested-finalization}@anchor{1e5} @subsection No_Nested_Finalization @@ -12832,7 +12814,7 @@ permitted and will be diagnosed by the binder. [RM D.7] All objects requiring finalization are declared at the library level. @node No_Protected_Type_Allocators,No_Protected_Types,No_Nested_Finalization,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-protected-type-allocators}@anchor{1e7} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-protected-type-allocators}@anchor{1e6} @subsection No_Protected_Type_Allocators @@ -12842,7 +12824,7 @@ permitted and will be diagnosed by the binder. expressions that attempt to allocate protected objects. @node No_Protected_Types,No_Recursion,No_Protected_Type_Allocators,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-protected-types}@anchor{1e8} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-protected-types}@anchor{1e7} @subsection No_Protected_Types @@ -12852,7 +12834,7 @@ expressions that attempt to allocate protected objects. declarations of protected types or protected objects. @node No_Recursion,No_Reentrancy,No_Protected_Types,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-recursion}@anchor{1e9} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-recursion}@anchor{1e8} @subsection No_Recursion @@ -12862,7 +12844,7 @@ declarations of protected types or protected objects. part of its execution. @node No_Reentrancy,No_Relative_Delay,No_Recursion,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-reentrancy}@anchor{1ea} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-reentrancy}@anchor{1e9} @subsection No_Reentrancy @@ -12872,7 +12854,7 @@ part of its execution. two tasks at the same time. @node No_Relative_Delay,No_Requeue_Statements,No_Reentrancy,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-relative-delay}@anchor{1eb} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-relative-delay}@anchor{1ea} @subsection No_Relative_Delay @@ -12883,7 +12865,7 @@ relative statements and prevents expressions such as @code{delay 1.23;} from appearing in source code. @node No_Requeue_Statements,No_Secondary_Stack,No_Relative_Delay,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-requeue-statements}@anchor{1ec} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-requeue-statements}@anchor{1eb} @subsection No_Requeue_Statements @@ -12901,7 +12883,7 @@ compatibility purposes (and a warning will be generated for its use if warnings on oNobsolescent features are activated). @node No_Secondary_Stack,No_Select_Statements,No_Requeue_Statements,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-secondary-stack}@anchor{1ed} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-secondary-stack}@anchor{1ec} @subsection No_Secondary_Stack @@ -12914,7 +12896,7 @@ stack is used to implement functions returning unconstrained objects secondary stacks for tasks (excluding the environment task) at run time. @node No_Select_Statements,No_Specific_Termination_Handlers,No_Secondary_Stack,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-select-statements}@anchor{1ee} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-select-statements}@anchor{1ed} @subsection No_Select_Statements @@ -12924,7 +12906,7 @@ secondary stacks for tasks (excluding the environment task) at run time. kind are permitted, that is the keyword @code{select} may not appear. @node No_Specific_Termination_Handlers,No_Specification_of_Aspect,No_Select_Statements,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-specific-termination-handlers}@anchor{1ef} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-specific-termination-handlers}@anchor{1ee} @subsection No_Specific_Termination_Handlers @@ -12934,7 +12916,7 @@ kind are permitted, that is the keyword @code{select} may not appear. or to Ada.Task_Termination.Specific_Handler. @node No_Specification_of_Aspect,No_Standard_Allocators_After_Elaboration,No_Specific_Termination_Handlers,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-specification-of-aspect}@anchor{1f0} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-specification-of-aspect}@anchor{1ef} @subsection No_Specification_of_Aspect @@ -12945,7 +12927,7 @@ specification, attribute definition clause, or pragma is given for a given aspect. @node No_Standard_Allocators_After_Elaboration,No_Standard_Storage_Pools,No_Specification_of_Aspect,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-standard-allocators-after-elaboration}@anchor{1f1} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-standard-allocators-after-elaboration}@anchor{1f0} @subsection No_Standard_Allocators_After_Elaboration @@ -12957,7 +12939,7 @@ library items of the partition has completed. Otherwise, Storage_Error is raised. @node No_Standard_Storage_Pools,No_Stream_Optimizations,No_Standard_Allocators_After_Elaboration,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-standard-storage-pools}@anchor{1f2} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-standard-storage-pools}@anchor{1f1} @subsection No_Standard_Storage_Pools @@ -12969,7 +12951,7 @@ have an explicit Storage_Pool attribute defined specifying a user-defined storage pool. @node No_Stream_Optimizations,No_Streams,No_Standard_Storage_Pools,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-stream-optimizations}@anchor{1f3} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-stream-optimizations}@anchor{1f2} @subsection No_Stream_Optimizations @@ -12982,7 +12964,7 @@ due to their superior performance. When this restriction is in effect, the compiler performs all IO operations on a per-character basis. @node No_Streams,No_Task_Allocators,No_Stream_Optimizations,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-streams}@anchor{1f4} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-streams}@anchor{1f3} @subsection No_Streams @@ -13003,7 +12985,7 @@ unit declaring a tagged type should be compiled with the restriction, though this is not required. @node No_Task_Allocators,No_Task_At_Interrupt_Priority,No_Streams,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-allocators}@anchor{1f5} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-allocators}@anchor{1f4} @subsection No_Task_Allocators @@ -13013,7 +12995,7 @@ though this is not required. or types containing task subcomponents. @node No_Task_At_Interrupt_Priority,No_Task_Attributes_Package,No_Task_Allocators,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-at-interrupt-priority}@anchor{1f6} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-at-interrupt-priority}@anchor{1f5} @subsection No_Task_At_Interrupt_Priority @@ -13025,7 +13007,7 @@ a consequence, the tasks are always created with a priority below that an interrupt priority. @node No_Task_Attributes_Package,No_Task_Hierarchy,No_Task_At_Interrupt_Priority,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-attributes-package}@anchor{1f7} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-attributes-package}@anchor{1f6} @subsection No_Task_Attributes_Package @@ -13042,7 +13024,7 @@ compatibility purposes (and a warning will be generated for its use if warnings on obsolescent features are activated). @node No_Task_Hierarchy,No_Task_Termination,No_Task_Attributes_Package,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-hierarchy}@anchor{1f8} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-hierarchy}@anchor{1f7} @subsection No_Task_Hierarchy @@ -13052,7 +13034,7 @@ warnings on obsolescent features are activated). directly on the environment task of the partition. @node No_Task_Termination,No_Tasking,No_Task_Hierarchy,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-termination}@anchor{1f9} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-termination}@anchor{1f8} @subsection No_Task_Termination @@ -13061,7 +13043,7 @@ directly on the environment task of the partition. [RM D.7] Tasks that terminate are erroneous. @node No_Tasking,No_Terminate_Alternatives,No_Task_Termination,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-tasking}@anchor{1fa} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-tasking}@anchor{1f9} @subsection No_Tasking @@ -13074,7 +13056,7 @@ and cause an error message to be output either by the compiler or binder. @node No_Terminate_Alternatives,No_Unchecked_Access,No_Tasking,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-terminate-alternatives}@anchor{1fb} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-terminate-alternatives}@anchor{1fa} @subsection No_Terminate_Alternatives @@ -13083,7 +13065,7 @@ binder. [RM D.7] There are no selective accepts with terminate alternatives. @node No_Unchecked_Access,No_Unchecked_Conversion,No_Terminate_Alternatives,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-unchecked-access}@anchor{1fc} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-unchecked-access}@anchor{1fb} @subsection No_Unchecked_Access @@ -13093,7 +13075,7 @@ binder. occurrences of the Unchecked_Access attribute. @node No_Unchecked_Conversion,No_Unchecked_Deallocation,No_Unchecked_Access,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-unchecked-conversion}@anchor{1fd} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-unchecked-conversion}@anchor{1fc} @subsection No_Unchecked_Conversion @@ -13103,7 +13085,7 @@ occurrences of the Unchecked_Access attribute. dependences on the predefined generic function Unchecked_Conversion. @node No_Unchecked_Deallocation,No_Use_Of_Entity,No_Unchecked_Conversion,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-unchecked-deallocation}@anchor{1fe} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-unchecked-deallocation}@anchor{1fd} @subsection No_Unchecked_Deallocation @@ -13113,7 +13095,7 @@ dependences on the predefined generic function Unchecked_Conversion. dependences on the predefined generic procedure Unchecked_Deallocation. @node No_Use_Of_Entity,Pure_Barriers,No_Unchecked_Deallocation,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-use-of-entity}@anchor{1ff} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-use-of-entity}@anchor{1fe} @subsection No_Use_Of_Entity @@ -13133,7 +13115,7 @@ No_Use_Of_Entity => Ada.Text_IO.Put_Line @end example @node Pure_Barriers,Simple_Barriers,No_Use_Of_Entity,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions pure-barriers}@anchor{200} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions pure-barriers}@anchor{1ff} @subsection Pure_Barriers @@ -13184,7 +13166,7 @@ but still ensures absence of side effects, exceptions, and recursion during the evaluation of the barriers. @node Simple_Barriers,Static_Priorities,Pure_Barriers,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions simple-barriers}@anchor{201} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions simple-barriers}@anchor{200} @subsection Simple_Barriers @@ -13203,7 +13185,7 @@ compatibility purposes (and a warning will be generated for its use if warnings on obsolescent features are activated). @node Static_Priorities,Static_Storage_Size,Simple_Barriers,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions static-priorities}@anchor{202} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions static-priorities}@anchor{201} @subsection Static_Priorities @@ -13214,7 +13196,7 @@ are static, and that there are no dependences on the package @code{Ada.Dynamic_Priorities}. @node Static_Storage_Size,,Static_Priorities,Partition-Wide Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions static-storage-size}@anchor{203} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions static-storage-size}@anchor{202} @subsection Static_Storage_Size @@ -13224,7 +13206,7 @@ are static, and that there are no dependences on the package in a Storage_Size pragma or attribute definition clause is static. @node Program Unit Level Restrictions,,Partition-Wide Restrictions,Standard and Implementation Defined Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions program-unit-level-restrictions}@anchor{204}@anchor{gnat_rm/standard_and_implementation_defined_restrictions id3}@anchor{205} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions program-unit-level-restrictions}@anchor{203}@anchor{gnat_rm/standard_and_implementation_defined_restrictions id3}@anchor{204} @section Program Unit Level Restrictions @@ -13254,7 +13236,7 @@ other compilation units in the partition. @end menu @node No_Elaboration_Code,No_Dynamic_Sized_Objects,,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-elaboration-code}@anchor{206} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-elaboration-code}@anchor{205} @subsection No_Elaboration_Code @@ -13310,7 +13292,7 @@ associated with the unit. This counter is typically used to check for access before elaboration and to control multiple elaboration attempts. @node No_Dynamic_Sized_Objects,No_Entry_Queue,No_Elaboration_Code,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dynamic-sized-objects}@anchor{207} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dynamic-sized-objects}@anchor{206} @subsection No_Dynamic_Sized_Objects @@ -13328,7 +13310,7 @@ access discriminants. It is often a good idea to combine this restriction with No_Secondary_Stack. @node No_Entry_Queue,No_Implementation_Aspect_Specifications,No_Dynamic_Sized_Objects,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-entry-queue}@anchor{208} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-entry-queue}@anchor{207} @subsection No_Entry_Queue @@ -13341,7 +13323,7 @@ checked at compile time. A program execution is erroneous if an attempt is made to queue a second task on such an entry. @node No_Implementation_Aspect_Specifications,No_Implementation_Attributes,No_Entry_Queue,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-aspect-specifications}@anchor{209} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-aspect-specifications}@anchor{208} @subsection No_Implementation_Aspect_Specifications @@ -13352,7 +13334,7 @@ GNAT-defined aspects are present. With this restriction, the only aspects that can be used are those defined in the Ada Reference Manual. @node No_Implementation_Attributes,No_Implementation_Identifiers,No_Implementation_Aspect_Specifications,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-attributes}@anchor{20a} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-attributes}@anchor{209} @subsection No_Implementation_Attributes @@ -13364,7 +13346,7 @@ attributes that can be used are those defined in the Ada Reference Manual. @node No_Implementation_Identifiers,No_Implementation_Pragmas,No_Implementation_Attributes,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-identifiers}@anchor{20b} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-identifiers}@anchor{20a} @subsection No_Implementation_Identifiers @@ -13375,7 +13357,7 @@ implementation-defined identifiers (marked with pragma Implementation_Defined) occur within language-defined packages. @node No_Implementation_Pragmas,No_Implementation_Restrictions,No_Implementation_Identifiers,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-pragmas}@anchor{20c} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-pragmas}@anchor{20b} @subsection No_Implementation_Pragmas @@ -13386,7 +13368,7 @@ GNAT-defined pragmas are present. With this restriction, the only pragmas that can be used are those defined in the Ada Reference Manual. @node No_Implementation_Restrictions,No_Implementation_Units,No_Implementation_Pragmas,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-restrictions}@anchor{20d} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-restrictions}@anchor{20c} @subsection No_Implementation_Restrictions @@ -13398,7 +13380,7 @@ are present. With this restriction, the only other restriction identifiers that can be used are those defined in the Ada Reference Manual. @node No_Implementation_Units,No_Implicit_Aliasing,No_Implementation_Restrictions,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-units}@anchor{20e} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-units}@anchor{20d} @subsection No_Implementation_Units @@ -13409,7 +13391,7 @@ mention in the context clause of any implementation-defined descendants of packages Ada, Interfaces, or System. @node No_Implicit_Aliasing,No_Implicit_Loops,No_Implementation_Units,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-aliasing}@anchor{20f} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-aliasing}@anchor{20e} @subsection No_Implicit_Aliasing @@ -13424,7 +13406,7 @@ to be aliased, and in such cases, it can always be replaced by the standard attribute Unchecked_Access which is preferable. @node No_Implicit_Loops,No_Obsolescent_Features,No_Implicit_Aliasing,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-loops}@anchor{210} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-loops}@anchor{20f} @subsection No_Implicit_Loops @@ -13441,7 +13423,7 @@ arrays larger than about 5000 scalar components. Note that if this restriction is set in the spec of a package, it will not apply to its body. @node No_Obsolescent_Features,No_Wide_Characters,No_Implicit_Loops,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-obsolescent-features}@anchor{211} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-obsolescent-features}@anchor{210} @subsection No_Obsolescent_Features @@ -13451,7 +13433,7 @@ is set in the spec of a package, it will not apply to its body. features are used, as defined in Annex J of the Ada Reference Manual. @node No_Wide_Characters,Static_Dispatch_Tables,No_Obsolescent_Features,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-wide-characters}@anchor{212} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-wide-characters}@anchor{211} @subsection No_Wide_Characters @@ -13465,7 +13447,7 @@ appear in the program (that is literals representing characters not in type @code{Character}). @node Static_Dispatch_Tables,SPARK_05,No_Wide_Characters,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions static-dispatch-tables}@anchor{213} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions static-dispatch-tables}@anchor{212} @subsection Static_Dispatch_Tables @@ -13475,7 +13457,7 @@ type @code{Character}). associated with dispatch tables can be placed in read-only memory. @node SPARK_05,,Static_Dispatch_Tables,Program Unit Level Restrictions -@anchor{gnat_rm/standard_and_implementation_defined_restrictions spark-05}@anchor{214} +@anchor{gnat_rm/standard_and_implementation_defined_restrictions spark-05}@anchor{213} @subsection SPARK_05 @@ -13849,7 +13831,7 @@ violations will be reported for constructs forbidden in SPARK 95, instead of SPARK 2005. @node Implementation Advice,Implementation Defined Characteristics,Standard and Implementation Defined Restrictions,Top -@anchor{gnat_rm/implementation_advice doc}@anchor{215}@anchor{gnat_rm/implementation_advice implementation-advice}@anchor{a}@anchor{gnat_rm/implementation_advice id1}@anchor{216} +@anchor{gnat_rm/implementation_advice doc}@anchor{214}@anchor{gnat_rm/implementation_advice implementation-advice}@anchor{a}@anchor{gnat_rm/implementation_advice id1}@anchor{215} @chapter Implementation Advice @@ -13946,7 +13928,7 @@ case the text describes what GNAT does and why. @end menu @node RM 1 1 3 20 Error Detection,RM 1 1 3 31 Child Units,,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-1-1-3-20-error-detection}@anchor{217} +@anchor{gnat_rm/implementation_advice rm-1-1-3-20-error-detection}@anchor{216} @section RM 1.1.3(20): Error Detection @@ -13963,7 +13945,7 @@ or diagnosed at compile time. @geindex Child Units @node RM 1 1 3 31 Child Units,RM 1 1 5 12 Bounded Errors,RM 1 1 3 20 Error Detection,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-1-1-3-31-child-units}@anchor{218} +@anchor{gnat_rm/implementation_advice rm-1-1-3-31-child-units}@anchor{217} @section RM 1.1.3(31): Child Units @@ -13979,7 +13961,7 @@ Followed. @geindex Bounded errors @node RM 1 1 5 12 Bounded Errors,RM 2 8 16 Pragmas,RM 1 1 3 31 Child Units,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-1-1-5-12-bounded-errors}@anchor{219} +@anchor{gnat_rm/implementation_advice rm-1-1-5-12-bounded-errors}@anchor{218} @section RM 1.1.5(12): Bounded Errors @@ -13996,7 +13978,7 @@ runtime. @geindex Pragmas @node RM 2 8 16 Pragmas,RM 2 8 17-19 Pragmas,RM 1 1 5 12 Bounded Errors,Implementation Advice -@anchor{gnat_rm/implementation_advice id2}@anchor{21a}@anchor{gnat_rm/implementation_advice rm-2-8-16-pragmas}@anchor{21b} +@anchor{gnat_rm/implementation_advice id2}@anchor{219}@anchor{gnat_rm/implementation_advice rm-2-8-16-pragmas}@anchor{21a} @section RM 2.8(16): Pragmas @@ -14109,7 +14091,7 @@ that this advice not be followed. For details see @ref{7,,Implementation Defined Pragmas}. @node RM 2 8 17-19 Pragmas,RM 3 5 2 5 Alternative Character Sets,RM 2 8 16 Pragmas,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-2-8-17-19-pragmas}@anchor{21c} +@anchor{gnat_rm/implementation_advice rm-2-8-17-19-pragmas}@anchor{21b} @section RM 2.8(17-19): Pragmas @@ -14130,14 +14112,14 @@ replacing @code{library_items}." @end itemize @end quotation -See @ref{21b,,RM 2.8(16); Pragmas}. +See @ref{21a,,RM 2.8(16); Pragmas}. @geindex Character Sets @geindex Alternative Character Sets @node RM 3 5 2 5 Alternative Character Sets,RM 3 5 4 28 Integer Types,RM 2 8 17-19 Pragmas,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-3-5-2-5-alternative-character-sets}@anchor{21d} +@anchor{gnat_rm/implementation_advice rm-3-5-2-5-alternative-character-sets}@anchor{21c} @section RM 3.5.2(5): Alternative Character Sets @@ -14165,7 +14147,7 @@ there is no such restriction. @geindex Integer types @node RM 3 5 4 28 Integer Types,RM 3 5 4 29 Integer Types,RM 3 5 2 5 Alternative Character Sets,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-3-5-4-28-integer-types}@anchor{21e} +@anchor{gnat_rm/implementation_advice rm-3-5-4-28-integer-types}@anchor{21d} @section RM 3.5.4(28): Integer Types @@ -14184,7 +14166,7 @@ are supported for convenient interface to C, and so that all hardware types of the machine are easily available. @node RM 3 5 4 29 Integer Types,RM 3 5 5 8 Enumeration Values,RM 3 5 4 28 Integer Types,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-3-5-4-29-integer-types}@anchor{21f} +@anchor{gnat_rm/implementation_advice rm-3-5-4-29-integer-types}@anchor{21e} @section RM 3.5.4(29): Integer Types @@ -14200,7 +14182,7 @@ Followed. @geindex Enumeration values @node RM 3 5 5 8 Enumeration Values,RM 3 5 7 17 Float Types,RM 3 5 4 29 Integer Types,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-3-5-5-8-enumeration-values}@anchor{220} +@anchor{gnat_rm/implementation_advice rm-3-5-5-8-enumeration-values}@anchor{21f} @section RM 3.5.5(8): Enumeration Values @@ -14220,7 +14202,7 @@ Followed. @geindex Float types @node RM 3 5 7 17 Float Types,RM 3 6 2 11 Multidimensional Arrays,RM 3 5 5 8 Enumeration Values,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-3-5-7-17-float-types}@anchor{221} +@anchor{gnat_rm/implementation_advice rm-3-5-7-17-float-types}@anchor{220} @section RM 3.5.7(17): Float Types @@ -14250,7 +14232,7 @@ since this is a software rather than a hardware format. @geindex multidimensional @node RM 3 6 2 11 Multidimensional Arrays,RM 9 6 30-31 Duration'Small,RM 3 5 7 17 Float Types,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-3-6-2-11-multidimensional-arrays}@anchor{222} +@anchor{gnat_rm/implementation_advice rm-3-6-2-11-multidimensional-arrays}@anchor{221} @section RM 3.6.2(11): Multidimensional Arrays @@ -14268,7 +14250,7 @@ Followed. @geindex Duration'Small @node RM 9 6 30-31 Duration'Small,RM 10 2 1 12 Consistent Representation,RM 3 6 2 11 Multidimensional Arrays,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-9-6-30-31-duration-small}@anchor{223} +@anchor{gnat_rm/implementation_advice rm-9-6-30-31-duration-small}@anchor{222} @section RM 9.6(30-31): Duration'Small @@ -14289,7 +14271,7 @@ it need not be the same time base as used for @code{Calendar.Clock}." Followed. @node RM 10 2 1 12 Consistent Representation,RM 11 4 1 19 Exception Information,RM 9 6 30-31 Duration'Small,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-10-2-1-12-consistent-representation}@anchor{224} +@anchor{gnat_rm/implementation_advice rm-10-2-1-12-consistent-representation}@anchor{223} @section RM 10.2.1(12): Consistent Representation @@ -14311,7 +14293,7 @@ advice without severely impacting efficiency of execution. @geindex Exception information @node RM 11 4 1 19 Exception Information,RM 11 5 28 Suppression of Checks,RM 10 2 1 12 Consistent Representation,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-11-4-1-19-exception-information}@anchor{225} +@anchor{gnat_rm/implementation_advice rm-11-4-1-19-exception-information}@anchor{224} @section RM 11.4.1(19): Exception Information @@ -14342,7 +14324,7 @@ Pragma @code{Discard_Names}. @geindex suppression of @node RM 11 5 28 Suppression of Checks,RM 13 1 21-24 Representation Clauses,RM 11 4 1 19 Exception Information,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-11-5-28-suppression-of-checks}@anchor{226} +@anchor{gnat_rm/implementation_advice rm-11-5-28-suppression-of-checks}@anchor{225} @section RM 11.5(28): Suppression of Checks @@ -14357,7 +14339,7 @@ Followed. @geindex Representation clauses @node RM 13 1 21-24 Representation Clauses,RM 13 2 6-8 Packed Types,RM 11 5 28 Suppression of Checks,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-1-21-24-representation-clauses}@anchor{227} +@anchor{gnat_rm/implementation_advice rm-13-1-21-24-representation-clauses}@anchor{226} @section RM 13.1 (21-24): Representation Clauses @@ -14406,7 +14388,7 @@ Followed. @geindex Packed types @node RM 13 2 6-8 Packed Types,RM 13 3 14-19 Address Clauses,RM 13 1 21-24 Representation Clauses,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-2-6-8-packed-types}@anchor{228} +@anchor{gnat_rm/implementation_advice rm-13-2-6-8-packed-types}@anchor{227} @section RM 13.2(6-8): Packed Types @@ -14445,7 +14427,7 @@ Followed. @geindex Address clauses @node RM 13 3 14-19 Address Clauses,RM 13 3 29-35 Alignment Clauses,RM 13 2 6-8 Packed Types,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-3-14-19-address-clauses}@anchor{229} +@anchor{gnat_rm/implementation_advice rm-13-3-14-19-address-clauses}@anchor{228} @section RM 13.3(14-19): Address Clauses @@ -14498,7 +14480,7 @@ Followed. @geindex Alignment clauses @node RM 13 3 29-35 Alignment Clauses,RM 13 3 42-43 Size Clauses,RM 13 3 14-19 Address Clauses,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-3-29-35-alignment-clauses}@anchor{22a} +@anchor{gnat_rm/implementation_advice rm-13-3-29-35-alignment-clauses}@anchor{229} @section RM 13.3(29-35): Alignment Clauses @@ -14555,7 +14537,7 @@ Followed. @geindex Size clauses @node RM 13 3 42-43 Size Clauses,RM 13 3 50-56 Size Clauses,RM 13 3 29-35 Alignment Clauses,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-3-42-43-size-clauses}@anchor{22b} +@anchor{gnat_rm/implementation_advice rm-13-3-42-43-size-clauses}@anchor{22a} @section RM 13.3(42-43): Size Clauses @@ -14573,7 +14555,7 @@ object's @code{Alignment} (if the @code{Alignment} is nonzero)." Followed. @node RM 13 3 50-56 Size Clauses,RM 13 3 71-73 Component Size Clauses,RM 13 3 42-43 Size Clauses,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-3-50-56-size-clauses}@anchor{22c} +@anchor{gnat_rm/implementation_advice rm-13-3-50-56-size-clauses}@anchor{22b} @section RM 13.3(50-56): Size Clauses @@ -14624,7 +14606,7 @@ Followed. @geindex Component_Size clauses @node RM 13 3 71-73 Component Size Clauses,RM 13 4 9-10 Enumeration Representation Clauses,RM 13 3 50-56 Size Clauses,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-3-71-73-component-size-clauses}@anchor{22d} +@anchor{gnat_rm/implementation_advice rm-13-3-71-73-component-size-clauses}@anchor{22c} @section RM 13.3(71-73): Component Size Clauses @@ -14658,7 +14640,7 @@ Followed. @geindex enumeration @node RM 13 4 9-10 Enumeration Representation Clauses,RM 13 5 1 17-22 Record Representation Clauses,RM 13 3 71-73 Component Size Clauses,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-4-9-10-enumeration-representation-clauses}@anchor{22e} +@anchor{gnat_rm/implementation_advice rm-13-4-9-10-enumeration-representation-clauses}@anchor{22d} @section RM 13.4(9-10): Enumeration Representation Clauses @@ -14680,7 +14662,7 @@ Followed. @geindex records @node RM 13 5 1 17-22 Record Representation Clauses,RM 13 5 2 5 Storage Place Attributes,RM 13 4 9-10 Enumeration Representation Clauses,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-5-1-17-22-record-representation-clauses}@anchor{22f} +@anchor{gnat_rm/implementation_advice rm-13-5-1-17-22-record-representation-clauses}@anchor{22e} @section RM 13.5.1(17-22): Record Representation Clauses @@ -14740,7 +14722,7 @@ and all mentioned features are implemented. @geindex Storage place attributes @node RM 13 5 2 5 Storage Place Attributes,RM 13 5 3 7-8 Bit Ordering,RM 13 5 1 17-22 Record Representation Clauses,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-5-2-5-storage-place-attributes}@anchor{230} +@anchor{gnat_rm/implementation_advice rm-13-5-2-5-storage-place-attributes}@anchor{22f} @section RM 13.5.2(5): Storage Place Attributes @@ -14760,7 +14742,7 @@ Followed. There are no such components in GNAT. @geindex Bit ordering @node RM 13 5 3 7-8 Bit Ordering,RM 13 7 37 Address as Private,RM 13 5 2 5 Storage Place Attributes,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-5-3-7-8-bit-ordering}@anchor{231} +@anchor{gnat_rm/implementation_advice rm-13-5-3-7-8-bit-ordering}@anchor{230} @section RM 13.5.3(7-8): Bit Ordering @@ -14780,7 +14762,7 @@ Thus non-default bit ordering is not supported. @geindex as private type @node RM 13 7 37 Address as Private,RM 13 7 1 16 Address Operations,RM 13 5 3 7-8 Bit Ordering,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-7-37-address-as-private}@anchor{232} +@anchor{gnat_rm/implementation_advice rm-13-7-37-address-as-private}@anchor{231} @section RM 13.7(37): Address as Private @@ -14798,7 +14780,7 @@ Followed. @geindex operations of @node RM 13 7 1 16 Address Operations,RM 13 9 14-17 Unchecked Conversion,RM 13 7 37 Address as Private,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-7-1-16-address-operations}@anchor{233} +@anchor{gnat_rm/implementation_advice rm-13-7-1-16-address-operations}@anchor{232} @section RM 13.7.1(16): Address Operations @@ -14816,7 +14798,7 @@ operation raises @code{Program_Error}, since all operations make sense. @geindex Unchecked conversion @node RM 13 9 14-17 Unchecked Conversion,RM 13 11 23-25 Implicit Heap Usage,RM 13 7 1 16 Address Operations,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-9-14-17-unchecked-conversion}@anchor{234} +@anchor{gnat_rm/implementation_advice rm-13-9-14-17-unchecked-conversion}@anchor{233} @section RM 13.9(14-17): Unchecked Conversion @@ -14860,7 +14842,7 @@ Followed. @geindex implicit @node RM 13 11 23-25 Implicit Heap Usage,RM 13 11 2 17 Unchecked Deallocation,RM 13 9 14-17 Unchecked Conversion,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-11-23-25-implicit-heap-usage}@anchor{235} +@anchor{gnat_rm/implementation_advice rm-13-11-23-25-implicit-heap-usage}@anchor{234} @section RM 13.11(23-25): Implicit Heap Usage @@ -14911,7 +14893,7 @@ Followed. @geindex Unchecked deallocation @node RM 13 11 2 17 Unchecked Deallocation,RM 13 13 2 1 6 Stream Oriented Attributes,RM 13 11 23-25 Implicit Heap Usage,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-11-2-17-unchecked-deallocation}@anchor{236} +@anchor{gnat_rm/implementation_advice rm-13-11-2-17-unchecked-deallocation}@anchor{235} @section RM 13.11.2(17): Unchecked Deallocation @@ -14926,7 +14908,7 @@ Followed. @geindex Stream oriented attributes @node RM 13 13 2 1 6 Stream Oriented Attributes,RM A 1 52 Names of Predefined Numeric Types,RM 13 11 2 17 Unchecked Deallocation,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-13-13-2-1-6-stream-oriented-attributes}@anchor{237} +@anchor{gnat_rm/implementation_advice rm-13-13-2-1-6-stream-oriented-attributes}@anchor{236} @section RM 13.13.2(1.6): Stream Oriented Attributes @@ -14981,7 +14963,7 @@ the @emph{GNAT and Libraries} section of the @cite{GNAT User's Guide}. @end itemize @node RM A 1 52 Names of Predefined Numeric Types,RM A 3 2 49 Ada Characters Handling,RM 13 13 2 1 6 Stream Oriented Attributes,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-a-1-52-names-of-predefined-numeric-types}@anchor{238} +@anchor{gnat_rm/implementation_advice rm-a-1-52-names-of-predefined-numeric-types}@anchor{237} @section RM A.1(52): Names of Predefined Numeric Types @@ -14999,7 +14981,7 @@ Followed. @geindex Ada.Characters.Handling @node RM A 3 2 49 Ada Characters Handling,RM A 4 4 106 Bounded-Length String Handling,RM A 1 52 Names of Predefined Numeric Types,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-a-3-2-49-ada-characters-handling}@anchor{239} +@anchor{gnat_rm/implementation_advice rm-a-3-2-49-ada-characters-handling}@anchor{238} @section RM A.3.2(49): @code{Ada.Characters.Handling} @@ -15016,7 +14998,7 @@ Followed. GNAT provides no such localized definitions. @geindex Bounded-length strings @node RM A 4 4 106 Bounded-Length String Handling,RM A 5 2 46-47 Random Number Generation,RM A 3 2 49 Ada Characters Handling,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-a-4-4-106-bounded-length-string-handling}@anchor{23a} +@anchor{gnat_rm/implementation_advice rm-a-4-4-106-bounded-length-string-handling}@anchor{239} @section RM A.4.4(106): Bounded-Length String Handling @@ -15031,7 +15013,7 @@ Followed. No implicit pointers or dynamic allocation are used. @geindex Random number generation @node RM A 5 2 46-47 Random Number Generation,RM A 10 7 23 Get_Immediate,RM A 4 4 106 Bounded-Length String Handling,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-a-5-2-46-47-random-number-generation}@anchor{23b} +@anchor{gnat_rm/implementation_advice rm-a-5-2-46-47-random-number-generation}@anchor{23a} @section RM A.5.2(46-47): Random Number Generation @@ -15060,7 +15042,7 @@ condition here to hold true. @geindex Get_Immediate @node RM A 10 7 23 Get_Immediate,RM B 1 39-41 Pragma Export,RM A 5 2 46-47 Random Number Generation,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-a-10-7-23-get-immediate}@anchor{23c} +@anchor{gnat_rm/implementation_advice rm-a-10-7-23-get-immediate}@anchor{23b} @section RM A.10.7(23): @code{Get_Immediate} @@ -15084,7 +15066,7 @@ this functionality. @geindex Export @node RM B 1 39-41 Pragma Export,RM B 2 12-13 Package Interfaces,RM A 10 7 23 Get_Immediate,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-b-1-39-41-pragma-export}@anchor{23d} +@anchor{gnat_rm/implementation_advice rm-b-1-39-41-pragma-export}@anchor{23c} @section RM B.1(39-41): Pragma @code{Export} @@ -15132,7 +15114,7 @@ Followed. @geindex Interfaces @node RM B 2 12-13 Package Interfaces,RM B 3 63-71 Interfacing with C,RM B 1 39-41 Pragma Export,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-b-2-12-13-package-interfaces}@anchor{23e} +@anchor{gnat_rm/implementation_advice rm-b-2-12-13-package-interfaces}@anchor{23d} @section RM B.2(12-13): Package @code{Interfaces} @@ -15162,7 +15144,7 @@ Followed. GNAT provides all the packages described in this section. @geindex interfacing with @node RM B 3 63-71 Interfacing with C,RM B 4 95-98 Interfacing with COBOL,RM B 2 12-13 Package Interfaces,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-b-3-63-71-interfacing-with-c}@anchor{23f} +@anchor{gnat_rm/implementation_advice rm-b-3-63-71-interfacing-with-c}@anchor{23e} @section RM B.3(63-71): Interfacing with C @@ -15250,7 +15232,7 @@ Followed. @geindex interfacing with @node RM B 4 95-98 Interfacing with COBOL,RM B 5 22-26 Interfacing with Fortran,RM B 3 63-71 Interfacing with C,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-b-4-95-98-interfacing-with-cobol}@anchor{240} +@anchor{gnat_rm/implementation_advice rm-b-4-95-98-interfacing-with-cobol}@anchor{23f} @section RM B.4(95-98): Interfacing with COBOL @@ -15291,7 +15273,7 @@ Followed. @geindex interfacing with @node RM B 5 22-26 Interfacing with Fortran,RM C 1 3-5 Access to Machine Operations,RM B 4 95-98 Interfacing with COBOL,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-b-5-22-26-interfacing-with-fortran}@anchor{241} +@anchor{gnat_rm/implementation_advice rm-b-5-22-26-interfacing-with-fortran}@anchor{240} @section RM B.5(22-26): Interfacing with Fortran @@ -15342,7 +15324,7 @@ Followed. @geindex Machine operations @node RM C 1 3-5 Access to Machine Operations,RM C 1 10-16 Access to Machine Operations,RM B 5 22-26 Interfacing with Fortran,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-c-1-3-5-access-to-machine-operations}@anchor{242} +@anchor{gnat_rm/implementation_advice rm-c-1-3-5-access-to-machine-operations}@anchor{241} @section RM C.1(3-5): Access to Machine Operations @@ -15377,7 +15359,7 @@ object that is specified as exported." Followed. @node RM C 1 10-16 Access to Machine Operations,RM C 3 28 Interrupt Support,RM C 1 3-5 Access to Machine Operations,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-c-1-10-16-access-to-machine-operations}@anchor{243} +@anchor{gnat_rm/implementation_advice rm-c-1-10-16-access-to-machine-operations}@anchor{242} @section RM C.1(10-16): Access to Machine Operations @@ -15438,7 +15420,7 @@ Followed on any target supporting such operations. @geindex Interrupt support @node RM C 3 28 Interrupt Support,RM C 3 1 20-21 Protected Procedure Handlers,RM C 1 10-16 Access to Machine Operations,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-c-3-28-interrupt-support}@anchor{244} +@anchor{gnat_rm/implementation_advice rm-c-3-28-interrupt-support}@anchor{243} @section RM C.3(28): Interrupt Support @@ -15456,7 +15438,7 @@ of interrupt blocking. @geindex Protected procedure handlers @node RM C 3 1 20-21 Protected Procedure Handlers,RM C 3 2 25 Package Interrupts,RM C 3 28 Interrupt Support,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-c-3-1-20-21-protected-procedure-handlers}@anchor{245} +@anchor{gnat_rm/implementation_advice rm-c-3-1-20-21-protected-procedure-handlers}@anchor{244} @section RM C.3.1(20-21): Protected Procedure Handlers @@ -15482,7 +15464,7 @@ Followed. Compile time warnings are given when possible. @geindex Interrupts @node RM C 3 2 25 Package Interrupts,RM C 4 14 Pre-elaboration Requirements,RM C 3 1 20-21 Protected Procedure Handlers,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-c-3-2-25-package-interrupts}@anchor{246} +@anchor{gnat_rm/implementation_advice rm-c-3-2-25-package-interrupts}@anchor{245} @section RM C.3.2(25): Package @code{Interrupts} @@ -15500,7 +15482,7 @@ Followed. @geindex Pre-elaboration requirements @node RM C 4 14 Pre-elaboration Requirements,RM C 5 8 Pragma Discard_Names,RM C 3 2 25 Package Interrupts,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-c-4-14-pre-elaboration-requirements}@anchor{247} +@anchor{gnat_rm/implementation_advice rm-c-4-14-pre-elaboration-requirements}@anchor{246} @section RM C.4(14): Pre-elaboration Requirements @@ -15516,7 +15498,7 @@ Followed. Executable code is generated in some cases, e.g., loops to initialize large arrays. @node RM C 5 8 Pragma Discard_Names,RM C 7 2 30 The Package Task_Attributes,RM C 4 14 Pre-elaboration Requirements,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-c-5-8-pragma-discard-names}@anchor{248} +@anchor{gnat_rm/implementation_advice rm-c-5-8-pragma-discard-names}@anchor{247} @section RM C.5(8): Pragma @code{Discard_Names} @@ -15534,7 +15516,7 @@ Followed. @geindex Task_Attributes @node RM C 7 2 30 The Package Task_Attributes,RM D 3 17 Locking Policies,RM C 5 8 Pragma Discard_Names,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-c-7-2-30-the-package-task-attributes}@anchor{249} +@anchor{gnat_rm/implementation_advice rm-c-7-2-30-the-package-task-attributes}@anchor{248} @section RM C.7.2(30): The Package Task_Attributes @@ -15555,7 +15537,7 @@ Not followed. This implementation is not targeted to such a domain. @geindex Locking Policies @node RM D 3 17 Locking Policies,RM D 4 16 Entry Queuing Policies,RM C 7 2 30 The Package Task_Attributes,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-d-3-17-locking-policies}@anchor{24a} +@anchor{gnat_rm/implementation_advice rm-d-3-17-locking-policies}@anchor{249} @section RM D.3(17): Locking Policies @@ -15572,7 +15554,7 @@ whose names (@code{Inheritance_Locking} and @geindex Entry queuing policies @node RM D 4 16 Entry Queuing Policies,RM D 6 9-10 Preemptive Abort,RM D 3 17 Locking Policies,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-d-4-16-entry-queuing-policies}@anchor{24b} +@anchor{gnat_rm/implementation_advice rm-d-4-16-entry-queuing-policies}@anchor{24a} @section RM D.4(16): Entry Queuing Policies @@ -15587,7 +15569,7 @@ Followed. No such implementation-defined queuing policies exist. @geindex Preemptive abort @node RM D 6 9-10 Preemptive Abort,RM D 7 21 Tasking Restrictions,RM D 4 16 Entry Queuing Policies,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-d-6-9-10-preemptive-abort}@anchor{24c} +@anchor{gnat_rm/implementation_advice rm-d-6-9-10-preemptive-abort}@anchor{24b} @section RM D.6(9-10): Preemptive Abort @@ -15613,7 +15595,7 @@ Followed. @geindex Tasking restrictions @node RM D 7 21 Tasking Restrictions,RM D 8 47-49 Monotonic Time,RM D 6 9-10 Preemptive Abort,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-d-7-21-tasking-restrictions}@anchor{24d} +@anchor{gnat_rm/implementation_advice rm-d-7-21-tasking-restrictions}@anchor{24c} @section RM D.7(21): Tasking Restrictions @@ -15632,7 +15614,7 @@ pragma @code{Profile (Restricted)} for more details. @geindex monotonic @node RM D 8 47-49 Monotonic Time,RM E 5 28-29 Partition Communication Subsystem,RM D 7 21 Tasking Restrictions,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-d-8-47-49-monotonic-time}@anchor{24e} +@anchor{gnat_rm/implementation_advice rm-d-8-47-49-monotonic-time}@anchor{24d} @section RM D.8(47-49): Monotonic Time @@ -15667,7 +15649,7 @@ Followed. @geindex PCS @node RM E 5 28-29 Partition Communication Subsystem,RM F 7 COBOL Support,RM D 8 47-49 Monotonic Time,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-e-5-28-29-partition-communication-subsystem}@anchor{24f} +@anchor{gnat_rm/implementation_advice rm-e-5-28-29-partition-communication-subsystem}@anchor{24e} @section RM E.5(28-29): Partition Communication Subsystem @@ -15695,7 +15677,7 @@ GNAT. @geindex COBOL support @node RM F 7 COBOL Support,RM F 1 2 Decimal Radix Support,RM E 5 28-29 Partition Communication Subsystem,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-f-7-cobol-support}@anchor{250} +@anchor{gnat_rm/implementation_advice rm-f-7-cobol-support}@anchor{24f} @section RM F(7): COBOL Support @@ -15715,7 +15697,7 @@ Followed. @geindex Decimal radix support @node RM F 1 2 Decimal Radix Support,RM G Numerics,RM F 7 COBOL Support,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-f-1-2-decimal-radix-support}@anchor{251} +@anchor{gnat_rm/implementation_advice rm-f-1-2-decimal-radix-support}@anchor{250} @section RM F.1(2): Decimal Radix Support @@ -15731,7 +15713,7 @@ representations. @geindex Numerics @node RM G Numerics,RM G 1 1 56-58 Complex Types,RM F 1 2 Decimal Radix Support,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-g-numerics}@anchor{252} +@anchor{gnat_rm/implementation_advice rm-g-numerics}@anchor{251} @section RM G: Numerics @@ -15751,7 +15733,7 @@ Followed. @geindex Complex types @node RM G 1 1 56-58 Complex Types,RM G 1 2 49 Complex Elementary Functions,RM G Numerics,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-g-1-1-56-58-complex-types}@anchor{253} +@anchor{gnat_rm/implementation_advice rm-g-1-1-56-58-complex-types}@anchor{252} @section RM G.1.1(56-58): Complex Types @@ -15813,7 +15795,7 @@ Followed. @geindex Complex elementary functions @node RM G 1 2 49 Complex Elementary Functions,RM G 2 4 19 Accuracy Requirements,RM G 1 1 56-58 Complex Types,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-g-1-2-49-complex-elementary-functions}@anchor{254} +@anchor{gnat_rm/implementation_advice rm-g-1-2-49-complex-elementary-functions}@anchor{253} @section RM G.1.2(49): Complex Elementary Functions @@ -15835,7 +15817,7 @@ Followed. @geindex Accuracy requirements @node RM G 2 4 19 Accuracy Requirements,RM G 2 6 15 Complex Arithmetic Accuracy,RM G 1 2 49 Complex Elementary Functions,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-g-2-4-19-accuracy-requirements}@anchor{255} +@anchor{gnat_rm/implementation_advice rm-g-2-4-19-accuracy-requirements}@anchor{254} @section RM G.2.4(19): Accuracy Requirements @@ -15859,7 +15841,7 @@ Followed. @geindex complex arithmetic @node RM G 2 6 15 Complex Arithmetic Accuracy,RM H 6 15/2 Pragma Partition_Elaboration_Policy,RM G 2 4 19 Accuracy Requirements,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-g-2-6-15-complex-arithmetic-accuracy}@anchor{256} +@anchor{gnat_rm/implementation_advice rm-g-2-6-15-complex-arithmetic-accuracy}@anchor{255} @section RM G.2.6(15): Complex Arithmetic Accuracy @@ -15877,7 +15859,7 @@ Followed. @geindex Sequential elaboration policy @node RM H 6 15/2 Pragma Partition_Elaboration_Policy,,RM G 2 6 15 Complex Arithmetic Accuracy,Implementation Advice -@anchor{gnat_rm/implementation_advice rm-h-6-15-2-pragma-partition-elaboration-policy}@anchor{257} +@anchor{gnat_rm/implementation_advice rm-h-6-15-2-pragma-partition-elaboration-policy}@anchor{256} @section RM H.6(15/2): Pragma Partition_Elaboration_Policy @@ -15892,7 +15874,7 @@ immediately terminated." Not followed. @node Implementation Defined Characteristics,Intrinsic Subprograms,Implementation Advice,Top -@anchor{gnat_rm/implementation_defined_characteristics implementation-defined-characteristics}@anchor{b}@anchor{gnat_rm/implementation_defined_characteristics doc}@anchor{258}@anchor{gnat_rm/implementation_defined_characteristics id1}@anchor{259} +@anchor{gnat_rm/implementation_defined_characteristics implementation-defined-characteristics}@anchor{b}@anchor{gnat_rm/implementation_defined_characteristics doc}@anchor{257}@anchor{gnat_rm/implementation_defined_characteristics id1}@anchor{258} @chapter Implementation Defined Characteristics @@ -17088,7 +17070,7 @@ When the @code{Pattern} parameter is not the null string, it is interpreted according to the syntax of regular expressions as defined in the @code{GNAT.Regexp} package. -See @ref{25a,,GNAT.Regexp (g-regexp.ads)}. +See @ref{259,,GNAT.Regexp (g-regexp.ads)}. @itemize * @@ -18137,7 +18119,7 @@ H.4(27)." There are no restrictions on pragma @code{Restrictions}. @node Intrinsic Subprograms,Representation Clauses and Pragmas,Implementation Defined Characteristics,Top -@anchor{gnat_rm/intrinsic_subprograms doc}@anchor{25b}@anchor{gnat_rm/intrinsic_subprograms intrinsic-subprograms}@anchor{c}@anchor{gnat_rm/intrinsic_subprograms id1}@anchor{25c} +@anchor{gnat_rm/intrinsic_subprograms doc}@anchor{25a}@anchor{gnat_rm/intrinsic_subprograms intrinsic-subprograms}@anchor{c}@anchor{gnat_rm/intrinsic_subprograms id1}@anchor{25b} @chapter Intrinsic Subprograms @@ -18175,7 +18157,7 @@ Ada standard does not require Ada compilers to implement this feature. @end menu @node Intrinsic Operators,Compilation_ISO_Date,,Intrinsic Subprograms -@anchor{gnat_rm/intrinsic_subprograms id2}@anchor{25d}@anchor{gnat_rm/intrinsic_subprograms intrinsic-operators}@anchor{25e} +@anchor{gnat_rm/intrinsic_subprograms id2}@anchor{25c}@anchor{gnat_rm/intrinsic_subprograms intrinsic-operators}@anchor{25d} @section Intrinsic Operators @@ -18206,7 +18188,7 @@ It is also possible to specify such operators for private types, if the full views are appropriate arithmetic types. @node Compilation_ISO_Date,Compilation_Date,Intrinsic Operators,Intrinsic Subprograms -@anchor{gnat_rm/intrinsic_subprograms id3}@anchor{25f}@anchor{gnat_rm/intrinsic_subprograms compilation-iso-date}@anchor{260} +@anchor{gnat_rm/intrinsic_subprograms id3}@anchor{25e}@anchor{gnat_rm/intrinsic_subprograms compilation-iso-date}@anchor{25f} @section Compilation_ISO_Date @@ -18220,7 +18202,7 @@ application program should simply call the function the current compilation (in local time format YYYY-MM-DD). @node Compilation_Date,Compilation_Time,Compilation_ISO_Date,Intrinsic Subprograms -@anchor{gnat_rm/intrinsic_subprograms compilation-date}@anchor{261}@anchor{gnat_rm/intrinsic_subprograms id4}@anchor{262} +@anchor{gnat_rm/intrinsic_subprograms compilation-date}@anchor{260}@anchor{gnat_rm/intrinsic_subprograms id4}@anchor{261} @section Compilation_Date @@ -18230,7 +18212,7 @@ Same as Compilation_ISO_Date, except the string is in the form MMM DD YYYY. @node Compilation_Time,Enclosing_Entity,Compilation_Date,Intrinsic Subprograms -@anchor{gnat_rm/intrinsic_subprograms compilation-time}@anchor{263}@anchor{gnat_rm/intrinsic_subprograms id5}@anchor{264} +@anchor{gnat_rm/intrinsic_subprograms compilation-time}@anchor{262}@anchor{gnat_rm/intrinsic_subprograms id5}@anchor{263} @section Compilation_Time @@ -18244,7 +18226,7 @@ application program should simply call the function the current compilation (in local time format HH:MM:SS). @node Enclosing_Entity,Exception_Information,Compilation_Time,Intrinsic Subprograms -@anchor{gnat_rm/intrinsic_subprograms id6}@anchor{265}@anchor{gnat_rm/intrinsic_subprograms enclosing-entity}@anchor{266} +@anchor{gnat_rm/intrinsic_subprograms id6}@anchor{264}@anchor{gnat_rm/intrinsic_subprograms enclosing-entity}@anchor{265} @section Enclosing_Entity @@ -18258,7 +18240,7 @@ application program should simply call the function the current subprogram, package, task, entry, or protected subprogram. @node Exception_Information,Exception_Message,Enclosing_Entity,Intrinsic Subprograms -@anchor{gnat_rm/intrinsic_subprograms id7}@anchor{267}@anchor{gnat_rm/intrinsic_subprograms exception-information}@anchor{268} +@anchor{gnat_rm/intrinsic_subprograms id7}@anchor{266}@anchor{gnat_rm/intrinsic_subprograms exception-information}@anchor{267} @section Exception_Information @@ -18272,7 +18254,7 @@ so an application program should simply call the function the exception information associated with the current exception. @node Exception_Message,Exception_Name,Exception_Information,Intrinsic Subprograms -@anchor{gnat_rm/intrinsic_subprograms exception-message}@anchor{269}@anchor{gnat_rm/intrinsic_subprograms id8}@anchor{26a} +@anchor{gnat_rm/intrinsic_subprograms exception-message}@anchor{268}@anchor{gnat_rm/intrinsic_subprograms id8}@anchor{269} @section Exception_Message @@ -18286,7 +18268,7 @@ so an application program should simply call the function the message associated with the current exception. @node Exception_Name,File,Exception_Message,Intrinsic Subprograms -@anchor{gnat_rm/intrinsic_subprograms exception-name}@anchor{26b}@anchor{gnat_rm/intrinsic_subprograms id9}@anchor{26c} +@anchor{gnat_rm/intrinsic_subprograms exception-name}@anchor{26a}@anchor{gnat_rm/intrinsic_subprograms id9}@anchor{26b} @section Exception_Name @@ -18300,7 +18282,7 @@ so an application program should simply call the function the name of the current exception. @node File,Line,Exception_Name,Intrinsic Subprograms -@anchor{gnat_rm/intrinsic_subprograms id10}@anchor{26d}@anchor{gnat_rm/intrinsic_subprograms file}@anchor{26e} +@anchor{gnat_rm/intrinsic_subprograms id10}@anchor{26c}@anchor{gnat_rm/intrinsic_subprograms file}@anchor{26d} @section File @@ -18314,7 +18296,7 @@ application program should simply call the function file. @node Line,Shifts and Rotates,File,Intrinsic Subprograms -@anchor{gnat_rm/intrinsic_subprograms id11}@anchor{26f}@anchor{gnat_rm/intrinsic_subprograms line}@anchor{270} +@anchor{gnat_rm/intrinsic_subprograms id11}@anchor{26e}@anchor{gnat_rm/intrinsic_subprograms line}@anchor{26f} @section Line @@ -18328,7 +18310,7 @@ application program should simply call the function source line. @node Shifts and Rotates,Source_Location,Line,Intrinsic Subprograms -@anchor{gnat_rm/intrinsic_subprograms shifts-and-rotates}@anchor{271}@anchor{gnat_rm/intrinsic_subprograms id12}@anchor{272} +@anchor{gnat_rm/intrinsic_subprograms shifts-and-rotates}@anchor{270}@anchor{gnat_rm/intrinsic_subprograms id12}@anchor{271} @section Shifts and Rotates @@ -18367,7 +18349,7 @@ the Provide_Shift_Operators pragma, which provides the function declarations and corresponding pragma Import's for all five shift functions. @node Source_Location,,Shifts and Rotates,Intrinsic Subprograms -@anchor{gnat_rm/intrinsic_subprograms source-location}@anchor{273}@anchor{gnat_rm/intrinsic_subprograms id13}@anchor{274} +@anchor{gnat_rm/intrinsic_subprograms source-location}@anchor{272}@anchor{gnat_rm/intrinsic_subprograms id13}@anchor{273} @section Source_Location @@ -18381,7 +18363,7 @@ application program should simply call the function source file location. @node Representation Clauses and Pragmas,Standard Library Routines,Intrinsic Subprograms,Top -@anchor{gnat_rm/representation_clauses_and_pragmas representation-clauses-and-pragmas}@anchor{d}@anchor{gnat_rm/representation_clauses_and_pragmas doc}@anchor{275}@anchor{gnat_rm/representation_clauses_and_pragmas id1}@anchor{276} +@anchor{gnat_rm/representation_clauses_and_pragmas representation-clauses-and-pragmas}@anchor{d}@anchor{gnat_rm/representation_clauses_and_pragmas doc}@anchor{274}@anchor{gnat_rm/representation_clauses_and_pragmas id1}@anchor{275} @chapter Representation Clauses and Pragmas @@ -18427,7 +18409,7 @@ and this section describes the additional capabilities provided. @end menu @node Alignment Clauses,Size Clauses,,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas id2}@anchor{277}@anchor{gnat_rm/representation_clauses_and_pragmas alignment-clauses}@anchor{278} +@anchor{gnat_rm/representation_clauses_and_pragmas id2}@anchor{276}@anchor{gnat_rm/representation_clauses_and_pragmas alignment-clauses}@anchor{277} @section Alignment Clauses @@ -18449,7 +18431,7 @@ For elementary types, the alignment is the minimum of the actual size of objects of the type divided by @code{Storage_Unit}, and the maximum alignment supported by the target. (This maximum alignment is given by the GNAT-specific attribute -@code{Standard'Maximum_Alignment}; see @ref{192,,Attribute Maximum_Alignment}.) +@code{Standard'Maximum_Alignment}; see @ref{191,,Attribute Maximum_Alignment}.) @geindex Maximum_Alignment attribute @@ -18558,7 +18540,7 @@ assumption is non-portable, and other compilers may choose different alignments for the subtype @code{RS}. @node Size Clauses,Storage_Size Clauses,Alignment Clauses,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas id3}@anchor{279}@anchor{gnat_rm/representation_clauses_and_pragmas size-clauses}@anchor{27a} +@anchor{gnat_rm/representation_clauses_and_pragmas id3}@anchor{278}@anchor{gnat_rm/representation_clauses_and_pragmas size-clauses}@anchor{279} @section Size Clauses @@ -18635,7 +18617,7 @@ if it is known that a Size value can be accommodated in an object of type Integer. @node Storage_Size Clauses,Size of Variant Record Objects,Size Clauses,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas storage-size-clauses}@anchor{27b}@anchor{gnat_rm/representation_clauses_and_pragmas id4}@anchor{27c} +@anchor{gnat_rm/representation_clauses_and_pragmas storage-size-clauses}@anchor{27a}@anchor{gnat_rm/representation_clauses_and_pragmas id4}@anchor{27b} @section Storage_Size Clauses @@ -18708,7 +18690,7 @@ Of course in practice, there will not be any explicit allocators in the case of such an access declaration. @node Size of Variant Record Objects,Biased Representation,Storage_Size Clauses,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas id5}@anchor{27d}@anchor{gnat_rm/representation_clauses_and_pragmas size-of-variant-record-objects}@anchor{27e} +@anchor{gnat_rm/representation_clauses_and_pragmas id5}@anchor{27c}@anchor{gnat_rm/representation_clauses_and_pragmas size-of-variant-record-objects}@anchor{27d} @section Size of Variant Record Objects @@ -18818,7 +18800,7 @@ the maximum size, regardless of the current variant value, the variant value. @node Biased Representation,Value_Size and Object_Size Clauses,Size of Variant Record Objects,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas id6}@anchor{27f}@anchor{gnat_rm/representation_clauses_and_pragmas biased-representation}@anchor{280} +@anchor{gnat_rm/representation_clauses_and_pragmas id6}@anchor{27e}@anchor{gnat_rm/representation_clauses_and_pragmas biased-representation}@anchor{27f} @section Biased Representation @@ -18856,7 +18838,7 @@ biased representation can be used for all discrete types except for enumeration types for which a representation clause is given. @node Value_Size and Object_Size Clauses,Component_Size Clauses,Biased Representation,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas id7}@anchor{281}@anchor{gnat_rm/representation_clauses_and_pragmas value-size-and-object-size-clauses}@anchor{282} +@anchor{gnat_rm/representation_clauses_and_pragmas id7}@anchor{280}@anchor{gnat_rm/representation_clauses_and_pragmas value-size-and-object-size-clauses}@anchor{281} @section Value_Size and Object_Size Clauses @@ -19172,7 +19154,7 @@ definition clause forces biased representation. This warning can be turned off using @code{-gnatw.B}. @node Component_Size Clauses,Bit_Order Clauses,Value_Size and Object_Size Clauses,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas id8}@anchor{283}@anchor{gnat_rm/representation_clauses_and_pragmas component-size-clauses}@anchor{284} +@anchor{gnat_rm/representation_clauses_and_pragmas id8}@anchor{282}@anchor{gnat_rm/representation_clauses_and_pragmas component-size-clauses}@anchor{283} @section Component_Size Clauses @@ -19219,7 +19201,7 @@ and a pragma Pack for the same array type. if such duplicate clauses are given, the pragma Pack will be ignored. @node Bit_Order Clauses,Effect of Bit_Order on Byte Ordering,Component_Size Clauses,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas bit-order-clauses}@anchor{285}@anchor{gnat_rm/representation_clauses_and_pragmas id9}@anchor{286} +@anchor{gnat_rm/representation_clauses_and_pragmas bit-order-clauses}@anchor{284}@anchor{gnat_rm/representation_clauses_and_pragmas id9}@anchor{285} @section Bit_Order Clauses @@ -19325,7 +19307,7 @@ if desired. The following section contains additional details regarding the issue of byte ordering. @node Effect of Bit_Order on Byte Ordering,Pragma Pack for Arrays,Bit_Order Clauses,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas id10}@anchor{287}@anchor{gnat_rm/representation_clauses_and_pragmas effect-of-bit-order-on-byte-ordering}@anchor{288} +@anchor{gnat_rm/representation_clauses_and_pragmas id10}@anchor{286}@anchor{gnat_rm/representation_clauses_and_pragmas effect-of-bit-order-on-byte-ordering}@anchor{287} @section Effect of Bit_Order on Byte Ordering @@ -19582,7 +19564,7 @@ to set the boolean constant @code{Master_Byte_First} in an appropriate manner. @node Pragma Pack for Arrays,Pragma Pack for Records,Effect of Bit_Order on Byte Ordering,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas pragma-pack-for-arrays}@anchor{289}@anchor{gnat_rm/representation_clauses_and_pragmas id11}@anchor{28a} +@anchor{gnat_rm/representation_clauses_and_pragmas pragma-pack-for-arrays}@anchor{288}@anchor{gnat_rm/representation_clauses_and_pragmas id11}@anchor{289} @section Pragma Pack for Arrays @@ -19699,7 +19681,7 @@ Here 31-bit packing is achieved as required, and no warning is generated, since in this case the programmer intention is clear. @node Pragma Pack for Records,Record Representation Clauses,Pragma Pack for Arrays,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas pragma-pack-for-records}@anchor{28b}@anchor{gnat_rm/representation_clauses_and_pragmas id12}@anchor{28c} +@anchor{gnat_rm/representation_clauses_and_pragmas pragma-pack-for-records}@anchor{28a}@anchor{gnat_rm/representation_clauses_and_pragmas id12}@anchor{28b} @section Pragma Pack for Records @@ -19784,7 +19766,7 @@ the @code{L6} field is aligned to the next byte boundary, and takes an integral number of bytes, i.e., 72 bits. @node Record Representation Clauses,Handling of Records with Holes,Pragma Pack for Records,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas id13}@anchor{28d}@anchor{gnat_rm/representation_clauses_and_pragmas record-representation-clauses}@anchor{28e} +@anchor{gnat_rm/representation_clauses_and_pragmas id13}@anchor{28c}@anchor{gnat_rm/representation_clauses_and_pragmas record-representation-clauses}@anchor{28d} @section Record Representation Clauses @@ -19862,7 +19844,7 @@ end record; @end example @node Handling of Records with Holes,Enumeration Clauses,Record Representation Clauses,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas handling-of-records-with-holes}@anchor{28f}@anchor{gnat_rm/representation_clauses_and_pragmas id14}@anchor{290} +@anchor{gnat_rm/representation_clauses_and_pragmas handling-of-records-with-holes}@anchor{28e}@anchor{gnat_rm/representation_clauses_and_pragmas id14}@anchor{28f} @section Handling of Records with Holes @@ -19939,7 +19921,7 @@ for Hrec'Size use 64; @end example @node Enumeration Clauses,Address Clauses,Handling of Records with Holes,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas enumeration-clauses}@anchor{291}@anchor{gnat_rm/representation_clauses_and_pragmas id15}@anchor{292} +@anchor{gnat_rm/representation_clauses_and_pragmas enumeration-clauses}@anchor{290}@anchor{gnat_rm/representation_clauses_and_pragmas id15}@anchor{291} @section Enumeration Clauses @@ -19982,7 +19964,7 @@ the overhead of converting representation values to the corresponding positional values, (i.e., the value delivered by the @code{Pos} attribute). @node Address Clauses,Use of Address Clauses for Memory-Mapped I/O,Enumeration Clauses,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas id16}@anchor{293}@anchor{gnat_rm/representation_clauses_and_pragmas address-clauses}@anchor{294} +@anchor{gnat_rm/representation_clauses_and_pragmas id16}@anchor{292}@anchor{gnat_rm/representation_clauses_and_pragmas address-clauses}@anchor{293} @section Address Clauses @@ -20311,7 +20293,7 @@ then the program compiles without the warning and when run will generate the output @code{X was not clobbered}. @node Use of Address Clauses for Memory-Mapped I/O,Effect of Convention on Representation,Address Clauses,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas id17}@anchor{295}@anchor{gnat_rm/representation_clauses_and_pragmas use-of-address-clauses-for-memory-mapped-i-o}@anchor{296} +@anchor{gnat_rm/representation_clauses_and_pragmas id17}@anchor{294}@anchor{gnat_rm/representation_clauses_and_pragmas use-of-address-clauses-for-memory-mapped-i-o}@anchor{295} @section Use of Address Clauses for Memory-Mapped I/O @@ -20369,7 +20351,7 @@ provides the pragma @code{Volatile_Full_Access} which can be used in lieu of pragma @code{Atomic} and will give the additional guarantee. @node Effect of Convention on Representation,Conventions and Anonymous Access Types,Use of Address Clauses for Memory-Mapped I/O,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas id18}@anchor{297}@anchor{gnat_rm/representation_clauses_and_pragmas effect-of-convention-on-representation}@anchor{298} +@anchor{gnat_rm/representation_clauses_and_pragmas id18}@anchor{296}@anchor{gnat_rm/representation_clauses_and_pragmas effect-of-convention-on-representation}@anchor{297} @section Effect of Convention on Representation @@ -20447,7 +20429,7 @@ when one of these values is read, any nonzero value is treated as True. @end itemize @node Conventions and Anonymous Access Types,Determining the Representations chosen by GNAT,Effect of Convention on Representation,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas conventions-and-anonymous-access-types}@anchor{299}@anchor{gnat_rm/representation_clauses_and_pragmas id19}@anchor{29a} +@anchor{gnat_rm/representation_clauses_and_pragmas conventions-and-anonymous-access-types}@anchor{298}@anchor{gnat_rm/representation_clauses_and_pragmas id19}@anchor{299} @section Conventions and Anonymous Access Types @@ -20523,7 +20505,7 @@ package ConvComp is @end example @node Determining the Representations chosen by GNAT,,Conventions and Anonymous Access Types,Representation Clauses and Pragmas -@anchor{gnat_rm/representation_clauses_and_pragmas id20}@anchor{29b}@anchor{gnat_rm/representation_clauses_and_pragmas determining-the-representations-chosen-by-gnat}@anchor{29c} +@anchor{gnat_rm/representation_clauses_and_pragmas id20}@anchor{29a}@anchor{gnat_rm/representation_clauses_and_pragmas determining-the-representations-chosen-by-gnat}@anchor{29b} @section Determining the Representations chosen by GNAT @@ -20675,7 +20657,7 @@ generated by the compiler into the original source to fix and guarantee the actual representation to be used. @node Standard Library Routines,The Implementation of Standard I/O,Representation Clauses and Pragmas,Top -@anchor{gnat_rm/standard_library_routines standard-library-routines}@anchor{e}@anchor{gnat_rm/standard_library_routines doc}@anchor{29d}@anchor{gnat_rm/standard_library_routines id1}@anchor{29e} +@anchor{gnat_rm/standard_library_routines standard-library-routines}@anchor{e}@anchor{gnat_rm/standard_library_routines doc}@anchor{29c}@anchor{gnat_rm/standard_library_routines id1}@anchor{29d} @chapter Standard Library Routines @@ -21499,7 +21481,7 @@ For packages in Interfaces and System, all the RM defined packages are available in GNAT, see the Ada 2012 RM for full details. @node The Implementation of Standard I/O,The GNAT Library,Standard Library Routines,Top -@anchor{gnat_rm/the_implementation_of_standard_i_o the-implementation-of-standard-i-o}@anchor{f}@anchor{gnat_rm/the_implementation_of_standard_i_o doc}@anchor{29f}@anchor{gnat_rm/the_implementation_of_standard_i_o id1}@anchor{2a0} +@anchor{gnat_rm/the_implementation_of_standard_i_o the-implementation-of-standard-i-o}@anchor{f}@anchor{gnat_rm/the_implementation_of_standard_i_o doc}@anchor{29e}@anchor{gnat_rm/the_implementation_of_standard_i_o id1}@anchor{29f} @chapter The Implementation of Standard I/O @@ -21551,7 +21533,7 @@ these additional facilities are also described in this chapter. @end menu @node Standard I/O Packages,FORM Strings,,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o standard-i-o-packages}@anchor{2a1}@anchor{gnat_rm/the_implementation_of_standard_i_o id2}@anchor{2a2} +@anchor{gnat_rm/the_implementation_of_standard_i_o standard-i-o-packages}@anchor{2a0}@anchor{gnat_rm/the_implementation_of_standard_i_o id2}@anchor{2a1} @section Standard I/O Packages @@ -21622,7 +21604,7 @@ flush the common I/O streams and in particular Standard_Output before elaborating the Ada code. @node FORM Strings,Direct_IO,Standard I/O Packages,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o form-strings}@anchor{2a3}@anchor{gnat_rm/the_implementation_of_standard_i_o id3}@anchor{2a4} +@anchor{gnat_rm/the_implementation_of_standard_i_o form-strings}@anchor{2a2}@anchor{gnat_rm/the_implementation_of_standard_i_o id3}@anchor{2a3} @section FORM Strings @@ -21648,7 +21630,7 @@ unrecognized keyword appears in a form string, it is silently ignored and not considered invalid. @node Direct_IO,Sequential_IO,FORM Strings,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o direct-io}@anchor{2a5}@anchor{gnat_rm/the_implementation_of_standard_i_o id4}@anchor{2a6} +@anchor{gnat_rm/the_implementation_of_standard_i_o direct-io}@anchor{2a4}@anchor{gnat_rm/the_implementation_of_standard_i_o id4}@anchor{2a5} @section Direct_IO @@ -21668,7 +21650,7 @@ There is no limit on the size of Direct_IO files, they are expanded as necessary to accommodate whatever records are written to the file. @node Sequential_IO,Text_IO,Direct_IO,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o sequential-io}@anchor{2a7}@anchor{gnat_rm/the_implementation_of_standard_i_o id5}@anchor{2a8} +@anchor{gnat_rm/the_implementation_of_standard_i_o sequential-io}@anchor{2a6}@anchor{gnat_rm/the_implementation_of_standard_i_o id5}@anchor{2a7} @section Sequential_IO @@ -21715,7 +21697,7 @@ using Stream_IO, and this is the preferred mechanism. In particular, the above program fragment rewritten to use Stream_IO will work correctly. @node Text_IO,Wide_Text_IO,Sequential_IO,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o id6}@anchor{2a9}@anchor{gnat_rm/the_implementation_of_standard_i_o text-io}@anchor{2aa} +@anchor{gnat_rm/the_implementation_of_standard_i_o id6}@anchor{2a8}@anchor{gnat_rm/the_implementation_of_standard_i_o text-io}@anchor{2a9} @section Text_IO @@ -21798,7 +21780,7 @@ the file. @end menu @node Stream Pointer Positioning,Reading and Writing Non-Regular Files,,Text_IO -@anchor{gnat_rm/the_implementation_of_standard_i_o id7}@anchor{2ab}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning}@anchor{2ac} +@anchor{gnat_rm/the_implementation_of_standard_i_o id7}@anchor{2aa}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning}@anchor{2ab} @subsection Stream Pointer Positioning @@ -21834,7 +21816,7 @@ between two Ada files, then the difference may be observable in some situations. @node Reading and Writing Non-Regular Files,Get_Immediate,Stream Pointer Positioning,Text_IO -@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files}@anchor{2ad}@anchor{gnat_rm/the_implementation_of_standard_i_o id8}@anchor{2ae} +@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files}@anchor{2ac}@anchor{gnat_rm/the_implementation_of_standard_i_o id8}@anchor{2ad} @subsection Reading and Writing Non-Regular Files @@ -21885,7 +21867,7 @@ to read data past that end of file indication, until another end of file indication is entered. @node Get_Immediate,Treating Text_IO Files as Streams,Reading and Writing Non-Regular Files,Text_IO -@anchor{gnat_rm/the_implementation_of_standard_i_o get-immediate}@anchor{2af}@anchor{gnat_rm/the_implementation_of_standard_i_o id9}@anchor{2b0} +@anchor{gnat_rm/the_implementation_of_standard_i_o get-immediate}@anchor{2ae}@anchor{gnat_rm/the_implementation_of_standard_i_o id9}@anchor{2af} @subsection Get_Immediate @@ -21903,7 +21885,7 @@ possible), it is undefined whether the FF character will be treated as a page mark. @node Treating Text_IO Files as Streams,Text_IO Extensions,Get_Immediate,Text_IO -@anchor{gnat_rm/the_implementation_of_standard_i_o id10}@anchor{2b1}@anchor{gnat_rm/the_implementation_of_standard_i_o treating-text-io-files-as-streams}@anchor{2b2} +@anchor{gnat_rm/the_implementation_of_standard_i_o id10}@anchor{2b0}@anchor{gnat_rm/the_implementation_of_standard_i_o treating-text-io-files-as-streams}@anchor{2b1} @subsection Treating Text_IO Files as Streams @@ -21919,7 +21901,7 @@ skipped and the effect is similar to that described above for @code{Get_Immediate}. @node Text_IO Extensions,Text_IO Facilities for Unbounded Strings,Treating Text_IO Files as Streams,Text_IO -@anchor{gnat_rm/the_implementation_of_standard_i_o id11}@anchor{2b3}@anchor{gnat_rm/the_implementation_of_standard_i_o text-io-extensions}@anchor{2b4} +@anchor{gnat_rm/the_implementation_of_standard_i_o id11}@anchor{2b2}@anchor{gnat_rm/the_implementation_of_standard_i_o text-io-extensions}@anchor{2b3} @subsection Text_IO Extensions @@ -21947,7 +21929,7 @@ the string is to be read. @end itemize @node Text_IO Facilities for Unbounded Strings,,Text_IO Extensions,Text_IO -@anchor{gnat_rm/the_implementation_of_standard_i_o text-io-facilities-for-unbounded-strings}@anchor{2b5}@anchor{gnat_rm/the_implementation_of_standard_i_o id12}@anchor{2b6} +@anchor{gnat_rm/the_implementation_of_standard_i_o text-io-facilities-for-unbounded-strings}@anchor{2b4}@anchor{gnat_rm/the_implementation_of_standard_i_o id12}@anchor{2b5} @subsection Text_IO Facilities for Unbounded Strings @@ -21995,7 +21977,7 @@ files @code{a-szuzti.ads} and @code{a-szuzti.adb} provides similar extended @code{Wide_Wide_Text_IO} functionality for unbounded wide wide strings. @node Wide_Text_IO,Wide_Wide_Text_IO,Text_IO,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o wide-text-io}@anchor{2b7}@anchor{gnat_rm/the_implementation_of_standard_i_o id13}@anchor{2b8} +@anchor{gnat_rm/the_implementation_of_standard_i_o wide-text-io}@anchor{2b6}@anchor{gnat_rm/the_implementation_of_standard_i_o id13}@anchor{2b7} @section Wide_Text_IO @@ -22242,12 +22224,12 @@ input also causes Constraint_Error to be raised. @end menu @node Stream Pointer Positioning<2>,Reading and Writing Non-Regular Files<2>,,Wide_Text_IO -@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning-1}@anchor{2b9}@anchor{gnat_rm/the_implementation_of_standard_i_o id14}@anchor{2ba} +@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning-1}@anchor{2b8}@anchor{gnat_rm/the_implementation_of_standard_i_o id14}@anchor{2b9} @subsection Stream Pointer Positioning @code{Ada.Wide_Text_IO} is similar to @code{Ada.Text_IO} in its handling -of stream pointer positioning (@ref{2aa,,Text_IO}). There is one additional +of stream pointer positioning (@ref{2a9,,Text_IO}). There is one additional case: If @code{Ada.Wide_Text_IO.Look_Ahead} reads a character outside the @@ -22266,7 +22248,7 @@ to a normal program using @code{Wide_Text_IO}. However, this discrepancy can be observed if the wide text file shares a stream with another file. @node Reading and Writing Non-Regular Files<2>,,Stream Pointer Positioning<2>,Wide_Text_IO -@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files-1}@anchor{2bb}@anchor{gnat_rm/the_implementation_of_standard_i_o id15}@anchor{2bc} +@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files-1}@anchor{2ba}@anchor{gnat_rm/the_implementation_of_standard_i_o id15}@anchor{2bb} @subsection Reading and Writing Non-Regular Files @@ -22277,7 +22259,7 @@ treated as data characters), and @code{End_Of_Page} always returns it is possible to read beyond an end of file. @node Wide_Wide_Text_IO,Stream_IO,Wide_Text_IO,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o id16}@anchor{2bd}@anchor{gnat_rm/the_implementation_of_standard_i_o wide-wide-text-io}@anchor{2be} +@anchor{gnat_rm/the_implementation_of_standard_i_o id16}@anchor{2bc}@anchor{gnat_rm/the_implementation_of_standard_i_o wide-wide-text-io}@anchor{2bd} @section Wide_Wide_Text_IO @@ -22446,12 +22428,12 @@ input also causes Constraint_Error to be raised. @end menu @node Stream Pointer Positioning<3>,Reading and Writing Non-Regular Files<3>,,Wide_Wide_Text_IO -@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning-2}@anchor{2bf}@anchor{gnat_rm/the_implementation_of_standard_i_o id17}@anchor{2c0} +@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning-2}@anchor{2be}@anchor{gnat_rm/the_implementation_of_standard_i_o id17}@anchor{2bf} @subsection Stream Pointer Positioning @code{Ada.Wide_Wide_Text_IO} is similar to @code{Ada.Text_IO} in its handling -of stream pointer positioning (@ref{2aa,,Text_IO}). There is one additional +of stream pointer positioning (@ref{2a9,,Text_IO}). There is one additional case: If @code{Ada.Wide_Wide_Text_IO.Look_Ahead} reads a character outside the @@ -22470,7 +22452,7 @@ to a normal program using @code{Wide_Wide_Text_IO}. However, this discrepancy can be observed if the wide text file shares a stream with another file. @node Reading and Writing Non-Regular Files<3>,,Stream Pointer Positioning<3>,Wide_Wide_Text_IO -@anchor{gnat_rm/the_implementation_of_standard_i_o id18}@anchor{2c1}@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files-2}@anchor{2c2} +@anchor{gnat_rm/the_implementation_of_standard_i_o id18}@anchor{2c0}@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files-2}@anchor{2c1} @subsection Reading and Writing Non-Regular Files @@ -22481,7 +22463,7 @@ treated as data characters), and @code{End_Of_Page} always returns it is possible to read beyond an end of file. @node Stream_IO,Text Translation,Wide_Wide_Text_IO,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o id19}@anchor{2c3}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-io}@anchor{2c4} +@anchor{gnat_rm/the_implementation_of_standard_i_o id19}@anchor{2c2}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-io}@anchor{2c3} @section Stream_IO @@ -22503,7 +22485,7 @@ manner described for stream attributes. @end itemize @node Text Translation,Shared Files,Stream_IO,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o id20}@anchor{2c5}@anchor{gnat_rm/the_implementation_of_standard_i_o text-translation}@anchor{2c6} +@anchor{gnat_rm/the_implementation_of_standard_i_o id20}@anchor{2c4}@anchor{gnat_rm/the_implementation_of_standard_i_o text-translation}@anchor{2c5} @section Text Translation @@ -22537,7 +22519,7 @@ mode. (corresponds to_O_U16TEXT). @end itemize @node Shared Files,Filenames encoding,Text Translation,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o id21}@anchor{2c7}@anchor{gnat_rm/the_implementation_of_standard_i_o shared-files}@anchor{2c8} +@anchor{gnat_rm/the_implementation_of_standard_i_o id21}@anchor{2c6}@anchor{gnat_rm/the_implementation_of_standard_i_o shared-files}@anchor{2c7} @section Shared Files @@ -22600,7 +22582,7 @@ heterogeneous input-output. Although this approach will work in GNAT if for this purpose (using the stream attributes) @node Filenames encoding,File content encoding,Shared Files,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o filenames-encoding}@anchor{2c9}@anchor{gnat_rm/the_implementation_of_standard_i_o id22}@anchor{2ca} +@anchor{gnat_rm/the_implementation_of_standard_i_o filenames-encoding}@anchor{2c8}@anchor{gnat_rm/the_implementation_of_standard_i_o id22}@anchor{2c9} @section Filenames encoding @@ -22640,7 +22622,7 @@ platform. On the other Operating Systems the run-time is supporting UTF-8 natively. @node File content encoding,Open Modes,Filenames encoding,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o file-content-encoding}@anchor{2cb}@anchor{gnat_rm/the_implementation_of_standard_i_o id23}@anchor{2cc} +@anchor{gnat_rm/the_implementation_of_standard_i_o file-content-encoding}@anchor{2ca}@anchor{gnat_rm/the_implementation_of_standard_i_o id23}@anchor{2cb} @section File content encoding @@ -22673,7 +22655,7 @@ Unicode 8-bit encoding This encoding is only supported on the Windows platform. @node Open Modes,Operations on C Streams,File content encoding,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o open-modes}@anchor{2cd}@anchor{gnat_rm/the_implementation_of_standard_i_o id24}@anchor{2ce} +@anchor{gnat_rm/the_implementation_of_standard_i_o open-modes}@anchor{2cc}@anchor{gnat_rm/the_implementation_of_standard_i_o id24}@anchor{2cd} @section Open Modes @@ -22776,7 +22758,7 @@ subsequently requires switching from reading to writing or vice-versa, then the file is reopened in @code{r+} mode to permit the required operation. @node Operations on C Streams,Interfacing to C Streams,Open Modes,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o operations-on-c-streams}@anchor{2cf}@anchor{gnat_rm/the_implementation_of_standard_i_o id25}@anchor{2d0} +@anchor{gnat_rm/the_implementation_of_standard_i_o operations-on-c-streams}@anchor{2ce}@anchor{gnat_rm/the_implementation_of_standard_i_o id25}@anchor{2cf} @section Operations on C Streams @@ -22936,7 +22918,7 @@ end Interfaces.C_Streams; @end example @node Interfacing to C Streams,,Operations on C Streams,The Implementation of Standard I/O -@anchor{gnat_rm/the_implementation_of_standard_i_o interfacing-to-c-streams}@anchor{2d1}@anchor{gnat_rm/the_implementation_of_standard_i_o id26}@anchor{2d2} +@anchor{gnat_rm/the_implementation_of_standard_i_o interfacing-to-c-streams}@anchor{2d0}@anchor{gnat_rm/the_implementation_of_standard_i_o id26}@anchor{2d1} @section Interfacing to C Streams @@ -23029,7 +23011,7 @@ imported from a C program, allowing an Ada file to operate on an existing C file. @node The GNAT Library,Interfacing to Other Languages,The Implementation of Standard I/O,Top -@anchor{gnat_rm/the_gnat_library the-gnat-library}@anchor{10}@anchor{gnat_rm/the_gnat_library doc}@anchor{2d3}@anchor{gnat_rm/the_gnat_library id1}@anchor{2d4} +@anchor{gnat_rm/the_gnat_library the-gnat-library}@anchor{10}@anchor{gnat_rm/the_gnat_library doc}@anchor{2d2}@anchor{gnat_rm/the_gnat_library id1}@anchor{2d3} @chapter The GNAT Library @@ -23222,7 +23204,7 @@ of GNAT, and will generate a warning message. @end menu @node Ada Characters Latin_9 a-chlat9 ads,Ada Characters Wide_Latin_1 a-cwila1 ads,,The GNAT Library -@anchor{gnat_rm/the_gnat_library id2}@anchor{2d5}@anchor{gnat_rm/the_gnat_library ada-characters-latin-9-a-chlat9-ads}@anchor{2d6} +@anchor{gnat_rm/the_gnat_library id2}@anchor{2d4}@anchor{gnat_rm/the_gnat_library ada-characters-latin-9-a-chlat9-ads}@anchor{2d5} @section @code{Ada.Characters.Latin_9} (@code{a-chlat9.ads}) @@ -23239,7 +23221,7 @@ is specifically authorized by the Ada Reference Manual (RM A.3.3(27)). @node Ada Characters Wide_Latin_1 a-cwila1 ads,Ada Characters Wide_Latin_9 a-cwila1 ads,Ada Characters Latin_9 a-chlat9 ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-characters-wide-latin-1-a-cwila1-ads}@anchor{2d7}@anchor{gnat_rm/the_gnat_library id3}@anchor{2d8} +@anchor{gnat_rm/the_gnat_library ada-characters-wide-latin-1-a-cwila1-ads}@anchor{2d6}@anchor{gnat_rm/the_gnat_library id3}@anchor{2d7} @section @code{Ada.Characters.Wide_Latin_1} (@code{a-cwila1.ads}) @@ -23256,7 +23238,7 @@ is specifically authorized by the Ada Reference Manual (RM A.3.3(27)). @node Ada Characters Wide_Latin_9 a-cwila1 ads,Ada Characters Wide_Wide_Latin_1 a-chzla1 ads,Ada Characters Wide_Latin_1 a-cwila1 ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id4}@anchor{2d9}@anchor{gnat_rm/the_gnat_library ada-characters-wide-latin-9-a-cwila1-ads}@anchor{2da} +@anchor{gnat_rm/the_gnat_library id4}@anchor{2d8}@anchor{gnat_rm/the_gnat_library ada-characters-wide-latin-9-a-cwila1-ads}@anchor{2d9} @section @code{Ada.Characters.Wide_Latin_9} (@code{a-cwila1.ads}) @@ -23273,7 +23255,7 @@ is specifically authorized by the Ada Reference Manual (RM A.3.3(27)). @node Ada Characters Wide_Wide_Latin_1 a-chzla1 ads,Ada Characters Wide_Wide_Latin_9 a-chzla9 ads,Ada Characters Wide_Latin_9 a-cwila1 ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-characters-wide-wide-latin-1-a-chzla1-ads}@anchor{2db}@anchor{gnat_rm/the_gnat_library id5}@anchor{2dc} +@anchor{gnat_rm/the_gnat_library ada-characters-wide-wide-latin-1-a-chzla1-ads}@anchor{2da}@anchor{gnat_rm/the_gnat_library id5}@anchor{2db} @section @code{Ada.Characters.Wide_Wide_Latin_1} (@code{a-chzla1.ads}) @@ -23290,7 +23272,7 @@ is specifically authorized by the Ada Reference Manual (RM A.3.3(27)). @node Ada Characters Wide_Wide_Latin_9 a-chzla9 ads,Ada Containers Formal_Doubly_Linked_Lists a-cfdlli ads,Ada Characters Wide_Wide_Latin_1 a-chzla1 ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-characters-wide-wide-latin-9-a-chzla9-ads}@anchor{2dd}@anchor{gnat_rm/the_gnat_library id6}@anchor{2de} +@anchor{gnat_rm/the_gnat_library ada-characters-wide-wide-latin-9-a-chzla9-ads}@anchor{2dc}@anchor{gnat_rm/the_gnat_library id6}@anchor{2dd} @section @code{Ada.Characters.Wide_Wide_Latin_9} (@code{a-chzla9.ads}) @@ -23307,7 +23289,7 @@ is specifically authorized by the Ada Reference Manual (RM A.3.3(27)). @node Ada Containers Formal_Doubly_Linked_Lists a-cfdlli ads,Ada Containers Formal_Hashed_Maps a-cfhama ads,Ada Characters Wide_Wide_Latin_9 a-chzla9 ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id7}@anchor{2df}@anchor{gnat_rm/the_gnat_library ada-containers-formal-doubly-linked-lists-a-cfdlli-ads}@anchor{2e0} +@anchor{gnat_rm/the_gnat_library id7}@anchor{2de}@anchor{gnat_rm/the_gnat_library ada-containers-formal-doubly-linked-lists-a-cfdlli-ads}@anchor{2df} @section @code{Ada.Containers.Formal_Doubly_Linked_Lists} (@code{a-cfdlli.ads}) @@ -23326,7 +23308,7 @@ efficient version than the one defined in the standard. In particular it does not have the complex overhead required to detect cursor tampering. @node Ada Containers Formal_Hashed_Maps a-cfhama ads,Ada Containers Formal_Hashed_Sets a-cfhase ads,Ada Containers Formal_Doubly_Linked_Lists a-cfdlli ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id8}@anchor{2e1}@anchor{gnat_rm/the_gnat_library ada-containers-formal-hashed-maps-a-cfhama-ads}@anchor{2e2} +@anchor{gnat_rm/the_gnat_library id8}@anchor{2e0}@anchor{gnat_rm/the_gnat_library ada-containers-formal-hashed-maps-a-cfhama-ads}@anchor{2e1} @section @code{Ada.Containers.Formal_Hashed_Maps} (@code{a-cfhama.ads}) @@ -23345,7 +23327,7 @@ efficient version than the one defined in the standard. In particular it does not have the complex overhead required to detect cursor tampering. @node Ada Containers Formal_Hashed_Sets a-cfhase ads,Ada Containers Formal_Ordered_Maps a-cforma ads,Ada Containers Formal_Hashed_Maps a-cfhama ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id9}@anchor{2e3}@anchor{gnat_rm/the_gnat_library ada-containers-formal-hashed-sets-a-cfhase-ads}@anchor{2e4} +@anchor{gnat_rm/the_gnat_library id9}@anchor{2e2}@anchor{gnat_rm/the_gnat_library ada-containers-formal-hashed-sets-a-cfhase-ads}@anchor{2e3} @section @code{Ada.Containers.Formal_Hashed_Sets} (@code{a-cfhase.ads}) @@ -23364,7 +23346,7 @@ efficient version than the one defined in the standard. In particular it does not have the complex overhead required to detect cursor tampering. @node Ada Containers Formal_Ordered_Maps a-cforma ads,Ada Containers Formal_Ordered_Sets a-cforse ads,Ada Containers Formal_Hashed_Sets a-cfhase ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id10}@anchor{2e5}@anchor{gnat_rm/the_gnat_library ada-containers-formal-ordered-maps-a-cforma-ads}@anchor{2e6} +@anchor{gnat_rm/the_gnat_library id10}@anchor{2e4}@anchor{gnat_rm/the_gnat_library ada-containers-formal-ordered-maps-a-cforma-ads}@anchor{2e5} @section @code{Ada.Containers.Formal_Ordered_Maps} (@code{a-cforma.ads}) @@ -23383,7 +23365,7 @@ efficient version than the one defined in the standard. In particular it does not have the complex overhead required to detect cursor tampering. @node Ada Containers Formal_Ordered_Sets a-cforse ads,Ada Containers Formal_Vectors a-cofove ads,Ada Containers Formal_Ordered_Maps a-cforma ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-containers-formal-ordered-sets-a-cforse-ads}@anchor{2e7}@anchor{gnat_rm/the_gnat_library id11}@anchor{2e8} +@anchor{gnat_rm/the_gnat_library ada-containers-formal-ordered-sets-a-cforse-ads}@anchor{2e6}@anchor{gnat_rm/the_gnat_library id11}@anchor{2e7} @section @code{Ada.Containers.Formal_Ordered_Sets} (@code{a-cforse.ads}) @@ -23402,7 +23384,7 @@ efficient version than the one defined in the standard. In particular it does not have the complex overhead required to detect cursor tampering. @node Ada Containers Formal_Vectors a-cofove ads,Ada Containers Formal_Indefinite_Vectors a-cfinve ads,Ada Containers Formal_Ordered_Sets a-cforse ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id12}@anchor{2e9}@anchor{gnat_rm/the_gnat_library ada-containers-formal-vectors-a-cofove-ads}@anchor{2ea} +@anchor{gnat_rm/the_gnat_library id12}@anchor{2e8}@anchor{gnat_rm/the_gnat_library ada-containers-formal-vectors-a-cofove-ads}@anchor{2e9} @section @code{Ada.Containers.Formal_Vectors} (@code{a-cofove.ads}) @@ -23421,7 +23403,7 @@ efficient version than the one defined in the standard. In particular it does not have the complex overhead required to detect cursor tampering. @node Ada Containers Formal_Indefinite_Vectors a-cfinve ads,Ada Containers Functional_Vectors a-cofuve ads,Ada Containers Formal_Vectors a-cofove ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id13}@anchor{2eb}@anchor{gnat_rm/the_gnat_library ada-containers-formal-indefinite-vectors-a-cfinve-ads}@anchor{2ec} +@anchor{gnat_rm/the_gnat_library id13}@anchor{2ea}@anchor{gnat_rm/the_gnat_library ada-containers-formal-indefinite-vectors-a-cfinve-ads}@anchor{2eb} @section @code{Ada.Containers.Formal_Indefinite_Vectors} (@code{a-cfinve.ads}) @@ -23440,7 +23422,7 @@ efficient version than the one defined in the standard. In particular it does not have the complex overhead required to detect cursor tampering. @node Ada Containers Functional_Vectors a-cofuve ads,Ada Containers Functional_Sets a-cofuse ads,Ada Containers Formal_Indefinite_Vectors a-cfinve ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id14}@anchor{2ed}@anchor{gnat_rm/the_gnat_library ada-containers-functional-vectors-a-cofuve-ads}@anchor{2ee} +@anchor{gnat_rm/the_gnat_library id14}@anchor{2ec}@anchor{gnat_rm/the_gnat_library ada-containers-functional-vectors-a-cofuve-ads}@anchor{2ed} @section @code{Ada.Containers.Functional_Vectors} (@code{a-cofuve.ads}) @@ -23462,7 +23444,7 @@ and annotations, so that they can be removed from the final executable. The specification of this unit is compatible with SPARK 2014. @node Ada Containers Functional_Sets a-cofuse ads,Ada Containers Functional_Maps a-cofuma ads,Ada Containers Functional_Vectors a-cofuve ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-containers-functional-sets-a-cofuse-ads}@anchor{2ef}@anchor{gnat_rm/the_gnat_library id15}@anchor{2f0} +@anchor{gnat_rm/the_gnat_library ada-containers-functional-sets-a-cofuse-ads}@anchor{2ee}@anchor{gnat_rm/the_gnat_library id15}@anchor{2ef} @section @code{Ada.Containers.Functional_Sets} (@code{a-cofuse.ads}) @@ -23484,7 +23466,7 @@ and annotations, so that they can be removed from the final executable. The specification of this unit is compatible with SPARK 2014. @node Ada Containers Functional_Maps a-cofuma ads,Ada Containers Bounded_Holders a-coboho ads,Ada Containers Functional_Sets a-cofuse ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id16}@anchor{2f1}@anchor{gnat_rm/the_gnat_library ada-containers-functional-maps-a-cofuma-ads}@anchor{2f2} +@anchor{gnat_rm/the_gnat_library id16}@anchor{2f0}@anchor{gnat_rm/the_gnat_library ada-containers-functional-maps-a-cofuma-ads}@anchor{2f1} @section @code{Ada.Containers.Functional_Maps} (@code{a-cofuma.ads}) @@ -23506,7 +23488,7 @@ and annotations, so that they can be removed from the final executable. The specification of this unit is compatible with SPARK 2014. @node Ada Containers Bounded_Holders a-coboho ads,Ada Command_Line Environment a-colien ads,Ada Containers Functional_Maps a-cofuma ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-containers-bounded-holders-a-coboho-ads}@anchor{2f3}@anchor{gnat_rm/the_gnat_library id17}@anchor{2f4} +@anchor{gnat_rm/the_gnat_library ada-containers-bounded-holders-a-coboho-ads}@anchor{2f2}@anchor{gnat_rm/the_gnat_library id17}@anchor{2f3} @section @code{Ada.Containers.Bounded_Holders} (@code{a-coboho.ads}) @@ -23518,7 +23500,7 @@ This child of @code{Ada.Containers} defines a modified version of Indefinite_Holders that avoids heap allocation. @node Ada Command_Line Environment a-colien ads,Ada Command_Line Remove a-colire ads,Ada Containers Bounded_Holders a-coboho ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-command-line-environment-a-colien-ads}@anchor{2f5}@anchor{gnat_rm/the_gnat_library id18}@anchor{2f6} +@anchor{gnat_rm/the_gnat_library ada-command-line-environment-a-colien-ads}@anchor{2f4}@anchor{gnat_rm/the_gnat_library id18}@anchor{2f5} @section @code{Ada.Command_Line.Environment} (@code{a-colien.ads}) @@ -23531,7 +23513,7 @@ provides a mechanism for obtaining environment values on systems where this concept makes sense. @node Ada Command_Line Remove a-colire ads,Ada Command_Line Response_File a-clrefi ads,Ada Command_Line Environment a-colien ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id19}@anchor{2f7}@anchor{gnat_rm/the_gnat_library ada-command-line-remove-a-colire-ads}@anchor{2f8} +@anchor{gnat_rm/the_gnat_library id19}@anchor{2f6}@anchor{gnat_rm/the_gnat_library ada-command-line-remove-a-colire-ads}@anchor{2f7} @section @code{Ada.Command_Line.Remove} (@code{a-colire.ads}) @@ -23549,7 +23531,7 @@ to further calls on the subprograms in @code{Ada.Command_Line} will not see the removed argument. @node Ada Command_Line Response_File a-clrefi ads,Ada Direct_IO C_Streams a-diocst ads,Ada Command_Line Remove a-colire ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id20}@anchor{2f9}@anchor{gnat_rm/the_gnat_library ada-command-line-response-file-a-clrefi-ads}@anchor{2fa} +@anchor{gnat_rm/the_gnat_library id20}@anchor{2f8}@anchor{gnat_rm/the_gnat_library ada-command-line-response-file-a-clrefi-ads}@anchor{2f9} @section @code{Ada.Command_Line.Response_File} (@code{a-clrefi.ads}) @@ -23569,7 +23551,7 @@ Using a response file allow passing a set of arguments to an executable longer than the maximum allowed by the system on the command line. @node Ada Direct_IO C_Streams a-diocst ads,Ada Exceptions Is_Null_Occurrence a-einuoc ads,Ada Command_Line Response_File a-clrefi ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id21}@anchor{2fb}@anchor{gnat_rm/the_gnat_library ada-direct-io-c-streams-a-diocst-ads}@anchor{2fc} +@anchor{gnat_rm/the_gnat_library id21}@anchor{2fa}@anchor{gnat_rm/the_gnat_library ada-direct-io-c-streams-a-diocst-ads}@anchor{2fb} @section @code{Ada.Direct_IO.C_Streams} (@code{a-diocst.ads}) @@ -23584,7 +23566,7 @@ extracted from a file opened on the Ada side, and an Ada file can be constructed from a stream opened on the C side. @node Ada Exceptions Is_Null_Occurrence a-einuoc ads,Ada Exceptions Last_Chance_Handler a-elchha ads,Ada Direct_IO C_Streams a-diocst ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id22}@anchor{2fd}@anchor{gnat_rm/the_gnat_library ada-exceptions-is-null-occurrence-a-einuoc-ads}@anchor{2fe} +@anchor{gnat_rm/the_gnat_library id22}@anchor{2fc}@anchor{gnat_rm/the_gnat_library ada-exceptions-is-null-occurrence-a-einuoc-ads}@anchor{2fd} @section @code{Ada.Exceptions.Is_Null_Occurrence} (@code{a-einuoc.ads}) @@ -23598,7 +23580,7 @@ exception occurrence (@code{Null_Occurrence}) without raising an exception. @node Ada Exceptions Last_Chance_Handler a-elchha ads,Ada Exceptions Traceback a-exctra ads,Ada Exceptions Is_Null_Occurrence a-einuoc ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id23}@anchor{2ff}@anchor{gnat_rm/the_gnat_library ada-exceptions-last-chance-handler-a-elchha-ads}@anchor{300} +@anchor{gnat_rm/the_gnat_library id23}@anchor{2fe}@anchor{gnat_rm/the_gnat_library ada-exceptions-last-chance-handler-a-elchha-ads}@anchor{2ff} @section @code{Ada.Exceptions.Last_Chance_Handler} (@code{a-elchha.ads}) @@ -23612,7 +23594,7 @@ exceptions (hence the name last chance), and perform clean ups before terminating the program. Note that this subprogram never returns. @node Ada Exceptions Traceback a-exctra ads,Ada Sequential_IO C_Streams a-siocst ads,Ada Exceptions Last_Chance_Handler a-elchha ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-exceptions-traceback-a-exctra-ads}@anchor{301}@anchor{gnat_rm/the_gnat_library id24}@anchor{302} +@anchor{gnat_rm/the_gnat_library ada-exceptions-traceback-a-exctra-ads}@anchor{300}@anchor{gnat_rm/the_gnat_library id24}@anchor{301} @section @code{Ada.Exceptions.Traceback} (@code{a-exctra.ads}) @@ -23625,7 +23607,7 @@ give a traceback array of addresses based on an exception occurrence. @node Ada Sequential_IO C_Streams a-siocst ads,Ada Streams Stream_IO C_Streams a-ssicst ads,Ada Exceptions Traceback a-exctra ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-sequential-io-c-streams-a-siocst-ads}@anchor{303}@anchor{gnat_rm/the_gnat_library id25}@anchor{304} +@anchor{gnat_rm/the_gnat_library ada-sequential-io-c-streams-a-siocst-ads}@anchor{302}@anchor{gnat_rm/the_gnat_library id25}@anchor{303} @section @code{Ada.Sequential_IO.C_Streams} (@code{a-siocst.ads}) @@ -23640,7 +23622,7 @@ extracted from a file opened on the Ada side, and an Ada file can be constructed from a stream opened on the C side. @node Ada Streams Stream_IO C_Streams a-ssicst ads,Ada Strings Unbounded Text_IO a-suteio ads,Ada Sequential_IO C_Streams a-siocst ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id26}@anchor{305}@anchor{gnat_rm/the_gnat_library ada-streams-stream-io-c-streams-a-ssicst-ads}@anchor{306} +@anchor{gnat_rm/the_gnat_library id26}@anchor{304}@anchor{gnat_rm/the_gnat_library ada-streams-stream-io-c-streams-a-ssicst-ads}@anchor{305} @section @code{Ada.Streams.Stream_IO.C_Streams} (@code{a-ssicst.ads}) @@ -23655,7 +23637,7 @@ extracted from a file opened on the Ada side, and an Ada file can be constructed from a stream opened on the C side. @node Ada Strings Unbounded Text_IO a-suteio ads,Ada Strings Wide_Unbounded Wide_Text_IO a-swuwti ads,Ada Streams Stream_IO C_Streams a-ssicst ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-strings-unbounded-text-io-a-suteio-ads}@anchor{307}@anchor{gnat_rm/the_gnat_library id27}@anchor{308} +@anchor{gnat_rm/the_gnat_library ada-strings-unbounded-text-io-a-suteio-ads}@anchor{306}@anchor{gnat_rm/the_gnat_library id27}@anchor{307} @section @code{Ada.Strings.Unbounded.Text_IO} (@code{a-suteio.ads}) @@ -23672,7 +23654,7 @@ strings, avoiding the necessity for an intermediate operation with ordinary strings. @node Ada Strings Wide_Unbounded Wide_Text_IO a-swuwti ads,Ada Strings Wide_Wide_Unbounded Wide_Wide_Text_IO a-szuzti ads,Ada Strings Unbounded Text_IO a-suteio ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id28}@anchor{309}@anchor{gnat_rm/the_gnat_library ada-strings-wide-unbounded-wide-text-io-a-swuwti-ads}@anchor{30a} +@anchor{gnat_rm/the_gnat_library id28}@anchor{308}@anchor{gnat_rm/the_gnat_library ada-strings-wide-unbounded-wide-text-io-a-swuwti-ads}@anchor{309} @section @code{Ada.Strings.Wide_Unbounded.Wide_Text_IO} (@code{a-swuwti.ads}) @@ -23689,7 +23671,7 @@ wide strings, avoiding the necessity for an intermediate operation with ordinary wide strings. @node Ada Strings Wide_Wide_Unbounded Wide_Wide_Text_IO a-szuzti ads,Ada Text_IO C_Streams a-tiocst ads,Ada Strings Wide_Unbounded Wide_Text_IO a-swuwti ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id29}@anchor{30b}@anchor{gnat_rm/the_gnat_library ada-strings-wide-wide-unbounded-wide-wide-text-io-a-szuzti-ads}@anchor{30c} +@anchor{gnat_rm/the_gnat_library id29}@anchor{30a}@anchor{gnat_rm/the_gnat_library ada-strings-wide-wide-unbounded-wide-wide-text-io-a-szuzti-ads}@anchor{30b} @section @code{Ada.Strings.Wide_Wide_Unbounded.Wide_Wide_Text_IO} (@code{a-szuzti.ads}) @@ -23706,7 +23688,7 @@ wide wide strings, avoiding the necessity for an intermediate operation with ordinary wide wide strings. @node Ada Text_IO C_Streams a-tiocst ads,Ada Text_IO Reset_Standard_Files a-tirsfi ads,Ada Strings Wide_Wide_Unbounded Wide_Wide_Text_IO a-szuzti ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-text-io-c-streams-a-tiocst-ads}@anchor{30d}@anchor{gnat_rm/the_gnat_library id30}@anchor{30e} +@anchor{gnat_rm/the_gnat_library ada-text-io-c-streams-a-tiocst-ads}@anchor{30c}@anchor{gnat_rm/the_gnat_library id30}@anchor{30d} @section @code{Ada.Text_IO.C_Streams} (@code{a-tiocst.ads}) @@ -23721,7 +23703,7 @@ extracted from a file opened on the Ada side, and an Ada file can be constructed from a stream opened on the C side. @node Ada Text_IO Reset_Standard_Files a-tirsfi ads,Ada Wide_Characters Unicode a-wichun ads,Ada Text_IO C_Streams a-tiocst ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-text-io-reset-standard-files-a-tirsfi-ads}@anchor{30f}@anchor{gnat_rm/the_gnat_library id31}@anchor{310} +@anchor{gnat_rm/the_gnat_library ada-text-io-reset-standard-files-a-tirsfi-ads}@anchor{30e}@anchor{gnat_rm/the_gnat_library id31}@anchor{30f} @section @code{Ada.Text_IO.Reset_Standard_Files} (@code{a-tirsfi.ads}) @@ -23736,7 +23718,7 @@ execution (for example a standard input file may be redefined to be interactive). @node Ada Wide_Characters Unicode a-wichun ads,Ada Wide_Text_IO C_Streams a-wtcstr ads,Ada Text_IO Reset_Standard_Files a-tirsfi ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id32}@anchor{311}@anchor{gnat_rm/the_gnat_library ada-wide-characters-unicode-a-wichun-ads}@anchor{312} +@anchor{gnat_rm/the_gnat_library id32}@anchor{310}@anchor{gnat_rm/the_gnat_library ada-wide-characters-unicode-a-wichun-ads}@anchor{311} @section @code{Ada.Wide_Characters.Unicode} (@code{a-wichun.ads}) @@ -23749,7 +23731,7 @@ This package provides subprograms that allow categorization of Wide_Character values according to Unicode categories. @node Ada Wide_Text_IO C_Streams a-wtcstr ads,Ada Wide_Text_IO Reset_Standard_Files a-wrstfi ads,Ada Wide_Characters Unicode a-wichun ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-wide-text-io-c-streams-a-wtcstr-ads}@anchor{313}@anchor{gnat_rm/the_gnat_library id33}@anchor{314} +@anchor{gnat_rm/the_gnat_library ada-wide-text-io-c-streams-a-wtcstr-ads}@anchor{312}@anchor{gnat_rm/the_gnat_library id33}@anchor{313} @section @code{Ada.Wide_Text_IO.C_Streams} (@code{a-wtcstr.ads}) @@ -23764,7 +23746,7 @@ extracted from a file opened on the Ada side, and an Ada file can be constructed from a stream opened on the C side. @node Ada Wide_Text_IO Reset_Standard_Files a-wrstfi ads,Ada Wide_Wide_Characters Unicode a-zchuni ads,Ada Wide_Text_IO C_Streams a-wtcstr ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library ada-wide-text-io-reset-standard-files-a-wrstfi-ads}@anchor{315}@anchor{gnat_rm/the_gnat_library id34}@anchor{316} +@anchor{gnat_rm/the_gnat_library ada-wide-text-io-reset-standard-files-a-wrstfi-ads}@anchor{314}@anchor{gnat_rm/the_gnat_library id34}@anchor{315} @section @code{Ada.Wide_Text_IO.Reset_Standard_Files} (@code{a-wrstfi.ads}) @@ -23779,7 +23761,7 @@ execution (for example a standard input file may be redefined to be interactive). @node Ada Wide_Wide_Characters Unicode a-zchuni ads,Ada Wide_Wide_Text_IO C_Streams a-ztcstr ads,Ada Wide_Text_IO Reset_Standard_Files a-wrstfi ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id35}@anchor{317}@anchor{gnat_rm/the_gnat_library ada-wide-wide-characters-unicode-a-zchuni-ads}@anchor{318} +@anchor{gnat_rm/the_gnat_library id35}@anchor{316}@anchor{gnat_rm/the_gnat_library ada-wide-wide-characters-unicode-a-zchuni-ads}@anchor{317} @section @code{Ada.Wide_Wide_Characters.Unicode} (@code{a-zchuni.ads}) @@ -23792,7 +23774,7 @@ This package provides subprograms that allow categorization of Wide_Wide_Character values according to Unicode categories. @node Ada Wide_Wide_Text_IO C_Streams a-ztcstr ads,Ada Wide_Wide_Text_IO Reset_Standard_Files a-zrstfi ads,Ada Wide_Wide_Characters Unicode a-zchuni ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id36}@anchor{319}@anchor{gnat_rm/the_gnat_library ada-wide-wide-text-io-c-streams-a-ztcstr-ads}@anchor{31a} +@anchor{gnat_rm/the_gnat_library id36}@anchor{318}@anchor{gnat_rm/the_gnat_library ada-wide-wide-text-io-c-streams-a-ztcstr-ads}@anchor{319} @section @code{Ada.Wide_Wide_Text_IO.C_Streams} (@code{a-ztcstr.ads}) @@ -23807,7 +23789,7 @@ extracted from a file opened on the Ada side, and an Ada file can be constructed from a stream opened on the C side. @node Ada Wide_Wide_Text_IO Reset_Standard_Files a-zrstfi ads,GNAT Altivec g-altive ads,Ada Wide_Wide_Text_IO C_Streams a-ztcstr ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id37}@anchor{31b}@anchor{gnat_rm/the_gnat_library ada-wide-wide-text-io-reset-standard-files-a-zrstfi-ads}@anchor{31c} +@anchor{gnat_rm/the_gnat_library id37}@anchor{31a}@anchor{gnat_rm/the_gnat_library ada-wide-wide-text-io-reset-standard-files-a-zrstfi-ads}@anchor{31b} @section @code{Ada.Wide_Wide_Text_IO.Reset_Standard_Files} (@code{a-zrstfi.ads}) @@ -23822,7 +23804,7 @@ change during execution (for example a standard input file may be redefined to be interactive). @node GNAT Altivec g-altive ads,GNAT Altivec Conversions g-altcon ads,Ada Wide_Wide_Text_IO Reset_Standard_Files a-zrstfi ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-altivec-g-altive-ads}@anchor{31d}@anchor{gnat_rm/the_gnat_library id38}@anchor{31e} +@anchor{gnat_rm/the_gnat_library gnat-altivec-g-altive-ads}@anchor{31c}@anchor{gnat_rm/the_gnat_library id38}@anchor{31d} @section @code{GNAT.Altivec} (@code{g-altive.ads}) @@ -23835,7 +23817,7 @@ definitions of constants and types common to all the versions of the binding. @node GNAT Altivec Conversions g-altcon ads,GNAT Altivec Vector_Operations g-alveop ads,GNAT Altivec g-altive ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-altivec-conversions-g-altcon-ads}@anchor{31f}@anchor{gnat_rm/the_gnat_library id39}@anchor{320} +@anchor{gnat_rm/the_gnat_library gnat-altivec-conversions-g-altcon-ads}@anchor{31e}@anchor{gnat_rm/the_gnat_library id39}@anchor{31f} @section @code{GNAT.Altivec.Conversions} (@code{g-altcon.ads}) @@ -23846,7 +23828,7 @@ binding. This package provides the Vector/View conversion routines. @node GNAT Altivec Vector_Operations g-alveop ads,GNAT Altivec Vector_Types g-alvety ads,GNAT Altivec Conversions g-altcon ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-operations-g-alveop-ads}@anchor{321}@anchor{gnat_rm/the_gnat_library id40}@anchor{322} +@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-operations-g-alveop-ads}@anchor{320}@anchor{gnat_rm/the_gnat_library id40}@anchor{321} @section @code{GNAT.Altivec.Vector_Operations} (@code{g-alveop.ads}) @@ -23860,7 +23842,7 @@ library. The hard binding is provided as a separate package. This unit is common to both bindings. @node GNAT Altivec Vector_Types g-alvety ads,GNAT Altivec Vector_Views g-alvevi ads,GNAT Altivec Vector_Operations g-alveop ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-types-g-alvety-ads}@anchor{323}@anchor{gnat_rm/the_gnat_library id41}@anchor{324} +@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-types-g-alvety-ads}@anchor{322}@anchor{gnat_rm/the_gnat_library id41}@anchor{323} @section @code{GNAT.Altivec.Vector_Types} (@code{g-alvety.ads}) @@ -23872,7 +23854,7 @@ This package exposes the various vector types part of the Ada binding to AltiVec facilities. @node GNAT Altivec Vector_Views g-alvevi ads,GNAT Array_Split g-arrspl ads,GNAT Altivec Vector_Types g-alvety ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-views-g-alvevi-ads}@anchor{325}@anchor{gnat_rm/the_gnat_library id42}@anchor{326} +@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-views-g-alvevi-ads}@anchor{324}@anchor{gnat_rm/the_gnat_library id42}@anchor{325} @section @code{GNAT.Altivec.Vector_Views} (@code{g-alvevi.ads}) @@ -23887,7 +23869,7 @@ vector elements and provides a simple way to initialize vector objects. @node GNAT Array_Split g-arrspl ads,GNAT AWK g-awk ads,GNAT Altivec Vector_Views g-alvevi ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-array-split-g-arrspl-ads}@anchor{327}@anchor{gnat_rm/the_gnat_library id43}@anchor{328} +@anchor{gnat_rm/the_gnat_library gnat-array-split-g-arrspl-ads}@anchor{326}@anchor{gnat_rm/the_gnat_library id43}@anchor{327} @section @code{GNAT.Array_Split} (@code{g-arrspl.ads}) @@ -23900,7 +23882,7 @@ an array wherever the separators appear, and provide direct access to the resulting slices. @node GNAT AWK g-awk ads,GNAT Bind_Environment g-binenv ads,GNAT Array_Split g-arrspl ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id44}@anchor{329}@anchor{gnat_rm/the_gnat_library gnat-awk-g-awk-ads}@anchor{32a} +@anchor{gnat_rm/the_gnat_library id44}@anchor{328}@anchor{gnat_rm/the_gnat_library gnat-awk-g-awk-ads}@anchor{329} @section @code{GNAT.AWK} (@code{g-awk.ads}) @@ -23915,7 +23897,7 @@ or more files containing formatted data. The file is viewed as a database where each record is a line and a field is a data element in this line. @node GNAT Bind_Environment g-binenv ads,GNAT Branch_Prediction g-brapre ads,GNAT AWK g-awk ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-bind-environment-g-binenv-ads}@anchor{32b}@anchor{gnat_rm/the_gnat_library id45}@anchor{32c} +@anchor{gnat_rm/the_gnat_library gnat-bind-environment-g-binenv-ads}@anchor{32a}@anchor{gnat_rm/the_gnat_library id45}@anchor{32b} @section @code{GNAT.Bind_Environment} (@code{g-binenv.ads}) @@ -23928,7 +23910,7 @@ These associations can be specified using the @code{-V} binder command line switch. @node GNAT Branch_Prediction g-brapre ads,GNAT Bounded_Buffers g-boubuf ads,GNAT Bind_Environment g-binenv ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id46}@anchor{32d}@anchor{gnat_rm/the_gnat_library gnat-branch-prediction-g-brapre-ads}@anchor{32e} +@anchor{gnat_rm/the_gnat_library id46}@anchor{32c}@anchor{gnat_rm/the_gnat_library gnat-branch-prediction-g-brapre-ads}@anchor{32d} @section @code{GNAT.Branch_Prediction} (@code{g-brapre.ads}) @@ -23939,7 +23921,7 @@ line switch. Provides routines giving hints to the branch predictor of the code generator. @node GNAT Bounded_Buffers g-boubuf ads,GNAT Bounded_Mailboxes g-boumai ads,GNAT Branch_Prediction g-brapre ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id47}@anchor{32f}@anchor{gnat_rm/the_gnat_library gnat-bounded-buffers-g-boubuf-ads}@anchor{330} +@anchor{gnat_rm/the_gnat_library id47}@anchor{32e}@anchor{gnat_rm/the_gnat_library gnat-bounded-buffers-g-boubuf-ads}@anchor{32f} @section @code{GNAT.Bounded_Buffers} (@code{g-boubuf.ads}) @@ -23954,7 +23936,7 @@ useful directly or as parts of the implementations of other abstractions, such as mailboxes. @node GNAT Bounded_Mailboxes g-boumai ads,GNAT Bubble_Sort g-bubsor ads,GNAT Bounded_Buffers g-boubuf ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-bounded-mailboxes-g-boumai-ads}@anchor{331}@anchor{gnat_rm/the_gnat_library id48}@anchor{332} +@anchor{gnat_rm/the_gnat_library gnat-bounded-mailboxes-g-boumai-ads}@anchor{330}@anchor{gnat_rm/the_gnat_library id48}@anchor{331} @section @code{GNAT.Bounded_Mailboxes} (@code{g-boumai.ads}) @@ -23967,7 +23949,7 @@ such as mailboxes. Provides a thread-safe asynchronous intertask mailbox communication facility. @node GNAT Bubble_Sort g-bubsor ads,GNAT Bubble_Sort_A g-busora ads,GNAT Bounded_Mailboxes g-boumai ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-g-bubsor-ads}@anchor{333}@anchor{gnat_rm/the_gnat_library id49}@anchor{334} +@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-g-bubsor-ads}@anchor{332}@anchor{gnat_rm/the_gnat_library id49}@anchor{333} @section @code{GNAT.Bubble_Sort} (@code{g-bubsor.ads}) @@ -23982,7 +23964,7 @@ data items. Exchange and comparison procedures are provided by passing access-to-procedure values. @node GNAT Bubble_Sort_A g-busora ads,GNAT Bubble_Sort_G g-busorg ads,GNAT Bubble_Sort g-bubsor ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id50}@anchor{335}@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-a-g-busora-ads}@anchor{336} +@anchor{gnat_rm/the_gnat_library id50}@anchor{334}@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-a-g-busora-ads}@anchor{335} @section @code{GNAT.Bubble_Sort_A} (@code{g-busora.ads}) @@ -23998,7 +23980,7 @@ access-to-procedure values. This is an older version, retained for compatibility. Usually @code{GNAT.Bubble_Sort} will be preferable. @node GNAT Bubble_Sort_G g-busorg ads,GNAT Byte_Order_Mark g-byorma ads,GNAT Bubble_Sort_A g-busora ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-g-g-busorg-ads}@anchor{337}@anchor{gnat_rm/the_gnat_library id51}@anchor{338} +@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-g-g-busorg-ads}@anchor{336}@anchor{gnat_rm/the_gnat_library id51}@anchor{337} @section @code{GNAT.Bubble_Sort_G} (@code{g-busorg.ads}) @@ -24014,7 +23996,7 @@ if the procedures can be inlined, at the expense of duplicating code for multiple instantiations. @node GNAT Byte_Order_Mark g-byorma ads,GNAT Byte_Swapping g-bytswa ads,GNAT Bubble_Sort_G g-busorg ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-byte-order-mark-g-byorma-ads}@anchor{339}@anchor{gnat_rm/the_gnat_library id52}@anchor{33a} +@anchor{gnat_rm/the_gnat_library gnat-byte-order-mark-g-byorma-ads}@anchor{338}@anchor{gnat_rm/the_gnat_library id52}@anchor{339} @section @code{GNAT.Byte_Order_Mark} (@code{g-byorma.ads}) @@ -24030,7 +24012,7 @@ the encoding of the string. The routine includes detection of special XML sequences for various UCS input formats. @node GNAT Byte_Swapping g-bytswa ads,GNAT Calendar g-calend ads,GNAT Byte_Order_Mark g-byorma ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-byte-swapping-g-bytswa-ads}@anchor{33b}@anchor{gnat_rm/the_gnat_library id53}@anchor{33c} +@anchor{gnat_rm/the_gnat_library gnat-byte-swapping-g-bytswa-ads}@anchor{33a}@anchor{gnat_rm/the_gnat_library id53}@anchor{33b} @section @code{GNAT.Byte_Swapping} (@code{g-bytswa.ads}) @@ -24044,7 +24026,7 @@ General routines for swapping the bytes in 2-, 4-, and 8-byte quantities. Machine-specific implementations are available in some cases. @node GNAT Calendar g-calend ads,GNAT Calendar Time_IO g-catiio ads,GNAT Byte_Swapping g-bytswa ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id54}@anchor{33d}@anchor{gnat_rm/the_gnat_library gnat-calendar-g-calend-ads}@anchor{33e} +@anchor{gnat_rm/the_gnat_library id54}@anchor{33c}@anchor{gnat_rm/the_gnat_library gnat-calendar-g-calend-ads}@anchor{33d} @section @code{GNAT.Calendar} (@code{g-calend.ads}) @@ -24058,7 +24040,7 @@ Also provides conversion of @code{Ada.Calendar.Time} values to and from the C @code{timeval} format. @node GNAT Calendar Time_IO g-catiio ads,GNAT CRC32 g-crc32 ads,GNAT Calendar g-calend ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id55}@anchor{33f}@anchor{gnat_rm/the_gnat_library gnat-calendar-time-io-g-catiio-ads}@anchor{340} +@anchor{gnat_rm/the_gnat_library id55}@anchor{33e}@anchor{gnat_rm/the_gnat_library gnat-calendar-time-io-g-catiio-ads}@anchor{33f} @section @code{GNAT.Calendar.Time_IO} (@code{g-catiio.ads}) @@ -24069,7 +24051,7 @@ C @code{timeval} format. @geindex GNAT.Calendar.Time_IO (g-catiio.ads) @node GNAT CRC32 g-crc32 ads,GNAT Case_Util g-casuti ads,GNAT Calendar Time_IO g-catiio ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id56}@anchor{341}@anchor{gnat_rm/the_gnat_library gnat-crc32-g-crc32-ads}@anchor{342} +@anchor{gnat_rm/the_gnat_library id56}@anchor{340}@anchor{gnat_rm/the_gnat_library gnat-crc32-g-crc32-ads}@anchor{341} @section @code{GNAT.CRC32} (@code{g-crc32.ads}) @@ -24086,7 +24068,7 @@ of this algorithm see Aug. 1988. Sarwate, D.V. @node GNAT Case_Util g-casuti ads,GNAT CGI g-cgi ads,GNAT CRC32 g-crc32 ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id57}@anchor{343}@anchor{gnat_rm/the_gnat_library gnat-case-util-g-casuti-ads}@anchor{344} +@anchor{gnat_rm/the_gnat_library id57}@anchor{342}@anchor{gnat_rm/the_gnat_library gnat-case-util-g-casuti-ads}@anchor{343} @section @code{GNAT.Case_Util} (@code{g-casuti.ads}) @@ -24101,7 +24083,7 @@ without the overhead of the full casing tables in @code{Ada.Characters.Handling}. @node GNAT CGI g-cgi ads,GNAT CGI Cookie g-cgicoo ads,GNAT Case_Util g-casuti ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id58}@anchor{345}@anchor{gnat_rm/the_gnat_library gnat-cgi-g-cgi-ads}@anchor{346} +@anchor{gnat_rm/the_gnat_library id58}@anchor{344}@anchor{gnat_rm/the_gnat_library gnat-cgi-g-cgi-ads}@anchor{345} @section @code{GNAT.CGI} (@code{g-cgi.ads}) @@ -24116,7 +24098,7 @@ builds a table whose index is the key and provides some services to deal with this table. @node GNAT CGI Cookie g-cgicoo ads,GNAT CGI Debug g-cgideb ads,GNAT CGI g-cgi ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-cgi-cookie-g-cgicoo-ads}@anchor{347}@anchor{gnat_rm/the_gnat_library id59}@anchor{348} +@anchor{gnat_rm/the_gnat_library gnat-cgi-cookie-g-cgicoo-ads}@anchor{346}@anchor{gnat_rm/the_gnat_library id59}@anchor{347} @section @code{GNAT.CGI.Cookie} (@code{g-cgicoo.ads}) @@ -24131,7 +24113,7 @@ Common Gateway Interface (CGI). It exports services to deal with Web cookies (piece of information kept in the Web client software). @node GNAT CGI Debug g-cgideb ads,GNAT Command_Line g-comlin ads,GNAT CGI Cookie g-cgicoo ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-cgi-debug-g-cgideb-ads}@anchor{349}@anchor{gnat_rm/the_gnat_library id60}@anchor{34a} +@anchor{gnat_rm/the_gnat_library gnat-cgi-debug-g-cgideb-ads}@anchor{348}@anchor{gnat_rm/the_gnat_library id60}@anchor{349} @section @code{GNAT.CGI.Debug} (@code{g-cgideb.ads}) @@ -24143,7 +24125,7 @@ This is a package to help debugging CGI (Common Gateway Interface) programs written in Ada. @node GNAT Command_Line g-comlin ads,GNAT Compiler_Version g-comver ads,GNAT CGI Debug g-cgideb ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id61}@anchor{34b}@anchor{gnat_rm/the_gnat_library gnat-command-line-g-comlin-ads}@anchor{34c} +@anchor{gnat_rm/the_gnat_library id61}@anchor{34a}@anchor{gnat_rm/the_gnat_library gnat-command-line-g-comlin-ads}@anchor{34b} @section @code{GNAT.Command_Line} (@code{g-comlin.ads}) @@ -24156,7 +24138,7 @@ including the ability to scan for named switches with optional parameters and expand file names using wildcard notations. @node GNAT Compiler_Version g-comver ads,GNAT Ctrl_C g-ctrl_c ads,GNAT Command_Line g-comlin ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-compiler-version-g-comver-ads}@anchor{34d}@anchor{gnat_rm/the_gnat_library id62}@anchor{34e} +@anchor{gnat_rm/the_gnat_library gnat-compiler-version-g-comver-ads}@anchor{34c}@anchor{gnat_rm/the_gnat_library id62}@anchor{34d} @section @code{GNAT.Compiler_Version} (@code{g-comver.ads}) @@ -24174,7 +24156,7 @@ of the compiler if a consistent tool set is used to compile all units of a partition). @node GNAT Ctrl_C g-ctrl_c ads,GNAT Current_Exception g-curexc ads,GNAT Compiler_Version g-comver ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-ctrl-c-g-ctrl-c-ads}@anchor{34f}@anchor{gnat_rm/the_gnat_library id63}@anchor{350} +@anchor{gnat_rm/the_gnat_library gnat-ctrl-c-g-ctrl-c-ads}@anchor{34e}@anchor{gnat_rm/the_gnat_library id63}@anchor{34f} @section @code{GNAT.Ctrl_C} (@code{g-ctrl_c.ads}) @@ -24185,7 +24167,7 @@ of a partition). Provides a simple interface to handle Ctrl-C keyboard events. @node GNAT Current_Exception g-curexc ads,GNAT Debug_Pools g-debpoo ads,GNAT Ctrl_C g-ctrl_c ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id64}@anchor{351}@anchor{gnat_rm/the_gnat_library gnat-current-exception-g-curexc-ads}@anchor{352} +@anchor{gnat_rm/the_gnat_library id64}@anchor{350}@anchor{gnat_rm/the_gnat_library gnat-current-exception-g-curexc-ads}@anchor{351} @section @code{GNAT.Current_Exception} (@code{g-curexc.ads}) @@ -24202,7 +24184,7 @@ This is particularly useful in simulating typical facilities for obtaining information about exceptions provided by Ada 83 compilers. @node GNAT Debug_Pools g-debpoo ads,GNAT Debug_Utilities g-debuti ads,GNAT Current_Exception g-curexc ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-debug-pools-g-debpoo-ads}@anchor{353}@anchor{gnat_rm/the_gnat_library id65}@anchor{354} +@anchor{gnat_rm/the_gnat_library gnat-debug-pools-g-debpoo-ads}@anchor{352}@anchor{gnat_rm/the_gnat_library id65}@anchor{353} @section @code{GNAT.Debug_Pools} (@code{g-debpoo.ads}) @@ -24219,7 +24201,7 @@ problems. See @code{The GNAT Debug_Pool Facility} section in the @cite{GNAT User's Guide}. @node GNAT Debug_Utilities g-debuti ads,GNAT Decode_String g-decstr ads,GNAT Debug_Pools g-debpoo ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-debug-utilities-g-debuti-ads}@anchor{355}@anchor{gnat_rm/the_gnat_library id66}@anchor{356} +@anchor{gnat_rm/the_gnat_library gnat-debug-utilities-g-debuti-ads}@anchor{354}@anchor{gnat_rm/the_gnat_library id66}@anchor{355} @section @code{GNAT.Debug_Utilities} (@code{g-debuti.ads}) @@ -24232,7 +24214,7 @@ to and from string images of address values. Supports both C and Ada formats for hexadecimal literals. @node GNAT Decode_String g-decstr ads,GNAT Decode_UTF8_String g-deutst ads,GNAT Debug_Utilities g-debuti ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id67}@anchor{357}@anchor{gnat_rm/the_gnat_library gnat-decode-string-g-decstr-ads}@anchor{358} +@anchor{gnat_rm/the_gnat_library id67}@anchor{356}@anchor{gnat_rm/the_gnat_library gnat-decode-string-g-decstr-ads}@anchor{357} @section @code{GNAT.Decode_String} (@code{g-decstr.ads}) @@ -24256,7 +24238,7 @@ Useful in conjunction with Unicode character coding. Note there is a preinstantiation for UTF-8. See next entry. @node GNAT Decode_UTF8_String g-deutst ads,GNAT Directory_Operations g-dirope ads,GNAT Decode_String g-decstr ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-decode-utf8-string-g-deutst-ads}@anchor{359}@anchor{gnat_rm/the_gnat_library id68}@anchor{35a} +@anchor{gnat_rm/the_gnat_library gnat-decode-utf8-string-g-deutst-ads}@anchor{358}@anchor{gnat_rm/the_gnat_library id68}@anchor{359} @section @code{GNAT.Decode_UTF8_String} (@code{g-deutst.ads}) @@ -24277,7 +24259,7 @@ preinstantiation for UTF-8. See next entry. A preinstantiation of GNAT.Decode_Strings for UTF-8 encoding. @node GNAT Directory_Operations g-dirope ads,GNAT Directory_Operations Iteration g-diopit ads,GNAT Decode_UTF8_String g-deutst ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id69}@anchor{35b}@anchor{gnat_rm/the_gnat_library gnat-directory-operations-g-dirope-ads}@anchor{35c} +@anchor{gnat_rm/the_gnat_library id69}@anchor{35a}@anchor{gnat_rm/the_gnat_library gnat-directory-operations-g-dirope-ads}@anchor{35b} @section @code{GNAT.Directory_Operations} (@code{g-dirope.ads}) @@ -24290,7 +24272,7 @@ the current directory, making new directories, and scanning the files in a directory. @node GNAT Directory_Operations Iteration g-diopit ads,GNAT Dynamic_HTables g-dynhta ads,GNAT Directory_Operations g-dirope ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id70}@anchor{35d}@anchor{gnat_rm/the_gnat_library gnat-directory-operations-iteration-g-diopit-ads}@anchor{35e} +@anchor{gnat_rm/the_gnat_library id70}@anchor{35c}@anchor{gnat_rm/the_gnat_library gnat-directory-operations-iteration-g-diopit-ads}@anchor{35d} @section @code{GNAT.Directory_Operations.Iteration} (@code{g-diopit.ads}) @@ -24302,7 +24284,7 @@ A child unit of GNAT.Directory_Operations providing additional operations for iterating through directories. @node GNAT Dynamic_HTables g-dynhta ads,GNAT Dynamic_Tables g-dyntab ads,GNAT Directory_Operations Iteration g-diopit ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id71}@anchor{35f}@anchor{gnat_rm/the_gnat_library gnat-dynamic-htables-g-dynhta-ads}@anchor{360} +@anchor{gnat_rm/the_gnat_library id71}@anchor{35e}@anchor{gnat_rm/the_gnat_library gnat-dynamic-htables-g-dynhta-ads}@anchor{35f} @section @code{GNAT.Dynamic_HTables} (@code{g-dynhta.ads}) @@ -24320,7 +24302,7 @@ dynamic instances of the hash table, while an instantiation of @code{GNAT.HTable} creates a single instance of the hash table. @node GNAT Dynamic_Tables g-dyntab ads,GNAT Encode_String g-encstr ads,GNAT Dynamic_HTables g-dynhta ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-dynamic-tables-g-dyntab-ads}@anchor{361}@anchor{gnat_rm/the_gnat_library id72}@anchor{362} +@anchor{gnat_rm/the_gnat_library gnat-dynamic-tables-g-dyntab-ads}@anchor{360}@anchor{gnat_rm/the_gnat_library id72}@anchor{361} @section @code{GNAT.Dynamic_Tables} (@code{g-dyntab.ads}) @@ -24340,7 +24322,7 @@ dynamic instances of the table, while an instantiation of @code{GNAT.Table} creates a single instance of the table type. @node GNAT Encode_String g-encstr ads,GNAT Encode_UTF8_String g-enutst ads,GNAT Dynamic_Tables g-dyntab ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id73}@anchor{363}@anchor{gnat_rm/the_gnat_library gnat-encode-string-g-encstr-ads}@anchor{364} +@anchor{gnat_rm/the_gnat_library id73}@anchor{362}@anchor{gnat_rm/the_gnat_library gnat-encode-string-g-encstr-ads}@anchor{363} @section @code{GNAT.Encode_String} (@code{g-encstr.ads}) @@ -24362,7 +24344,7 @@ encoding method. Useful in conjunction with Unicode character coding. Note there is a preinstantiation for UTF-8. See next entry. @node GNAT Encode_UTF8_String g-enutst ads,GNAT Exception_Actions g-excact ads,GNAT Encode_String g-encstr ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-encode-utf8-string-g-enutst-ads}@anchor{365}@anchor{gnat_rm/the_gnat_library id74}@anchor{366} +@anchor{gnat_rm/the_gnat_library gnat-encode-utf8-string-g-enutst-ads}@anchor{364}@anchor{gnat_rm/the_gnat_library id74}@anchor{365} @section @code{GNAT.Encode_UTF8_String} (@code{g-enutst.ads}) @@ -24383,7 +24365,7 @@ Note there is a preinstantiation for UTF-8. See next entry. A preinstantiation of GNAT.Encode_Strings for UTF-8 encoding. @node GNAT Exception_Actions g-excact ads,GNAT Exception_Traces g-exctra ads,GNAT Encode_UTF8_String g-enutst ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-exception-actions-g-excact-ads}@anchor{367}@anchor{gnat_rm/the_gnat_library id75}@anchor{368} +@anchor{gnat_rm/the_gnat_library gnat-exception-actions-g-excact-ads}@anchor{366}@anchor{gnat_rm/the_gnat_library id75}@anchor{367} @section @code{GNAT.Exception_Actions} (@code{g-excact.ads}) @@ -24396,7 +24378,7 @@ for specific exceptions, or when any exception is raised. This can be used for instance to force a core dump to ease debugging. @node GNAT Exception_Traces g-exctra ads,GNAT Exceptions g-except ads,GNAT Exception_Actions g-excact ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-exception-traces-g-exctra-ads}@anchor{369}@anchor{gnat_rm/the_gnat_library id76}@anchor{36a} +@anchor{gnat_rm/the_gnat_library gnat-exception-traces-g-exctra-ads}@anchor{368}@anchor{gnat_rm/the_gnat_library id76}@anchor{369} @section @code{GNAT.Exception_Traces} (@code{g-exctra.ads}) @@ -24410,7 +24392,7 @@ Provides an interface allowing to control automatic output upon exception occurrences. @node GNAT Exceptions g-except ads,GNAT Expect g-expect ads,GNAT Exception_Traces g-exctra ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id77}@anchor{36b}@anchor{gnat_rm/the_gnat_library gnat-exceptions-g-except-ads}@anchor{36c} +@anchor{gnat_rm/the_gnat_library id77}@anchor{36a}@anchor{gnat_rm/the_gnat_library gnat-exceptions-g-except-ads}@anchor{36b} @section @code{GNAT.Exceptions} (@code{g-except.ads}) @@ -24431,7 +24413,7 @@ predefined exceptions, and for example allow raising @code{Constraint_Error} with a message from a pure subprogram. @node GNAT Expect g-expect ads,GNAT Expect TTY g-exptty ads,GNAT Exceptions g-except ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id78}@anchor{36d}@anchor{gnat_rm/the_gnat_library gnat-expect-g-expect-ads}@anchor{36e} +@anchor{gnat_rm/the_gnat_library id78}@anchor{36c}@anchor{gnat_rm/the_gnat_library gnat-expect-g-expect-ads}@anchor{36d} @section @code{GNAT.Expect} (@code{g-expect.ads}) @@ -24447,7 +24429,7 @@ It is not implemented for cross ports, and in particular is not implemented for VxWorks or LynxOS. @node GNAT Expect TTY g-exptty ads,GNAT Float_Control g-flocon ads,GNAT Expect g-expect ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id79}@anchor{36f}@anchor{gnat_rm/the_gnat_library gnat-expect-tty-g-exptty-ads}@anchor{370} +@anchor{gnat_rm/the_gnat_library id79}@anchor{36e}@anchor{gnat_rm/the_gnat_library gnat-expect-tty-g-exptty-ads}@anchor{36f} @section @code{GNAT.Expect.TTY} (@code{g-exptty.ads}) @@ -24459,7 +24441,7 @@ ports. It is not implemented for cross ports, and in particular is not implemented for VxWorks or LynxOS. @node GNAT Float_Control g-flocon ads,GNAT Formatted_String g-forstr ads,GNAT Expect TTY g-exptty ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id80}@anchor{371}@anchor{gnat_rm/the_gnat_library gnat-float-control-g-flocon-ads}@anchor{372} +@anchor{gnat_rm/the_gnat_library id80}@anchor{370}@anchor{gnat_rm/the_gnat_library gnat-float-control-g-flocon-ads}@anchor{371} @section @code{GNAT.Float_Control} (@code{g-flocon.ads}) @@ -24473,7 +24455,7 @@ library calls may cause this mode to be modified, and the Reset procedure in this package can be used to reestablish the required mode. @node GNAT Formatted_String g-forstr ads,GNAT Heap_Sort g-heasor ads,GNAT Float_Control g-flocon ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id81}@anchor{373}@anchor{gnat_rm/the_gnat_library gnat-formatted-string-g-forstr-ads}@anchor{374} +@anchor{gnat_rm/the_gnat_library id81}@anchor{372}@anchor{gnat_rm/the_gnat_library gnat-formatted-string-g-forstr-ads}@anchor{373} @section @code{GNAT.Formatted_String} (@code{g-forstr.ads}) @@ -24488,7 +24470,7 @@ derived from Integer, Float or enumerations as values for the formatted string. @node GNAT Heap_Sort g-heasor ads,GNAT Heap_Sort_A g-hesora ads,GNAT Formatted_String g-forstr ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-heap-sort-g-heasor-ads}@anchor{375}@anchor{gnat_rm/the_gnat_library id82}@anchor{376} +@anchor{gnat_rm/the_gnat_library gnat-heap-sort-g-heasor-ads}@anchor{374}@anchor{gnat_rm/the_gnat_library id82}@anchor{375} @section @code{GNAT.Heap_Sort} (@code{g-heasor.ads}) @@ -24502,7 +24484,7 @@ access-to-procedure values. The algorithm used is a modified heap sort that performs approximately N*log(N) comparisons in the worst case. @node GNAT Heap_Sort_A g-hesora ads,GNAT Heap_Sort_G g-hesorg ads,GNAT Heap_Sort g-heasor ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id83}@anchor{377}@anchor{gnat_rm/the_gnat_library gnat-heap-sort-a-g-hesora-ads}@anchor{378} +@anchor{gnat_rm/the_gnat_library id83}@anchor{376}@anchor{gnat_rm/the_gnat_library gnat-heap-sort-a-g-hesora-ads}@anchor{377} @section @code{GNAT.Heap_Sort_A} (@code{g-hesora.ads}) @@ -24518,7 +24500,7 @@ This differs from @code{GNAT.Heap_Sort} in having a less convenient interface, but may be slightly more efficient. @node GNAT Heap_Sort_G g-hesorg ads,GNAT HTable g-htable ads,GNAT Heap_Sort_A g-hesora ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id84}@anchor{379}@anchor{gnat_rm/the_gnat_library gnat-heap-sort-g-g-hesorg-ads}@anchor{37a} +@anchor{gnat_rm/the_gnat_library id84}@anchor{378}@anchor{gnat_rm/the_gnat_library gnat-heap-sort-g-g-hesorg-ads}@anchor{379} @section @code{GNAT.Heap_Sort_G} (@code{g-hesorg.ads}) @@ -24532,7 +24514,7 @@ if the procedures can be inlined, at the expense of duplicating code for multiple instantiations. @node GNAT HTable g-htable ads,GNAT IO g-io ads,GNAT Heap_Sort_G g-hesorg ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id85}@anchor{37b}@anchor{gnat_rm/the_gnat_library gnat-htable-g-htable-ads}@anchor{37c} +@anchor{gnat_rm/the_gnat_library id85}@anchor{37a}@anchor{gnat_rm/the_gnat_library gnat-htable-g-htable-ads}@anchor{37b} @section @code{GNAT.HTable} (@code{g-htable.ads}) @@ -24545,7 +24527,7 @@ data. Provides two approaches, one a simple static approach, and the other allowing arbitrary dynamic hash tables. @node GNAT IO g-io ads,GNAT IO_Aux g-io_aux ads,GNAT HTable g-htable ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id86}@anchor{37d}@anchor{gnat_rm/the_gnat_library gnat-io-g-io-ads}@anchor{37e} +@anchor{gnat_rm/the_gnat_library id86}@anchor{37c}@anchor{gnat_rm/the_gnat_library gnat-io-g-io-ads}@anchor{37d} @section @code{GNAT.IO} (@code{g-io.ads}) @@ -24561,7 +24543,7 @@ Standard_Input, and writing characters, strings and integers to either Standard_Output or Standard_Error. @node GNAT IO_Aux g-io_aux ads,GNAT Lock_Files g-locfil ads,GNAT IO g-io ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id87}@anchor{37f}@anchor{gnat_rm/the_gnat_library gnat-io-aux-g-io-aux-ads}@anchor{380} +@anchor{gnat_rm/the_gnat_library id87}@anchor{37e}@anchor{gnat_rm/the_gnat_library gnat-io-aux-g-io-aux-ads}@anchor{37f} @section @code{GNAT.IO_Aux} (@code{g-io_aux.ads}) @@ -24575,7 +24557,7 @@ Provides some auxiliary functions for use with Text_IO, including a test for whether a file exists, and functions for reading a line of text. @node GNAT Lock_Files g-locfil ads,GNAT MBBS_Discrete_Random g-mbdira ads,GNAT IO_Aux g-io_aux ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id88}@anchor{381}@anchor{gnat_rm/the_gnat_library gnat-lock-files-g-locfil-ads}@anchor{382} +@anchor{gnat_rm/the_gnat_library id88}@anchor{380}@anchor{gnat_rm/the_gnat_library gnat-lock-files-g-locfil-ads}@anchor{381} @section @code{GNAT.Lock_Files} (@code{g-locfil.ads}) @@ -24589,7 +24571,7 @@ Provides a general interface for using files as locks. Can be used for providing program level synchronization. @node GNAT MBBS_Discrete_Random g-mbdira ads,GNAT MBBS_Float_Random g-mbflra ads,GNAT Lock_Files g-locfil ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id89}@anchor{383}@anchor{gnat_rm/the_gnat_library gnat-mbbs-discrete-random-g-mbdira-ads}@anchor{384} +@anchor{gnat_rm/the_gnat_library id89}@anchor{382}@anchor{gnat_rm/the_gnat_library gnat-mbbs-discrete-random-g-mbdira-ads}@anchor{383} @section @code{GNAT.MBBS_Discrete_Random} (@code{g-mbdira.ads}) @@ -24601,7 +24583,7 @@ The original implementation of @code{Ada.Numerics.Discrete_Random}. Uses a modified version of the Blum-Blum-Shub generator. @node GNAT MBBS_Float_Random g-mbflra ads,GNAT MD5 g-md5 ads,GNAT MBBS_Discrete_Random g-mbdira ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id90}@anchor{385}@anchor{gnat_rm/the_gnat_library gnat-mbbs-float-random-g-mbflra-ads}@anchor{386} +@anchor{gnat_rm/the_gnat_library id90}@anchor{384}@anchor{gnat_rm/the_gnat_library gnat-mbbs-float-random-g-mbflra-ads}@anchor{385} @section @code{GNAT.MBBS_Float_Random} (@code{g-mbflra.ads}) @@ -24613,7 +24595,7 @@ The original implementation of @code{Ada.Numerics.Float_Random}. Uses a modified version of the Blum-Blum-Shub generator. @node GNAT MD5 g-md5 ads,GNAT Memory_Dump g-memdum ads,GNAT MBBS_Float_Random g-mbflra ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id91}@anchor{387}@anchor{gnat_rm/the_gnat_library gnat-md5-g-md5-ads}@anchor{388} +@anchor{gnat_rm/the_gnat_library id91}@anchor{386}@anchor{gnat_rm/the_gnat_library gnat-md5-g-md5-ads}@anchor{387} @section @code{GNAT.MD5} (@code{g-md5.ads}) @@ -24626,7 +24608,7 @@ the HMAC-MD5 message authentication function as described in RFC 2104 and FIPS PUB 198. @node GNAT Memory_Dump g-memdum ads,GNAT Most_Recent_Exception g-moreex ads,GNAT MD5 g-md5 ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id92}@anchor{389}@anchor{gnat_rm/the_gnat_library gnat-memory-dump-g-memdum-ads}@anchor{38a} +@anchor{gnat_rm/the_gnat_library id92}@anchor{388}@anchor{gnat_rm/the_gnat_library gnat-memory-dump-g-memdum-ads}@anchor{389} @section @code{GNAT.Memory_Dump} (@code{g-memdum.ads}) @@ -24639,7 +24621,7 @@ standard output or standard error files. Uses GNAT.IO for actual output. @node GNAT Most_Recent_Exception g-moreex ads,GNAT OS_Lib g-os_lib ads,GNAT Memory_Dump g-memdum ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-most-recent-exception-g-moreex-ads}@anchor{38b}@anchor{gnat_rm/the_gnat_library id93}@anchor{38c} +@anchor{gnat_rm/the_gnat_library gnat-most-recent-exception-g-moreex-ads}@anchor{38a}@anchor{gnat_rm/the_gnat_library id93}@anchor{38b} @section @code{GNAT.Most_Recent_Exception} (@code{g-moreex.ads}) @@ -24653,7 +24635,7 @@ various logging purposes, including duplicating functionality of some Ada 83 implementation dependent extensions. @node GNAT OS_Lib g-os_lib ads,GNAT Perfect_Hash_Generators g-pehage ads,GNAT Most_Recent_Exception g-moreex ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-os-lib-g-os-lib-ads}@anchor{38d}@anchor{gnat_rm/the_gnat_library id94}@anchor{38e} +@anchor{gnat_rm/the_gnat_library gnat-os-lib-g-os-lib-ads}@anchor{38c}@anchor{gnat_rm/the_gnat_library id94}@anchor{38d} @section @code{GNAT.OS_Lib} (@code{g-os_lib.ads}) @@ -24669,7 +24651,7 @@ including a portable spawn procedure, and access to environment variables and error return codes. @node GNAT Perfect_Hash_Generators g-pehage ads,GNAT Random_Numbers g-rannum ads,GNAT OS_Lib g-os_lib ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-perfect-hash-generators-g-pehage-ads}@anchor{38f}@anchor{gnat_rm/the_gnat_library id95}@anchor{390} +@anchor{gnat_rm/the_gnat_library gnat-perfect-hash-generators-g-pehage-ads}@anchor{38e}@anchor{gnat_rm/the_gnat_library id95}@anchor{38f} @section @code{GNAT.Perfect_Hash_Generators} (@code{g-pehage.ads}) @@ -24687,7 +24669,7 @@ hashcode are in the same order. These hashing functions are very convenient for use with realtime applications. @node GNAT Random_Numbers g-rannum ads,GNAT Regexp g-regexp ads,GNAT Perfect_Hash_Generators g-pehage ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-random-numbers-g-rannum-ads}@anchor{391}@anchor{gnat_rm/the_gnat_library id96}@anchor{392} +@anchor{gnat_rm/the_gnat_library gnat-random-numbers-g-rannum-ads}@anchor{390}@anchor{gnat_rm/the_gnat_library id96}@anchor{391} @section @code{GNAT.Random_Numbers} (@code{g-rannum.ads}) @@ -24699,7 +24681,7 @@ Provides random number capabilities which extend those available in the standard Ada library and are more convenient to use. @node GNAT Regexp g-regexp ads,GNAT Registry g-regist ads,GNAT Random_Numbers g-rannum ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-regexp-g-regexp-ads}@anchor{25a}@anchor{gnat_rm/the_gnat_library id97}@anchor{393} +@anchor{gnat_rm/the_gnat_library gnat-regexp-g-regexp-ads}@anchor{259}@anchor{gnat_rm/the_gnat_library id97}@anchor{392} @section @code{GNAT.Regexp} (@code{g-regexp.ads}) @@ -24715,7 +24697,7 @@ simplest of the three pattern matching packages provided, and is particularly suitable for 'file globbing' applications. @node GNAT Registry g-regist ads,GNAT Regpat g-regpat ads,GNAT Regexp g-regexp ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id98}@anchor{394}@anchor{gnat_rm/the_gnat_library gnat-registry-g-regist-ads}@anchor{395} +@anchor{gnat_rm/the_gnat_library id98}@anchor{393}@anchor{gnat_rm/the_gnat_library gnat-registry-g-regist-ads}@anchor{394} @section @code{GNAT.Registry} (@code{g-regist.ads}) @@ -24729,7 +24711,7 @@ registry API, but at a lower level of abstraction, refer to the Win32.Winreg package provided with the Win32Ada binding @node GNAT Regpat g-regpat ads,GNAT Rewrite_Data g-rewdat ads,GNAT Registry g-regist ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id99}@anchor{396}@anchor{gnat_rm/the_gnat_library gnat-regpat-g-regpat-ads}@anchor{397} +@anchor{gnat_rm/the_gnat_library id99}@anchor{395}@anchor{gnat_rm/the_gnat_library gnat-regpat-g-regpat-ads}@anchor{396} @section @code{GNAT.Regpat} (@code{g-regpat.ads}) @@ -24744,7 +24726,7 @@ from the original V7 style regular expression library written in C by Henry Spencer (and binary compatible with this C library). @node GNAT Rewrite_Data g-rewdat ads,GNAT Secondary_Stack_Info g-sestin ads,GNAT Regpat g-regpat ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id100}@anchor{398}@anchor{gnat_rm/the_gnat_library gnat-rewrite-data-g-rewdat-ads}@anchor{399} +@anchor{gnat_rm/the_gnat_library id100}@anchor{397}@anchor{gnat_rm/the_gnat_library gnat-rewrite-data-g-rewdat-ads}@anchor{398} @section @code{GNAT.Rewrite_Data} (@code{g-rewdat.ads}) @@ -24758,7 +24740,7 @@ full content to be processed is not loaded into memory all at once. This makes this interface usable for large files or socket streams. @node GNAT Secondary_Stack_Info g-sestin ads,GNAT Semaphores g-semaph ads,GNAT Rewrite_Data g-rewdat ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id101}@anchor{39a}@anchor{gnat_rm/the_gnat_library gnat-secondary-stack-info-g-sestin-ads}@anchor{39b} +@anchor{gnat_rm/the_gnat_library id101}@anchor{399}@anchor{gnat_rm/the_gnat_library gnat-secondary-stack-info-g-sestin-ads}@anchor{39a} @section @code{GNAT.Secondary_Stack_Info} (@code{g-sestin.ads}) @@ -24770,7 +24752,7 @@ Provide the capability to query the high water mark of the current task's secondary stack. @node GNAT Semaphores g-semaph ads,GNAT Serial_Communications g-sercom ads,GNAT Secondary_Stack_Info g-sestin ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id102}@anchor{39c}@anchor{gnat_rm/the_gnat_library gnat-semaphores-g-semaph-ads}@anchor{39d} +@anchor{gnat_rm/the_gnat_library id102}@anchor{39b}@anchor{gnat_rm/the_gnat_library gnat-semaphores-g-semaph-ads}@anchor{39c} @section @code{GNAT.Semaphores} (@code{g-semaph.ads}) @@ -24781,7 +24763,7 @@ secondary stack. Provides classic counting and binary semaphores using protected types. @node GNAT Serial_Communications g-sercom ads,GNAT SHA1 g-sha1 ads,GNAT Semaphores g-semaph ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-serial-communications-g-sercom-ads}@anchor{39e}@anchor{gnat_rm/the_gnat_library id103}@anchor{39f} +@anchor{gnat_rm/the_gnat_library gnat-serial-communications-g-sercom-ads}@anchor{39d}@anchor{gnat_rm/the_gnat_library id103}@anchor{39e} @section @code{GNAT.Serial_Communications} (@code{g-sercom.ads}) @@ -24793,7 +24775,7 @@ Provides a simple interface to send and receive data over a serial port. This is only supported on GNU/Linux and Windows. @node GNAT SHA1 g-sha1 ads,GNAT SHA224 g-sha224 ads,GNAT Serial_Communications g-sercom ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-sha1-g-sha1-ads}@anchor{3a0}@anchor{gnat_rm/the_gnat_library id104}@anchor{3a1} +@anchor{gnat_rm/the_gnat_library gnat-sha1-g-sha1-ads}@anchor{39f}@anchor{gnat_rm/the_gnat_library id104}@anchor{3a0} @section @code{GNAT.SHA1} (@code{g-sha1.ads}) @@ -24806,7 +24788,7 @@ and RFC 3174, and the HMAC-SHA1 message authentication function as described in RFC 2104 and FIPS PUB 198. @node GNAT SHA224 g-sha224 ads,GNAT SHA256 g-sha256 ads,GNAT SHA1 g-sha1 ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-sha224-g-sha224-ads}@anchor{3a2}@anchor{gnat_rm/the_gnat_library id105}@anchor{3a3} +@anchor{gnat_rm/the_gnat_library gnat-sha224-g-sha224-ads}@anchor{3a1}@anchor{gnat_rm/the_gnat_library id105}@anchor{3a2} @section @code{GNAT.SHA224} (@code{g-sha224.ads}) @@ -24819,7 +24801,7 @@ and the HMAC-SHA224 message authentication function as described in RFC 2104 and FIPS PUB 198. @node GNAT SHA256 g-sha256 ads,GNAT SHA384 g-sha384 ads,GNAT SHA224 g-sha224 ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-sha256-g-sha256-ads}@anchor{3a4}@anchor{gnat_rm/the_gnat_library id106}@anchor{3a5} +@anchor{gnat_rm/the_gnat_library gnat-sha256-g-sha256-ads}@anchor{3a3}@anchor{gnat_rm/the_gnat_library id106}@anchor{3a4} @section @code{GNAT.SHA256} (@code{g-sha256.ads}) @@ -24832,7 +24814,7 @@ and the HMAC-SHA256 message authentication function as described in RFC 2104 and FIPS PUB 198. @node GNAT SHA384 g-sha384 ads,GNAT SHA512 g-sha512 ads,GNAT SHA256 g-sha256 ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-sha384-g-sha384-ads}@anchor{3a6}@anchor{gnat_rm/the_gnat_library id107}@anchor{3a7} +@anchor{gnat_rm/the_gnat_library gnat-sha384-g-sha384-ads}@anchor{3a5}@anchor{gnat_rm/the_gnat_library id107}@anchor{3a6} @section @code{GNAT.SHA384} (@code{g-sha384.ads}) @@ -24845,7 +24827,7 @@ and the HMAC-SHA384 message authentication function as described in RFC 2104 and FIPS PUB 198. @node GNAT SHA512 g-sha512 ads,GNAT Signals g-signal ads,GNAT SHA384 g-sha384 ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id108}@anchor{3a8}@anchor{gnat_rm/the_gnat_library gnat-sha512-g-sha512-ads}@anchor{3a9} +@anchor{gnat_rm/the_gnat_library id108}@anchor{3a7}@anchor{gnat_rm/the_gnat_library gnat-sha512-g-sha512-ads}@anchor{3a8} @section @code{GNAT.SHA512} (@code{g-sha512.ads}) @@ -24858,7 +24840,7 @@ and the HMAC-SHA512 message authentication function as described in RFC 2104 and FIPS PUB 198. @node GNAT Signals g-signal ads,GNAT Sockets g-socket ads,GNAT SHA512 g-sha512 ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id109}@anchor{3aa}@anchor{gnat_rm/the_gnat_library gnat-signals-g-signal-ads}@anchor{3ab} +@anchor{gnat_rm/the_gnat_library id109}@anchor{3a9}@anchor{gnat_rm/the_gnat_library gnat-signals-g-signal-ads}@anchor{3aa} @section @code{GNAT.Signals} (@code{g-signal.ads}) @@ -24870,7 +24852,7 @@ Provides the ability to manipulate the blocked status of signals on supported targets. @node GNAT Sockets g-socket ads,GNAT Source_Info g-souinf ads,GNAT Signals g-signal ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-sockets-g-socket-ads}@anchor{3ac}@anchor{gnat_rm/the_gnat_library id110}@anchor{3ad} +@anchor{gnat_rm/the_gnat_library gnat-sockets-g-socket-ads}@anchor{3ab}@anchor{gnat_rm/the_gnat_library id110}@anchor{3ac} @section @code{GNAT.Sockets} (@code{g-socket.ads}) @@ -24885,7 +24867,7 @@ on all native GNAT ports and on VxWorks cross prots. It is not implemented for the LynxOS cross port. @node GNAT Source_Info g-souinf ads,GNAT Spelling_Checker g-speche ads,GNAT Sockets g-socket ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-source-info-g-souinf-ads}@anchor{3ae}@anchor{gnat_rm/the_gnat_library id111}@anchor{3af} +@anchor{gnat_rm/the_gnat_library gnat-source-info-g-souinf-ads}@anchor{3ad}@anchor{gnat_rm/the_gnat_library id111}@anchor{3ae} @section @code{GNAT.Source_Info} (@code{g-souinf.ads}) @@ -24899,7 +24881,7 @@ subprograms yielding the date and time of the current compilation (like the C macros @code{__DATE__} and @code{__TIME__}) @node GNAT Spelling_Checker g-speche ads,GNAT Spelling_Checker_Generic g-spchge ads,GNAT Source_Info g-souinf ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id112}@anchor{3b0}@anchor{gnat_rm/the_gnat_library gnat-spelling-checker-g-speche-ads}@anchor{3b1} +@anchor{gnat_rm/the_gnat_library id112}@anchor{3af}@anchor{gnat_rm/the_gnat_library gnat-spelling-checker-g-speche-ads}@anchor{3b0} @section @code{GNAT.Spelling_Checker} (@code{g-speche.ads}) @@ -24911,7 +24893,7 @@ Provides a function for determining whether one string is a plausible near misspelling of another string. @node GNAT Spelling_Checker_Generic g-spchge ads,GNAT Spitbol Patterns g-spipat ads,GNAT Spelling_Checker g-speche ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-spelling-checker-generic-g-spchge-ads}@anchor{3b2}@anchor{gnat_rm/the_gnat_library id113}@anchor{3b3} +@anchor{gnat_rm/the_gnat_library gnat-spelling-checker-generic-g-spchge-ads}@anchor{3b1}@anchor{gnat_rm/the_gnat_library id113}@anchor{3b2} @section @code{GNAT.Spelling_Checker_Generic} (@code{g-spchge.ads}) @@ -24924,7 +24906,7 @@ determining whether one string is a plausible near misspelling of another string. @node GNAT Spitbol Patterns g-spipat ads,GNAT Spitbol g-spitbo ads,GNAT Spelling_Checker_Generic g-spchge ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-spitbol-patterns-g-spipat-ads}@anchor{3b4}@anchor{gnat_rm/the_gnat_library id114}@anchor{3b5} +@anchor{gnat_rm/the_gnat_library gnat-spitbol-patterns-g-spipat-ads}@anchor{3b3}@anchor{gnat_rm/the_gnat_library id114}@anchor{3b4} @section @code{GNAT.Spitbol.Patterns} (@code{g-spipat.ads}) @@ -24940,7 +24922,7 @@ the SNOBOL4 dynamic pattern construction and matching capabilities, using the efficient algorithm developed by Robert Dewar for the SPITBOL system. @node GNAT Spitbol g-spitbo ads,GNAT Spitbol Table_Boolean g-sptabo ads,GNAT Spitbol Patterns g-spipat ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-spitbol-g-spitbo-ads}@anchor{3b6}@anchor{gnat_rm/the_gnat_library id115}@anchor{3b7} +@anchor{gnat_rm/the_gnat_library gnat-spitbol-g-spitbo-ads}@anchor{3b5}@anchor{gnat_rm/the_gnat_library id115}@anchor{3b6} @section @code{GNAT.Spitbol} (@code{g-spitbo.ads}) @@ -24955,7 +24937,7 @@ useful for constructing arbitrary mappings from strings in the style of the SNOBOL4 TABLE function. @node GNAT Spitbol Table_Boolean g-sptabo ads,GNAT Spitbol Table_Integer g-sptain ads,GNAT Spitbol g-spitbo ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id116}@anchor{3b8}@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-boolean-g-sptabo-ads}@anchor{3b9} +@anchor{gnat_rm/the_gnat_library id116}@anchor{3b7}@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-boolean-g-sptabo-ads}@anchor{3b8} @section @code{GNAT.Spitbol.Table_Boolean} (@code{g-sptabo.ads}) @@ -24970,7 +24952,7 @@ for type @code{Standard.Boolean}, giving an implementation of sets of string values. @node GNAT Spitbol Table_Integer g-sptain ads,GNAT Spitbol Table_VString g-sptavs ads,GNAT Spitbol Table_Boolean g-sptabo ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-integer-g-sptain-ads}@anchor{3ba}@anchor{gnat_rm/the_gnat_library id117}@anchor{3bb} +@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-integer-g-sptain-ads}@anchor{3b9}@anchor{gnat_rm/the_gnat_library id117}@anchor{3ba} @section @code{GNAT.Spitbol.Table_Integer} (@code{g-sptain.ads}) @@ -24987,7 +24969,7 @@ for type @code{Standard.Integer}, giving an implementation of maps from string to integer values. @node GNAT Spitbol Table_VString g-sptavs ads,GNAT SSE g-sse ads,GNAT Spitbol Table_Integer g-sptain ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id118}@anchor{3bc}@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-vstring-g-sptavs-ads}@anchor{3bd} +@anchor{gnat_rm/the_gnat_library id118}@anchor{3bb}@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-vstring-g-sptavs-ads}@anchor{3bc} @section @code{GNAT.Spitbol.Table_VString} (@code{g-sptavs.ads}) @@ -25004,7 +24986,7 @@ a variable length string type, giving an implementation of general maps from strings to strings. @node GNAT SSE g-sse ads,GNAT SSE Vector_Types g-ssvety ads,GNAT Spitbol Table_VString g-sptavs ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id119}@anchor{3be}@anchor{gnat_rm/the_gnat_library gnat-sse-g-sse-ads}@anchor{3bf} +@anchor{gnat_rm/the_gnat_library id119}@anchor{3bd}@anchor{gnat_rm/the_gnat_library gnat-sse-g-sse-ads}@anchor{3be} @section @code{GNAT.SSE} (@code{g-sse.ads}) @@ -25016,7 +24998,7 @@ targets. It exposes vector component types together with a general introduction to the binding contents and use. @node GNAT SSE Vector_Types g-ssvety ads,GNAT String_Hash g-strhas ads,GNAT SSE g-sse ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-sse-vector-types-g-ssvety-ads}@anchor{3c0}@anchor{gnat_rm/the_gnat_library id120}@anchor{3c1} +@anchor{gnat_rm/the_gnat_library gnat-sse-vector-types-g-ssvety-ads}@anchor{3bf}@anchor{gnat_rm/the_gnat_library id120}@anchor{3c0} @section @code{GNAT.SSE.Vector_Types} (@code{g-ssvety.ads}) @@ -25025,7 +25007,7 @@ introduction to the binding contents and use. SSE vector types for use with SSE related intrinsics. @node GNAT String_Hash g-strhas ads,GNAT Strings g-string ads,GNAT SSE Vector_Types g-ssvety ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-string-hash-g-strhas-ads}@anchor{3c2}@anchor{gnat_rm/the_gnat_library id121}@anchor{3c3} +@anchor{gnat_rm/the_gnat_library gnat-string-hash-g-strhas-ads}@anchor{3c1}@anchor{gnat_rm/the_gnat_library id121}@anchor{3c2} @section @code{GNAT.String_Hash} (@code{g-strhas.ads}) @@ -25037,7 +25019,7 @@ Provides a generic hash function working on arrays of scalars. Both the scalar type and the hash result type are parameters. @node GNAT Strings g-string ads,GNAT String_Split g-strspl ads,GNAT String_Hash g-strhas ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-strings-g-string-ads}@anchor{3c4}@anchor{gnat_rm/the_gnat_library id122}@anchor{3c5} +@anchor{gnat_rm/the_gnat_library gnat-strings-g-string-ads}@anchor{3c3}@anchor{gnat_rm/the_gnat_library id122}@anchor{3c4} @section @code{GNAT.Strings} (@code{g-string.ads}) @@ -25047,7 +25029,7 @@ Common String access types and related subprograms. Basically it defines a string access and an array of string access types. @node GNAT String_Split g-strspl ads,GNAT Table g-table ads,GNAT Strings g-string ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-string-split-g-strspl-ads}@anchor{3c6}@anchor{gnat_rm/the_gnat_library id123}@anchor{3c7} +@anchor{gnat_rm/the_gnat_library gnat-string-split-g-strspl-ads}@anchor{3c5}@anchor{gnat_rm/the_gnat_library id123}@anchor{3c6} @section @code{GNAT.String_Split} (@code{g-strspl.ads}) @@ -25061,7 +25043,7 @@ to the resulting slices. This package is instantiated from @code{GNAT.Array_Split}. @node GNAT Table g-table ads,GNAT Task_Lock g-tasloc ads,GNAT String_Split g-strspl ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id124}@anchor{3c8}@anchor{gnat_rm/the_gnat_library gnat-table-g-table-ads}@anchor{3c9} +@anchor{gnat_rm/the_gnat_library id124}@anchor{3c7}@anchor{gnat_rm/the_gnat_library gnat-table-g-table-ads}@anchor{3c8} @section @code{GNAT.Table} (@code{g-table.ads}) @@ -25081,7 +25063,7 @@ while an instantiation of @code{GNAT.Dynamic_Tables} creates a type that can be used to define dynamic instances of the table. @node GNAT Task_Lock g-tasloc ads,GNAT Time_Stamp g-timsta ads,GNAT Table g-table ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id125}@anchor{3ca}@anchor{gnat_rm/the_gnat_library gnat-task-lock-g-tasloc-ads}@anchor{3cb} +@anchor{gnat_rm/the_gnat_library id125}@anchor{3c9}@anchor{gnat_rm/the_gnat_library gnat-task-lock-g-tasloc-ads}@anchor{3ca} @section @code{GNAT.Task_Lock} (@code{g-tasloc.ads}) @@ -25098,7 +25080,7 @@ single global task lock. Appropriate for use in situations where contention between tasks is very rarely expected. @node GNAT Time_Stamp g-timsta ads,GNAT Threads g-thread ads,GNAT Task_Lock g-tasloc ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id126}@anchor{3cc}@anchor{gnat_rm/the_gnat_library gnat-time-stamp-g-timsta-ads}@anchor{3cd} +@anchor{gnat_rm/the_gnat_library id126}@anchor{3cb}@anchor{gnat_rm/the_gnat_library gnat-time-stamp-g-timsta-ads}@anchor{3cc} @section @code{GNAT.Time_Stamp} (@code{g-timsta.ads}) @@ -25113,7 +25095,7 @@ represents the current date and time in ISO 8601 format. This is a very simple routine with minimal code and there are no dependencies on any other unit. @node GNAT Threads g-thread ads,GNAT Traceback g-traceb ads,GNAT Time_Stamp g-timsta ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id127}@anchor{3ce}@anchor{gnat_rm/the_gnat_library gnat-threads-g-thread-ads}@anchor{3cf} +@anchor{gnat_rm/the_gnat_library id127}@anchor{3cd}@anchor{gnat_rm/the_gnat_library gnat-threads-g-thread-ads}@anchor{3ce} @section @code{GNAT.Threads} (@code{g-thread.ads}) @@ -25130,7 +25112,7 @@ further details if your program has threads that are created by a non-Ada environment which then accesses Ada code. @node GNAT Traceback g-traceb ads,GNAT Traceback Symbolic g-trasym ads,GNAT Threads g-thread ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id128}@anchor{3d0}@anchor{gnat_rm/the_gnat_library gnat-traceback-g-traceb-ads}@anchor{3d1} +@anchor{gnat_rm/the_gnat_library id128}@anchor{3cf}@anchor{gnat_rm/the_gnat_library gnat-traceback-g-traceb-ads}@anchor{3d0} @section @code{GNAT.Traceback} (@code{g-traceb.ads}) @@ -25142,7 +25124,7 @@ Provides a facility for obtaining non-symbolic traceback information, useful in various debugging situations. @node GNAT Traceback Symbolic g-trasym ads,GNAT UTF_32 g-table ads,GNAT Traceback g-traceb ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-traceback-symbolic-g-trasym-ads}@anchor{3d2}@anchor{gnat_rm/the_gnat_library id129}@anchor{3d3} +@anchor{gnat_rm/the_gnat_library gnat-traceback-symbolic-g-trasym-ads}@anchor{3d1}@anchor{gnat_rm/the_gnat_library id129}@anchor{3d2} @section @code{GNAT.Traceback.Symbolic} (@code{g-trasym.ads}) @@ -25151,7 +25133,7 @@ in various debugging situations. @geindex Trace back facilities @node GNAT UTF_32 g-table ads,GNAT Wide_Spelling_Checker g-u3spch ads,GNAT Traceback Symbolic g-trasym ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id130}@anchor{3d4}@anchor{gnat_rm/the_gnat_library gnat-utf-32-g-table-ads}@anchor{3d5} +@anchor{gnat_rm/the_gnat_library id130}@anchor{3d3}@anchor{gnat_rm/the_gnat_library gnat-utf-32-g-table-ads}@anchor{3d4} @section @code{GNAT.UTF_32} (@code{g-table.ads}) @@ -25170,7 +25152,7 @@ lower case to upper case fold routine corresponding to the Ada 2005 rules for identifier equivalence. @node GNAT Wide_Spelling_Checker g-u3spch ads,GNAT Wide_Spelling_Checker g-wispch ads,GNAT UTF_32 g-table ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-wide-spelling-checker-g-u3spch-ads}@anchor{3d6}@anchor{gnat_rm/the_gnat_library id131}@anchor{3d7} +@anchor{gnat_rm/the_gnat_library gnat-wide-spelling-checker-g-u3spch-ads}@anchor{3d5}@anchor{gnat_rm/the_gnat_library id131}@anchor{3d6} @section @code{GNAT.Wide_Spelling_Checker} (@code{g-u3spch.ads}) @@ -25183,7 +25165,7 @@ near misspelling of another wide wide string, where the strings are represented using the UTF_32_String type defined in System.Wch_Cnv. @node GNAT Wide_Spelling_Checker g-wispch ads,GNAT Wide_String_Split g-wistsp ads,GNAT Wide_Spelling_Checker g-u3spch ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-wide-spelling-checker-g-wispch-ads}@anchor{3d8}@anchor{gnat_rm/the_gnat_library id132}@anchor{3d9} +@anchor{gnat_rm/the_gnat_library gnat-wide-spelling-checker-g-wispch-ads}@anchor{3d7}@anchor{gnat_rm/the_gnat_library id132}@anchor{3d8} @section @code{GNAT.Wide_Spelling_Checker} (@code{g-wispch.ads}) @@ -25195,7 +25177,7 @@ Provides a function for determining whether one wide string is a plausible near misspelling of another wide string. @node GNAT Wide_String_Split g-wistsp ads,GNAT Wide_Wide_Spelling_Checker g-zspche ads,GNAT Wide_Spelling_Checker g-wispch ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id133}@anchor{3da}@anchor{gnat_rm/the_gnat_library gnat-wide-string-split-g-wistsp-ads}@anchor{3db} +@anchor{gnat_rm/the_gnat_library id133}@anchor{3d9}@anchor{gnat_rm/the_gnat_library gnat-wide-string-split-g-wistsp-ads}@anchor{3da} @section @code{GNAT.Wide_String_Split} (@code{g-wistsp.ads}) @@ -25209,7 +25191,7 @@ to the resulting slices. This package is instantiated from @code{GNAT.Array_Split}. @node GNAT Wide_Wide_Spelling_Checker g-zspche ads,GNAT Wide_Wide_String_Split g-zistsp ads,GNAT Wide_String_Split g-wistsp ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-wide-wide-spelling-checker-g-zspche-ads}@anchor{3dc}@anchor{gnat_rm/the_gnat_library id134}@anchor{3dd} +@anchor{gnat_rm/the_gnat_library gnat-wide-wide-spelling-checker-g-zspche-ads}@anchor{3db}@anchor{gnat_rm/the_gnat_library id134}@anchor{3dc} @section @code{GNAT.Wide_Wide_Spelling_Checker} (@code{g-zspche.ads}) @@ -25221,7 +25203,7 @@ Provides a function for determining whether one wide wide string is a plausible near misspelling of another wide wide string. @node GNAT Wide_Wide_String_Split g-zistsp ads,Interfaces C Extensions i-cexten ads,GNAT Wide_Wide_Spelling_Checker g-zspche ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library gnat-wide-wide-string-split-g-zistsp-ads}@anchor{3de}@anchor{gnat_rm/the_gnat_library id135}@anchor{3df} +@anchor{gnat_rm/the_gnat_library gnat-wide-wide-string-split-g-zistsp-ads}@anchor{3dd}@anchor{gnat_rm/the_gnat_library id135}@anchor{3de} @section @code{GNAT.Wide_Wide_String_Split} (@code{g-zistsp.ads}) @@ -25235,7 +25217,7 @@ to the resulting slices. This package is instantiated from @code{GNAT.Array_Split}. @node Interfaces C Extensions i-cexten ads,Interfaces C Streams i-cstrea ads,GNAT Wide_Wide_String_Split g-zistsp ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library interfaces-c-extensions-i-cexten-ads}@anchor{3e0}@anchor{gnat_rm/the_gnat_library id136}@anchor{3e1} +@anchor{gnat_rm/the_gnat_library interfaces-c-extensions-i-cexten-ads}@anchor{3df}@anchor{gnat_rm/the_gnat_library id136}@anchor{3e0} @section @code{Interfaces.C.Extensions} (@code{i-cexten.ads}) @@ -25246,7 +25228,7 @@ for use with either manually or automatically generated bindings to C libraries. @node Interfaces C Streams i-cstrea ads,Interfaces Packed_Decimal i-pacdec ads,Interfaces C Extensions i-cexten ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library interfaces-c-streams-i-cstrea-ads}@anchor{3e2}@anchor{gnat_rm/the_gnat_library id137}@anchor{3e3} +@anchor{gnat_rm/the_gnat_library interfaces-c-streams-i-cstrea-ads}@anchor{3e1}@anchor{gnat_rm/the_gnat_library id137}@anchor{3e2} @section @code{Interfaces.C.Streams} (@code{i-cstrea.ads}) @@ -25259,7 +25241,7 @@ This package is a binding for the most commonly used operations on C streams. @node Interfaces Packed_Decimal i-pacdec ads,Interfaces VxWorks i-vxwork ads,Interfaces C Streams i-cstrea ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id138}@anchor{3e4}@anchor{gnat_rm/the_gnat_library interfaces-packed-decimal-i-pacdec-ads}@anchor{3e5} +@anchor{gnat_rm/the_gnat_library id138}@anchor{3e3}@anchor{gnat_rm/the_gnat_library interfaces-packed-decimal-i-pacdec-ads}@anchor{3e4} @section @code{Interfaces.Packed_Decimal} (@code{i-pacdec.ads}) @@ -25274,7 +25256,7 @@ from a packed decimal format compatible with that used on IBM mainframes. @node Interfaces VxWorks i-vxwork ads,Interfaces VxWorks Int_Connection i-vxinco ads,Interfaces Packed_Decimal i-pacdec ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id139}@anchor{3e6}@anchor{gnat_rm/the_gnat_library interfaces-vxworks-i-vxwork-ads}@anchor{3e7} +@anchor{gnat_rm/the_gnat_library id139}@anchor{3e5}@anchor{gnat_rm/the_gnat_library interfaces-vxworks-i-vxwork-ads}@anchor{3e6} @section @code{Interfaces.VxWorks} (@code{i-vxwork.ads}) @@ -25290,7 +25272,7 @@ In particular, it interfaces with the VxWorks hardware interrupt facilities. @node Interfaces VxWorks Int_Connection i-vxinco ads,Interfaces VxWorks IO i-vxwoio ads,Interfaces VxWorks i-vxwork ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library interfaces-vxworks-int-connection-i-vxinco-ads}@anchor{3e8}@anchor{gnat_rm/the_gnat_library id140}@anchor{3e9} +@anchor{gnat_rm/the_gnat_library interfaces-vxworks-int-connection-i-vxinco-ads}@anchor{3e7}@anchor{gnat_rm/the_gnat_library id140}@anchor{3e8} @section @code{Interfaces.VxWorks.Int_Connection} (@code{i-vxinco.ads}) @@ -25306,7 +25288,7 @@ intConnect() with a custom routine for installing interrupt handlers. @node Interfaces VxWorks IO i-vxwoio ads,System Address_Image s-addima ads,Interfaces VxWorks Int_Connection i-vxinco ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library interfaces-vxworks-io-i-vxwoio-ads}@anchor{3ea}@anchor{gnat_rm/the_gnat_library id141}@anchor{3eb} +@anchor{gnat_rm/the_gnat_library interfaces-vxworks-io-i-vxwoio-ads}@anchor{3e9}@anchor{gnat_rm/the_gnat_library id141}@anchor{3ea} @section @code{Interfaces.VxWorks.IO} (@code{i-vxwoio.ads}) @@ -25329,7 +25311,7 @@ function codes. A particular use of this package is to enable the use of Get_Immediate under VxWorks. @node System Address_Image s-addima ads,System Assertions s-assert ads,Interfaces VxWorks IO i-vxwoio ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library system-address-image-s-addima-ads}@anchor{3ec}@anchor{gnat_rm/the_gnat_library id142}@anchor{3ed} +@anchor{gnat_rm/the_gnat_library system-address-image-s-addima-ads}@anchor{3eb}@anchor{gnat_rm/the_gnat_library id142}@anchor{3ec} @section @code{System.Address_Image} (@code{s-addima.ads}) @@ -25345,7 +25327,7 @@ function that gives an (implementation dependent) string which identifies an address. @node System Assertions s-assert ads,System Atomic_Counters s-atocou ads,System Address_Image s-addima ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library system-assertions-s-assert-ads}@anchor{3ee}@anchor{gnat_rm/the_gnat_library id143}@anchor{3ef} +@anchor{gnat_rm/the_gnat_library system-assertions-s-assert-ads}@anchor{3ed}@anchor{gnat_rm/the_gnat_library id143}@anchor{3ee} @section @code{System.Assertions} (@code{s-assert.ads}) @@ -25361,7 +25343,7 @@ by an run-time assertion failure, as well as the routine that is used internally to raise this assertion. @node System Atomic_Counters s-atocou ads,System Memory s-memory ads,System Assertions s-assert ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id144}@anchor{3f0}@anchor{gnat_rm/the_gnat_library system-atomic-counters-s-atocou-ads}@anchor{3f1} +@anchor{gnat_rm/the_gnat_library id144}@anchor{3ef}@anchor{gnat_rm/the_gnat_library system-atomic-counters-s-atocou-ads}@anchor{3f0} @section @code{System.Atomic_Counters} (@code{s-atocou.ads}) @@ -25375,7 +25357,7 @@ on most targets, including all Alpha, ia64, PowerPC, SPARC V9, x86, and x86_64 platforms. @node System Memory s-memory ads,System Multiprocessors s-multip ads,System Atomic_Counters s-atocou ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library system-memory-s-memory-ads}@anchor{3f2}@anchor{gnat_rm/the_gnat_library id145}@anchor{3f3} +@anchor{gnat_rm/the_gnat_library system-memory-s-memory-ads}@anchor{3f1}@anchor{gnat_rm/the_gnat_library id145}@anchor{3f2} @section @code{System.Memory} (@code{s-memory.ads}) @@ -25393,7 +25375,7 @@ calls to this unit may be made for low level allocation uses (for example see the body of @code{GNAT.Tables}). @node System Multiprocessors s-multip ads,System Multiprocessors Dispatching_Domains s-mudido ads,System Memory s-memory ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id146}@anchor{3f4}@anchor{gnat_rm/the_gnat_library system-multiprocessors-s-multip-ads}@anchor{3f5} +@anchor{gnat_rm/the_gnat_library id146}@anchor{3f3}@anchor{gnat_rm/the_gnat_library system-multiprocessors-s-multip-ads}@anchor{3f4} @section @code{System.Multiprocessors} (@code{s-multip.ads}) @@ -25406,7 +25388,7 @@ in GNAT we also make it available in Ada 95 and Ada 2005 (where it is technically an implementation-defined addition). @node System Multiprocessors Dispatching_Domains s-mudido ads,System Partition_Interface s-parint ads,System Multiprocessors s-multip ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library system-multiprocessors-dispatching-domains-s-mudido-ads}@anchor{3f6}@anchor{gnat_rm/the_gnat_library id147}@anchor{3f7} +@anchor{gnat_rm/the_gnat_library system-multiprocessors-dispatching-domains-s-mudido-ads}@anchor{3f5}@anchor{gnat_rm/the_gnat_library id147}@anchor{3f6} @section @code{System.Multiprocessors.Dispatching_Domains} (@code{s-mudido.ads}) @@ -25419,7 +25401,7 @@ in GNAT we also make it available in Ada 95 and Ada 2005 (where it is technically an implementation-defined addition). @node System Partition_Interface s-parint ads,System Pool_Global s-pooglo ads,System Multiprocessors Dispatching_Domains s-mudido ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id148}@anchor{3f8}@anchor{gnat_rm/the_gnat_library system-partition-interface-s-parint-ads}@anchor{3f9} +@anchor{gnat_rm/the_gnat_library id148}@anchor{3f7}@anchor{gnat_rm/the_gnat_library system-partition-interface-s-parint-ads}@anchor{3f8} @section @code{System.Partition_Interface} (@code{s-parint.ads}) @@ -25432,7 +25414,7 @@ is used primarily in a distribution context when using Annex E with @code{GLADE}. @node System Pool_Global s-pooglo ads,System Pool_Local s-pooloc ads,System Partition_Interface s-parint ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id149}@anchor{3fa}@anchor{gnat_rm/the_gnat_library system-pool-global-s-pooglo-ads}@anchor{3fb} +@anchor{gnat_rm/the_gnat_library id149}@anchor{3f9}@anchor{gnat_rm/the_gnat_library system-pool-global-s-pooglo-ads}@anchor{3fa} @section @code{System.Pool_Global} (@code{s-pooglo.ads}) @@ -25449,7 +25431,7 @@ declared. It uses malloc/free to allocate/free and does not attempt to do any automatic reclamation. @node System Pool_Local s-pooloc ads,System Restrictions s-restri ads,System Pool_Global s-pooglo ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library system-pool-local-s-pooloc-ads}@anchor{3fc}@anchor{gnat_rm/the_gnat_library id150}@anchor{3fd} +@anchor{gnat_rm/the_gnat_library system-pool-local-s-pooloc-ads}@anchor{3fb}@anchor{gnat_rm/the_gnat_library id150}@anchor{3fc} @section @code{System.Pool_Local} (@code{s-pooloc.ads}) @@ -25466,7 +25448,7 @@ a list of allocated blocks, so that all storage allocated for the pool can be freed automatically when the pool is finalized. @node System Restrictions s-restri ads,System Rident s-rident ads,System Pool_Local s-pooloc ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library system-restrictions-s-restri-ads}@anchor{3fe}@anchor{gnat_rm/the_gnat_library id151}@anchor{3ff} +@anchor{gnat_rm/the_gnat_library system-restrictions-s-restri-ads}@anchor{3fd}@anchor{gnat_rm/the_gnat_library id151}@anchor{3fe} @section @code{System.Restrictions} (@code{s-restri.ads}) @@ -25482,7 +25464,7 @@ compiler determined information on which restrictions are violated by one or more packages in the partition. @node System Rident s-rident ads,System Strings Stream_Ops s-ststop ads,System Restrictions s-restri ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library system-rident-s-rident-ads}@anchor{400}@anchor{gnat_rm/the_gnat_library id152}@anchor{401} +@anchor{gnat_rm/the_gnat_library system-rident-s-rident-ads}@anchor{3ff}@anchor{gnat_rm/the_gnat_library id152}@anchor{400} @section @code{System.Rident} (@code{s-rident.ads}) @@ -25498,7 +25480,7 @@ since the necessary instantiation is included in package System.Restrictions. @node System Strings Stream_Ops s-ststop ads,System Unsigned_Types s-unstyp ads,System Rident s-rident ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id153}@anchor{402}@anchor{gnat_rm/the_gnat_library system-strings-stream-ops-s-ststop-ads}@anchor{403} +@anchor{gnat_rm/the_gnat_library id153}@anchor{401}@anchor{gnat_rm/the_gnat_library system-strings-stream-ops-s-ststop-ads}@anchor{402} @section @code{System.Strings.Stream_Ops} (@code{s-ststop.ads}) @@ -25514,7 +25496,7 @@ stream attributes are applied to string types, but the subprograms in this package can be used directly by application programs. @node System Unsigned_Types s-unstyp ads,System Wch_Cnv s-wchcnv ads,System Strings Stream_Ops s-ststop ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library system-unsigned-types-s-unstyp-ads}@anchor{404}@anchor{gnat_rm/the_gnat_library id154}@anchor{405} +@anchor{gnat_rm/the_gnat_library system-unsigned-types-s-unstyp-ads}@anchor{403}@anchor{gnat_rm/the_gnat_library id154}@anchor{404} @section @code{System.Unsigned_Types} (@code{s-unstyp.ads}) @@ -25527,7 +25509,7 @@ also contains some related definitions for other specialized types used by the compiler in connection with packed array types. @node System Wch_Cnv s-wchcnv ads,System Wch_Con s-wchcon ads,System Unsigned_Types s-unstyp ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library system-wch-cnv-s-wchcnv-ads}@anchor{406}@anchor{gnat_rm/the_gnat_library id155}@anchor{407} +@anchor{gnat_rm/the_gnat_library system-wch-cnv-s-wchcnv-ads}@anchor{405}@anchor{gnat_rm/the_gnat_library id155}@anchor{406} @section @code{System.Wch_Cnv} (@code{s-wchcnv.ads}) @@ -25548,7 +25530,7 @@ encoding method. It uses definitions in package @code{System.Wch_Con}. @node System Wch_Con s-wchcon ads,,System Wch_Cnv s-wchcnv ads,The GNAT Library -@anchor{gnat_rm/the_gnat_library id156}@anchor{408}@anchor{gnat_rm/the_gnat_library system-wch-con-s-wchcon-ads}@anchor{409} +@anchor{gnat_rm/the_gnat_library id156}@anchor{407}@anchor{gnat_rm/the_gnat_library system-wch-con-s-wchcon-ads}@anchor{408} @section @code{System.Wch_Con} (@code{s-wchcon.ads}) @@ -25560,7 +25542,7 @@ in ordinary strings. These definitions are used by the package @code{System.Wch_Cnv}. @node Interfacing to Other Languages,Specialized Needs Annexes,The GNAT Library,Top -@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-other-languages}@anchor{11}@anchor{gnat_rm/interfacing_to_other_languages doc}@anchor{40a}@anchor{gnat_rm/interfacing_to_other_languages id1}@anchor{40b} +@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-other-languages}@anchor{11}@anchor{gnat_rm/interfacing_to_other_languages doc}@anchor{409}@anchor{gnat_rm/interfacing_to_other_languages id1}@anchor{40a} @chapter Interfacing to Other Languages @@ -25578,7 +25560,7 @@ provided. @end menu @node Interfacing to C,Interfacing to C++,,Interfacing to Other Languages -@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-c}@anchor{40c}@anchor{gnat_rm/interfacing_to_other_languages id2}@anchor{40d} +@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-c}@anchor{40b}@anchor{gnat_rm/interfacing_to_other_languages id2}@anchor{40c} @section Interfacing to C @@ -25718,7 +25700,7 @@ of the length corresponding to the @code{type'Size} value in Ada. @end itemize @node Interfacing to C++,Interfacing to COBOL,Interfacing to C,Interfacing to Other Languages -@anchor{gnat_rm/interfacing_to_other_languages id4}@anchor{40e}@anchor{gnat_rm/interfacing_to_other_languages id3}@anchor{4a} +@anchor{gnat_rm/interfacing_to_other_languages id4}@anchor{40d}@anchor{gnat_rm/interfacing_to_other_languages id3}@anchor{4a} @section Interfacing to C++ @@ -25775,7 +25757,7 @@ The @code{External_Name} is the name of the C++ RTTI symbol. You can then cover a specific C++ exception in an exception handler. @node Interfacing to COBOL,Interfacing to Fortran,Interfacing to C++,Interfacing to Other Languages -@anchor{gnat_rm/interfacing_to_other_languages id5}@anchor{40f}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-cobol}@anchor{410} +@anchor{gnat_rm/interfacing_to_other_languages id5}@anchor{40e}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-cobol}@anchor{40f} @section Interfacing to COBOL @@ -25783,7 +25765,7 @@ Interfacing to COBOL is achieved as described in section B.4 of the Ada Reference Manual. @node Interfacing to Fortran,Interfacing to non-GNAT Ada code,Interfacing to COBOL,Interfacing to Other Languages -@anchor{gnat_rm/interfacing_to_other_languages id6}@anchor{411}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-fortran}@anchor{412} +@anchor{gnat_rm/interfacing_to_other_languages id6}@anchor{410}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-fortran}@anchor{411} @section Interfacing to Fortran @@ -25793,7 +25775,7 @@ multi-dimensional array causes the array to be stored in column-major order as required for convenient interface to Fortran. @node Interfacing to non-GNAT Ada code,,Interfacing to Fortran,Interfacing to Other Languages -@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-non-gnat-ada-code}@anchor{413}@anchor{gnat_rm/interfacing_to_other_languages id7}@anchor{414} +@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-non-gnat-ada-code}@anchor{412}@anchor{gnat_rm/interfacing_to_other_languages id7}@anchor{413} @section Interfacing to non-GNAT Ada code @@ -25817,7 +25799,7 @@ values or simple record types without variants, or simple array types with fixed bounds. @node Specialized Needs Annexes,Implementation of Specific Ada Features,Interfacing to Other Languages,Top -@anchor{gnat_rm/specialized_needs_annexes specialized-needs-annexes}@anchor{12}@anchor{gnat_rm/specialized_needs_annexes doc}@anchor{415}@anchor{gnat_rm/specialized_needs_annexes id1}@anchor{416} +@anchor{gnat_rm/specialized_needs_annexes specialized-needs-annexes}@anchor{12}@anchor{gnat_rm/specialized_needs_annexes doc}@anchor{414}@anchor{gnat_rm/specialized_needs_annexes id1}@anchor{415} @chapter Specialized Needs Annexes @@ -25858,7 +25840,7 @@ in Ada 2005) is fully implemented. @end table @node Implementation of Specific Ada Features,Implementation of Ada 2012 Features,Specialized Needs Annexes,Top -@anchor{gnat_rm/implementation_of_specific_ada_features implementation-of-specific-ada-features}@anchor{13}@anchor{gnat_rm/implementation_of_specific_ada_features doc}@anchor{417}@anchor{gnat_rm/implementation_of_specific_ada_features id1}@anchor{418} +@anchor{gnat_rm/implementation_of_specific_ada_features implementation-of-specific-ada-features}@anchor{13}@anchor{gnat_rm/implementation_of_specific_ada_features doc}@anchor{416}@anchor{gnat_rm/implementation_of_specific_ada_features id1}@anchor{417} @chapter Implementation of Specific Ada Features @@ -25876,7 +25858,7 @@ facilities. @end menu @node Machine Code Insertions,GNAT Implementation of Tasking,,Implementation of Specific Ada Features -@anchor{gnat_rm/implementation_of_specific_ada_features machine-code-insertions}@anchor{16d}@anchor{gnat_rm/implementation_of_specific_ada_features id2}@anchor{419} +@anchor{gnat_rm/implementation_of_specific_ada_features machine-code-insertions}@anchor{16c}@anchor{gnat_rm/implementation_of_specific_ada_features id2}@anchor{418} @section Machine Code Insertions @@ -26044,7 +26026,7 @@ according to normal visibility rules. In particular if there is no qualification is required. @node GNAT Implementation of Tasking,GNAT Implementation of Shared Passive Packages,Machine Code Insertions,Implementation of Specific Ada Features -@anchor{gnat_rm/implementation_of_specific_ada_features id3}@anchor{41a}@anchor{gnat_rm/implementation_of_specific_ada_features gnat-implementation-of-tasking}@anchor{41b} +@anchor{gnat_rm/implementation_of_specific_ada_features id3}@anchor{419}@anchor{gnat_rm/implementation_of_specific_ada_features gnat-implementation-of-tasking}@anchor{41a} @section GNAT Implementation of Tasking @@ -26060,7 +26042,7 @@ to compliance with the Real-Time Systems Annex. @end menu @node Mapping Ada Tasks onto the Underlying Kernel Threads,Ensuring Compliance with the Real-Time Annex,,GNAT Implementation of Tasking -@anchor{gnat_rm/implementation_of_specific_ada_features mapping-ada-tasks-onto-the-underlying-kernel-threads}@anchor{41c}@anchor{gnat_rm/implementation_of_specific_ada_features id4}@anchor{41d} +@anchor{gnat_rm/implementation_of_specific_ada_features mapping-ada-tasks-onto-the-underlying-kernel-threads}@anchor{41b}@anchor{gnat_rm/implementation_of_specific_ada_features id4}@anchor{41c} @subsection Mapping Ada Tasks onto the Underlying Kernel Threads @@ -26129,7 +26111,7 @@ support this functionality when the parent contains more than one task. @geindex Forking a new process @node Ensuring Compliance with the Real-Time Annex,Support for Locking Policies,Mapping Ada Tasks onto the Underlying Kernel Threads,GNAT Implementation of Tasking -@anchor{gnat_rm/implementation_of_specific_ada_features id5}@anchor{41e}@anchor{gnat_rm/implementation_of_specific_ada_features ensuring-compliance-with-the-real-time-annex}@anchor{41f} +@anchor{gnat_rm/implementation_of_specific_ada_features id5}@anchor{41d}@anchor{gnat_rm/implementation_of_specific_ada_features ensuring-compliance-with-the-real-time-annex}@anchor{41e} @subsection Ensuring Compliance with the Real-Time Annex @@ -26180,7 +26162,7 @@ placed at the end. @c Support_for_Locking_Policies @node Support for Locking Policies,,Ensuring Compliance with the Real-Time Annex,GNAT Implementation of Tasking -@anchor{gnat_rm/implementation_of_specific_ada_features support-for-locking-policies}@anchor{420} +@anchor{gnat_rm/implementation_of_specific_ada_features support-for-locking-policies}@anchor{41f} @subsection Support for Locking Policies @@ -26214,7 +26196,7 @@ then ceiling locking is used. Otherwise, the @code{Ceiling_Locking} policy is ignored. @node GNAT Implementation of Shared Passive Packages,Code Generation for Array Aggregates,GNAT Implementation of Tasking,Implementation of Specific Ada Features -@anchor{gnat_rm/implementation_of_specific_ada_features id6}@anchor{421}@anchor{gnat_rm/implementation_of_specific_ada_features gnat-implementation-of-shared-passive-packages}@anchor{422} +@anchor{gnat_rm/implementation_of_specific_ada_features id6}@anchor{420}@anchor{gnat_rm/implementation_of_specific_ada_features gnat-implementation-of-shared-passive-packages}@anchor{421} @section GNAT Implementation of Shared Passive Packages @@ -26315,7 +26297,7 @@ GNAT supports shared passive packages on all platforms except for OpenVMS. @node Code Generation for Array Aggregates,The Size of Discriminated Records with Default Discriminants,GNAT Implementation of Shared Passive Packages,Implementation of Specific Ada Features -@anchor{gnat_rm/implementation_of_specific_ada_features code-generation-for-array-aggregates}@anchor{423}@anchor{gnat_rm/implementation_of_specific_ada_features id7}@anchor{424} +@anchor{gnat_rm/implementation_of_specific_ada_features code-generation-for-array-aggregates}@anchor{422}@anchor{gnat_rm/implementation_of_specific_ada_features id7}@anchor{423} @section Code Generation for Array Aggregates @@ -26346,7 +26328,7 @@ component values and static subtypes also lead to simpler code. @end menu @node Static constant aggregates with static bounds,Constant aggregates with unconstrained nominal types,,Code Generation for Array Aggregates -@anchor{gnat_rm/implementation_of_specific_ada_features static-constant-aggregates-with-static-bounds}@anchor{425}@anchor{gnat_rm/implementation_of_specific_ada_features id8}@anchor{426} +@anchor{gnat_rm/implementation_of_specific_ada_features static-constant-aggregates-with-static-bounds}@anchor{424}@anchor{gnat_rm/implementation_of_specific_ada_features id8}@anchor{425} @subsection Static constant aggregates with static bounds @@ -26393,7 +26375,7 @@ Zero2: constant two_dim := (others => (others => 0)); @end example @node Constant aggregates with unconstrained nominal types,Aggregates with static bounds,Static constant aggregates with static bounds,Code Generation for Array Aggregates -@anchor{gnat_rm/implementation_of_specific_ada_features constant-aggregates-with-unconstrained-nominal-types}@anchor{427}@anchor{gnat_rm/implementation_of_specific_ada_features id9}@anchor{428} +@anchor{gnat_rm/implementation_of_specific_ada_features constant-aggregates-with-unconstrained-nominal-types}@anchor{426}@anchor{gnat_rm/implementation_of_specific_ada_features id9}@anchor{427} @subsection Constant aggregates with unconstrained nominal types @@ -26408,7 +26390,7 @@ Cr_Unc : constant One_Unc := (12,24,36); @end example @node Aggregates with static bounds,Aggregates with nonstatic bounds,Constant aggregates with unconstrained nominal types,Code Generation for Array Aggregates -@anchor{gnat_rm/implementation_of_specific_ada_features id10}@anchor{429}@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-with-static-bounds}@anchor{42a} +@anchor{gnat_rm/implementation_of_specific_ada_features id10}@anchor{428}@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-with-static-bounds}@anchor{429} @subsection Aggregates with static bounds @@ -26436,7 +26418,7 @@ end loop; @end example @node Aggregates with nonstatic bounds,Aggregates in assignment statements,Aggregates with static bounds,Code Generation for Array Aggregates -@anchor{gnat_rm/implementation_of_specific_ada_features id11}@anchor{42b}@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-with-nonstatic-bounds}@anchor{42c} +@anchor{gnat_rm/implementation_of_specific_ada_features id11}@anchor{42a}@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-with-nonstatic-bounds}@anchor{42b} @subsection Aggregates with nonstatic bounds @@ -26447,7 +26429,7 @@ have to be applied to sub-arrays individually, if they do not have statically compatible subtypes. @node Aggregates in assignment statements,,Aggregates with nonstatic bounds,Code Generation for Array Aggregates -@anchor{gnat_rm/implementation_of_specific_ada_features id12}@anchor{42d}@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-in-assignment-statements}@anchor{42e} +@anchor{gnat_rm/implementation_of_specific_ada_features id12}@anchor{42c}@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-in-assignment-statements}@anchor{42d} @subsection Aggregates in assignment statements @@ -26489,7 +26471,7 @@ a temporary (created either by the front-end or the code generator) and then that temporary will be copied onto the target. @node The Size of Discriminated Records with Default Discriminants,Strict Conformance to the Ada Reference Manual,Code Generation for Array Aggregates,Implementation of Specific Ada Features -@anchor{gnat_rm/implementation_of_specific_ada_features id13}@anchor{42f}@anchor{gnat_rm/implementation_of_specific_ada_features the-size-of-discriminated-records-with-default-discriminants}@anchor{430} +@anchor{gnat_rm/implementation_of_specific_ada_features id13}@anchor{42e}@anchor{gnat_rm/implementation_of_specific_ada_features the-size-of-discriminated-records-with-default-discriminants}@anchor{42f} @section The Size of Discriminated Records with Default Discriminants @@ -26569,7 +26551,7 @@ say) must be consistent, so it is imperative that the object, once created, remain invariant. @node Strict Conformance to the Ada Reference Manual,,The Size of Discriminated Records with Default Discriminants,Implementation of Specific Ada Features -@anchor{gnat_rm/implementation_of_specific_ada_features strict-conformance-to-the-ada-reference-manual}@anchor{431}@anchor{gnat_rm/implementation_of_specific_ada_features id14}@anchor{432} +@anchor{gnat_rm/implementation_of_specific_ada_features strict-conformance-to-the-ada-reference-manual}@anchor{430}@anchor{gnat_rm/implementation_of_specific_ada_features id14}@anchor{431} @section Strict Conformance to the Ada Reference Manual @@ -26596,7 +26578,7 @@ behavior (although at the cost of a significant performance penalty), so infinite and NaN values are properly generated. @node Implementation of Ada 2012 Features,Obsolescent Features,Implementation of Specific Ada Features,Top -@anchor{gnat_rm/implementation_of_ada_2012_features doc}@anchor{433}@anchor{gnat_rm/implementation_of_ada_2012_features implementation-of-ada-2012-features}@anchor{14}@anchor{gnat_rm/implementation_of_ada_2012_features id1}@anchor{434} +@anchor{gnat_rm/implementation_of_ada_2012_features doc}@anchor{432}@anchor{gnat_rm/implementation_of_ada_2012_features implementation-of-ada-2012-features}@anchor{14}@anchor{gnat_rm/implementation_of_ada_2012_features id1}@anchor{433} @chapter Implementation of Ada 2012 Features @@ -28762,7 +28744,7 @@ RM References: H.04 (8/1) @end itemize @node Obsolescent Features,Compatibility and Porting Guide,Implementation of Ada 2012 Features,Top -@anchor{gnat_rm/obsolescent_features id1}@anchor{435}@anchor{gnat_rm/obsolescent_features doc}@anchor{436}@anchor{gnat_rm/obsolescent_features obsolescent-features}@anchor{15} +@anchor{gnat_rm/obsolescent_features id1}@anchor{434}@anchor{gnat_rm/obsolescent_features doc}@anchor{435}@anchor{gnat_rm/obsolescent_features obsolescent-features}@anchor{15} @chapter Obsolescent Features @@ -28781,7 +28763,7 @@ compatibility purposes. @end menu @node pragma No_Run_Time,pragma Ravenscar,,Obsolescent Features -@anchor{gnat_rm/obsolescent_features id2}@anchor{437}@anchor{gnat_rm/obsolescent_features pragma-no-run-time}@anchor{438} +@anchor{gnat_rm/obsolescent_features id2}@anchor{436}@anchor{gnat_rm/obsolescent_features pragma-no-run-time}@anchor{437} @section pragma No_Run_Time @@ -28794,7 +28776,7 @@ preferred usage is to use an appropriately configured run-time that includes just those features that are to be made accessible. @node pragma Ravenscar,pragma Restricted_Run_Time,pragma No_Run_Time,Obsolescent Features -@anchor{gnat_rm/obsolescent_features id3}@anchor{439}@anchor{gnat_rm/obsolescent_features pragma-ravenscar}@anchor{43a} +@anchor{gnat_rm/obsolescent_features id3}@anchor{438}@anchor{gnat_rm/obsolescent_features pragma-ravenscar}@anchor{439} @section pragma Ravenscar @@ -28803,7 +28785,7 @@ The pragma @code{Ravenscar} has exactly the same effect as pragma is part of the new Ada 2005 standard. @node pragma Restricted_Run_Time,pragma Task_Info,pragma Ravenscar,Obsolescent Features -@anchor{gnat_rm/obsolescent_features pragma-restricted-run-time}@anchor{43b}@anchor{gnat_rm/obsolescent_features id4}@anchor{43c} +@anchor{gnat_rm/obsolescent_features pragma-restricted-run-time}@anchor{43a}@anchor{gnat_rm/obsolescent_features id4}@anchor{43b} @section pragma Restricted_Run_Time @@ -28813,7 +28795,7 @@ preferred since the Ada 2005 pragma @code{Profile} is intended for this kind of implementation dependent addition. @node pragma Task_Info,package System Task_Info s-tasinf ads,pragma Restricted_Run_Time,Obsolescent Features -@anchor{gnat_rm/obsolescent_features pragma-task-info}@anchor{43d}@anchor{gnat_rm/obsolescent_features id5}@anchor{43e} +@anchor{gnat_rm/obsolescent_features pragma-task-info}@anchor{43c}@anchor{gnat_rm/obsolescent_features id5}@anchor{43d} @section pragma Task_Info @@ -28839,7 +28821,7 @@ in the spec of package System.Task_Info in the runtime library. @node package System Task_Info s-tasinf ads,,pragma Task_Info,Obsolescent Features -@anchor{gnat_rm/obsolescent_features package-system-task-info}@anchor{43f}@anchor{gnat_rm/obsolescent_features package-system-task-info-s-tasinf-ads}@anchor{440} +@anchor{gnat_rm/obsolescent_features package-system-task-info}@anchor{43e}@anchor{gnat_rm/obsolescent_features package-system-task-info-s-tasinf-ads}@anchor{43f} @section package System.Task_Info (@code{s-tasinf.ads}) @@ -28849,7 +28831,7 @@ to support the @code{Task_Info} pragma. The predefined Ada package standard replacement for GNAT's @code{Task_Info} functionality. @node Compatibility and Porting Guide,GNU Free Documentation License,Obsolescent Features,Top -@anchor{gnat_rm/compatibility_and_porting_guide compatibility-and-porting-guide}@anchor{16}@anchor{gnat_rm/compatibility_and_porting_guide doc}@anchor{441}@anchor{gnat_rm/compatibility_and_porting_guide id1}@anchor{442} +@anchor{gnat_rm/compatibility_and_porting_guide compatibility-and-porting-guide}@anchor{16}@anchor{gnat_rm/compatibility_and_porting_guide doc}@anchor{440}@anchor{gnat_rm/compatibility_and_porting_guide id1}@anchor{441} @chapter Compatibility and Porting Guide @@ -28871,7 +28853,7 @@ applications developed in other Ada environments. @end menu @node Writing Portable Fixed-Point Declarations,Compatibility with Ada 83,,Compatibility and Porting Guide -@anchor{gnat_rm/compatibility_and_porting_guide id2}@anchor{443}@anchor{gnat_rm/compatibility_and_porting_guide writing-portable-fixed-point-declarations}@anchor{444} +@anchor{gnat_rm/compatibility_and_porting_guide id2}@anchor{442}@anchor{gnat_rm/compatibility_and_porting_guide writing-portable-fixed-point-declarations}@anchor{443} @section Writing Portable Fixed-Point Declarations @@ -28993,7 +28975,7 @@ If you follow this scheme you will be guaranteed that your fixed-point types will be portable. @node Compatibility with Ada 83,Compatibility between Ada 95 and Ada 2005,Writing Portable Fixed-Point Declarations,Compatibility and Porting Guide -@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-ada-83}@anchor{445}@anchor{gnat_rm/compatibility_and_porting_guide id3}@anchor{446} +@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-ada-83}@anchor{444}@anchor{gnat_rm/compatibility_and_porting_guide id3}@anchor{445} @section Compatibility with Ada 83 @@ -29021,7 +29003,7 @@ following subsections treat the most likely issues to be encountered. @end menu @node Legal Ada 83 programs that are illegal in Ada 95,More deterministic semantics,,Compatibility with Ada 83 -@anchor{gnat_rm/compatibility_and_porting_guide id4}@anchor{447}@anchor{gnat_rm/compatibility_and_porting_guide legal-ada-83-programs-that-are-illegal-in-ada-95}@anchor{448} +@anchor{gnat_rm/compatibility_and_porting_guide id4}@anchor{446}@anchor{gnat_rm/compatibility_and_porting_guide legal-ada-83-programs-that-are-illegal-in-ada-95}@anchor{447} @subsection Legal Ada 83 programs that are illegal in Ada 95 @@ -29121,7 +29103,7 @@ the fix is usually simply to add the @code{(<>)} to the generic declaration. @end itemize @node More deterministic semantics,Changed semantics,Legal Ada 83 programs that are illegal in Ada 95,Compatibility with Ada 83 -@anchor{gnat_rm/compatibility_and_porting_guide more-deterministic-semantics}@anchor{449}@anchor{gnat_rm/compatibility_and_porting_guide id5}@anchor{44a} +@anchor{gnat_rm/compatibility_and_porting_guide more-deterministic-semantics}@anchor{448}@anchor{gnat_rm/compatibility_and_porting_guide id5}@anchor{449} @subsection More deterministic semantics @@ -29149,7 +29131,7 @@ which open select branches are executed. @end itemize @node Changed semantics,Other language compatibility issues,More deterministic semantics,Compatibility with Ada 83 -@anchor{gnat_rm/compatibility_and_porting_guide id6}@anchor{44b}@anchor{gnat_rm/compatibility_and_porting_guide changed-semantics}@anchor{44c} +@anchor{gnat_rm/compatibility_and_porting_guide id6}@anchor{44a}@anchor{gnat_rm/compatibility_and_porting_guide changed-semantics}@anchor{44b} @subsection Changed semantics @@ -29191,7 +29173,7 @@ covers only the restricted range. @end itemize @node Other language compatibility issues,,Changed semantics,Compatibility with Ada 83 -@anchor{gnat_rm/compatibility_and_porting_guide other-language-compatibility-issues}@anchor{44d}@anchor{gnat_rm/compatibility_and_porting_guide id7}@anchor{44e} +@anchor{gnat_rm/compatibility_and_porting_guide other-language-compatibility-issues}@anchor{44c}@anchor{gnat_rm/compatibility_and_porting_guide id7}@anchor{44d} @subsection Other language compatibility issues @@ -29224,7 +29206,7 @@ include @code{pragma Interface} and the floating point type attributes @end itemize @node Compatibility between Ada 95 and Ada 2005,Implementation-dependent characteristics,Compatibility with Ada 83,Compatibility and Porting Guide -@anchor{gnat_rm/compatibility_and_porting_guide compatibility-between-ada-95-and-ada-2005}@anchor{44f}@anchor{gnat_rm/compatibility_and_porting_guide id8}@anchor{450} +@anchor{gnat_rm/compatibility_and_porting_guide compatibility-between-ada-95-and-ada-2005}@anchor{44e}@anchor{gnat_rm/compatibility_and_porting_guide id8}@anchor{44f} @section Compatibility between Ada 95 and Ada 2005 @@ -29296,7 +29278,7 @@ can declare a function returning a value from an anonymous access type. @end itemize @node Implementation-dependent characteristics,Compatibility with Other Ada Systems,Compatibility between Ada 95 and Ada 2005,Compatibility and Porting Guide -@anchor{gnat_rm/compatibility_and_porting_guide implementation-dependent-characteristics}@anchor{451}@anchor{gnat_rm/compatibility_and_porting_guide id9}@anchor{452} +@anchor{gnat_rm/compatibility_and_porting_guide implementation-dependent-characteristics}@anchor{450}@anchor{gnat_rm/compatibility_and_porting_guide id9}@anchor{451} @section Implementation-dependent characteristics @@ -29319,7 +29301,7 @@ transition from certain Ada 83 compilers. @end menu @node Implementation-defined pragmas,Implementation-defined attributes,,Implementation-dependent characteristics -@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-pragmas}@anchor{453}@anchor{gnat_rm/compatibility_and_porting_guide id10}@anchor{454} +@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-pragmas}@anchor{452}@anchor{gnat_rm/compatibility_and_porting_guide id10}@anchor{453} @subsection Implementation-defined pragmas @@ -29341,7 +29323,7 @@ avoiding compiler rejection of units that contain such pragmas; they are not relevant in a GNAT context and hence are not otherwise implemented. @node Implementation-defined attributes,Libraries,Implementation-defined pragmas,Implementation-dependent characteristics -@anchor{gnat_rm/compatibility_and_porting_guide id11}@anchor{455}@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-attributes}@anchor{456} +@anchor{gnat_rm/compatibility_and_porting_guide id11}@anchor{454}@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-attributes}@anchor{455} @subsection Implementation-defined attributes @@ -29355,7 +29337,7 @@ Ada 83, GNAT supplies the attributes @code{Bit}, @code{Machine_Size} and @code{Type_Class}. @node Libraries,Elaboration order,Implementation-defined attributes,Implementation-dependent characteristics -@anchor{gnat_rm/compatibility_and_porting_guide libraries}@anchor{457}@anchor{gnat_rm/compatibility_and_porting_guide id12}@anchor{458} +@anchor{gnat_rm/compatibility_and_porting_guide libraries}@anchor{456}@anchor{gnat_rm/compatibility_and_porting_guide id12}@anchor{457} @subsection Libraries @@ -29384,7 +29366,7 @@ be preferable to retrofit the application using modular types. @end itemize @node Elaboration order,Target-specific aspects,Libraries,Implementation-dependent characteristics -@anchor{gnat_rm/compatibility_and_porting_guide elaboration-order}@anchor{459}@anchor{gnat_rm/compatibility_and_porting_guide id13}@anchor{45a} +@anchor{gnat_rm/compatibility_and_porting_guide elaboration-order}@anchor{458}@anchor{gnat_rm/compatibility_and_porting_guide id13}@anchor{459} @subsection Elaboration order @@ -29420,7 +29402,7 @@ pragmas either globally (as an effect of the @emph{-gnatE} switch) or locally @end itemize @node Target-specific aspects,,Elaboration order,Implementation-dependent characteristics -@anchor{gnat_rm/compatibility_and_porting_guide target-specific-aspects}@anchor{45b}@anchor{gnat_rm/compatibility_and_porting_guide id14}@anchor{45c} +@anchor{gnat_rm/compatibility_and_porting_guide target-specific-aspects}@anchor{45a}@anchor{gnat_rm/compatibility_and_porting_guide id14}@anchor{45b} @subsection Target-specific aspects @@ -29433,10 +29415,10 @@ on the robustness of the original design. Moreover, Ada 95 (and thus Ada 2005 and Ada 2012) are sometimes incompatible with typical Ada 83 compiler practices regarding implicit packing, the meaning of the Size attribute, and the size of access values. -GNAT's approach to these issues is described in @ref{45d,,Representation Clauses}. +GNAT's approach to these issues is described in @ref{45c,,Representation Clauses}. @node Compatibility with Other Ada Systems,Representation Clauses,Implementation-dependent characteristics,Compatibility and Porting Guide -@anchor{gnat_rm/compatibility_and_porting_guide id15}@anchor{45e}@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-other-ada-systems}@anchor{45f} +@anchor{gnat_rm/compatibility_and_porting_guide id15}@anchor{45d}@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-other-ada-systems}@anchor{45e} @section Compatibility with Other Ada Systems @@ -29479,7 +29461,7 @@ far beyond this minimal set, as described in the next section. @end itemize @node Representation Clauses,Compatibility with HP Ada 83,Compatibility with Other Ada Systems,Compatibility and Porting Guide -@anchor{gnat_rm/compatibility_and_porting_guide representation-clauses}@anchor{45d}@anchor{gnat_rm/compatibility_and_porting_guide id16}@anchor{460} +@anchor{gnat_rm/compatibility_and_porting_guide representation-clauses}@anchor{45c}@anchor{gnat_rm/compatibility_and_porting_guide id16}@anchor{45f} @section Representation Clauses @@ -29572,7 +29554,7 @@ with thin pointers. @end itemize @node Compatibility with HP Ada 83,,Representation Clauses,Compatibility and Porting Guide -@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-hp-ada-83}@anchor{461}@anchor{gnat_rm/compatibility_and_porting_guide id17}@anchor{462} +@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-hp-ada-83}@anchor{460}@anchor{gnat_rm/compatibility_and_porting_guide id17}@anchor{461} @section Compatibility with HP Ada 83 @@ -29602,7 +29584,7 @@ extension of package System. @end itemize @node GNU Free Documentation License,Index,Compatibility and Porting Guide,Top -@anchor{share/gnu_free_documentation_license gnu-fdl}@anchor{1}@anchor{share/gnu_free_documentation_license doc}@anchor{463}@anchor{share/gnu_free_documentation_license gnu-free-documentation-license}@anchor{464} +@anchor{share/gnu_free_documentation_license gnu-fdl}@anchor{1}@anchor{share/gnu_free_documentation_license doc}@anchor{462}@anchor{share/gnu_free_documentation_license gnu-free-documentation-license}@anchor{463} @chapter GNU Free Documentation License diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi index c2dd053..eddd9e4 100644 --- a/gcc/ada/gnat_ugn.texi +++ b/gcc/ada/gnat_ugn.texi @@ -21,7 +21,7 @@ @copying @quotation -GNAT User's Guide for Native Platforms , Aug 01, 2019 +GNAT User's Guide for Native Platforms , Sep 13, 2019 AdaCore @@ -13661,7 +13661,7 @@ in the source text. The set of style check switches is set to match that used by the GNAT sources. This may be useful when developing code that is eventually intended to be -incorporated into GNAT. Currently this is equivalent to @code{-gnatwydISux}) +incorporated into GNAT. Currently this is equivalent to @code{-gnatyydISux}) but additional style switches may be added to this set in the future without advance notice. @end table -- cgit v1.1 From 77562afd5b514434c7f6cacaeb1eaaa234d19736 Mon Sep 17 00:00:00 2001 From: Claire Dross Date: Tue, 17 Sep 2019 08:01:58 +0000 Subject: [Ada] Support chained calls to traversal functions in SPARK This change only affects the SPARK toolset. In the part of semantic analysis enforcing ownership rules for SPARK, it corrects a crash in analysis of a declaration of a local borrower whose definition is a chain of several calls to traversal functions. 2019-09-17 Claire Dross gcc/ada/ * sem_spark.adb (Get_Observed_Or_Borrowed_Expr): If the definition of a local borrower contains calls to traversal functions, the borrowed expression is the first parameter of the first traversal function call in the definition. From-SVN: r275785 --- gcc/ada/ChangeLog | 7 ++++++ gcc/ada/sem_spark.adb | 63 +++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 63 insertions(+), 7 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 7ccb70f..baf17ca 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,10 @@ +2019-09-17 Claire Dross + + * sem_spark.adb (Get_Observed_Or_Borrowed_Expr): If the + definition of a local borrower contains calls to traversal + functions, the borrowed expression is the first parameter of the + first traversal function call in the definition. + 2019-09-17 Ed Falis * doc/gnat_rm/implementation_defined_pragmas.rst: Remove diff --git a/gcc/ada/sem_spark.adb b/gcc/ada/sem_spark.adb index 038c7cd..af53f69 100644 --- a/gcc/ada/sem_spark.adb +++ b/gcc/ada/sem_spark.adb @@ -708,8 +708,8 @@ package body Sem_SPARK is function Get_Observed_Or_Borrowed_Expr (Expr : Node_Id) return Node_Id; pragma Precondition (Is_Path_Expression (Expr)); -- Return the expression being borrowed/observed when borrowing or - -- observing Expr. If Expr is a call to a traversal function, this is - -- the first actual, otherwise it is Expr. + -- observing Expr. If Expr contains a call to traversal function, this is + -- the first actual of the first such call, otherwise it is Expr. function Get_Perm (N : Node_Or_Entity_Id) return Perm_Kind; -- The function that takes a name as input and returns a permission @@ -3772,12 +3772,61 @@ package body Sem_SPARK is ----------------------------------- function Get_Observed_Or_Borrowed_Expr (Expr : Node_Id) return Node_Id is + + function Find_Func_Call (Expr : Node_Id) return Node_Id; + -- Search for function calls in the prefixes of Expr + + -------------------- + -- Find_Func_Call -- + -------------------- + + function Find_Func_Call (Expr : Node_Id) return Node_Id is + begin + case Nkind (Expr) is + when N_Expanded_Name + | N_Identifier + => + return Empty; + + when N_Explicit_Dereference + | N_Indexed_Component + | N_Selected_Component + | N_Slice + => + return Find_Func_Call (Prefix (Expr)); + + when N_Qualified_Expression + | N_Type_Conversion + | N_Unchecked_Type_Conversion + => + return Find_Func_Call (Expression (Expr)); + + when N_Function_Call => + return Expr; + + when others => + raise Program_Error; + end case; + end Find_Func_Call; + + B_Expr : Node_Id := Expr; + begin - if Is_Traversal_Function_Call (Expr) then - return First_Actual (Expr); - else - return Expr; - end if; + -- Search for the first call to a traversal function in Expr. If there + -- is one, its first parameter is the borrowed expression. Otherwise, + -- it is Expr. + + loop + declare + Call : constant Node_Id := Find_Func_Call (B_Expr); + begin + exit when No (Call); + pragma Assert (Is_Traversal_Function_Call (Call)); + B_Expr := First_Actual (Call); + end; + end loop; + + return B_Expr; end Get_Observed_Or_Borrowed_Expr; -------------- -- cgit v1.1 From 0a39f241944cfb7090d73e076913ff068a1cc32f Mon Sep 17 00:00:00 2001 From: Steve Baird Date: Tue, 17 Sep 2019 08:02:04 +0000 Subject: [Ada] Don't accept illegal (e.g., Integer'(null)) generic actuals Sem_Util.Wrong_Type usually emits an error message, but in some cases it does not. The code which prevents emitting an error message was going too far in some cases, causing illegal constructs to be accepted. For example, a qualified expression such as Integer'(null) might be passed in as an actual parameter in an instantiation of a generic and generate no error message. Running this command: gcc -c inst.ads On the following sources: package Inst is type Ptr is new Integer; generic type TElement is private; NonDefini : TElement; package ArbMgr is end ArbMgr; package Pack is new ArbMgr (Ptr, Ptr'(null)); procedure Dummy; end Inst; Should produce the following output: inst.ads:10:42: expected type "Ptr" defined at line 2 inst.ads:10:42: found an access type compilation abandoned due to previous error 2019-09-17 Steve Baird gcc/ada/ * sem_util.adb (Wrong_Type): In deciding to suppress a message, it is not enough for In_Instance to be True; in addition, In_Generic_Actual (Expr) must be False. * sem_type.adb (In_Generic_Actual): Fix bug where traversal of parents skips every other node. From-SVN: r275786 --- gcc/ada/ChangeLog | 8 ++++++++ gcc/ada/sem_type.adb | 2 +- gcc/ada/sem_util.adb | 14 ++++++++++++-- 3 files changed, 21 insertions(+), 3 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index baf17ca..32d35b9 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,11 @@ +2019-09-17 Steve Baird + + * sem_util.adb (Wrong_Type): In deciding to suppress a message, + it is not enough for In_Instance to be True; in addition, + In_Generic_Actual (Expr) must be False. + * sem_type.adb (In_Generic_Actual): Fix bug where traversal of + parents skips every other node. + 2019-09-17 Claire Dross * sem_spark.adb (Get_Observed_Or_Borrowed_Expr): If the diff --git a/gcc/ada/sem_type.adb b/gcc/ada/sem_type.adb index fee9c5e..fc50524 100644 --- a/gcc/ada/sem_type.adb +++ b/gcc/ada/sem_type.adb @@ -2849,7 +2849,7 @@ package body Sem_Type is return False; else - return In_Generic_Actual (Parent (Par)); + return In_Generic_Actual (Par); end if; end In_Generic_Actual; diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb index b7d2895..99cdb8d 100644 --- a/gcc/ada/sem_util.adb +++ b/gcc/ada/sem_util.adb @@ -26689,7 +26689,7 @@ package body Sem_Util is return; -- In an instance, there is an ongoing problem with completion of - -- type derived from private types. Their structure is what Gigi + -- types derived from private types. Their structure is what Gigi -- expects, but the Etype is the parent type rather than the -- derived private type itself. Do not flag error in this case. The -- private completion is an entity without a parent, like an Itype. @@ -26700,7 +26700,17 @@ package body Sem_Util is -- same reason: inserted body may be outside of the original package -- and only partial views are visible at the point of insertion. - elsif In_Instance or else In_Inlined_Body then + -- If In_Generic_Actual (Expr) is True then we cannot assume that + -- the successful semantic analysis of the generic guarantees anything + -- useful about type checking of this instance, so we ignore + -- In_Instance in that case. There may be cases where this is not + -- right (the symptom would probably be rejecting something + -- that ought to be accepted) but we don't currently have any + -- concrete examples of this. + + elsif (In_Instance and then not In_Generic_Actual (Expr)) + or else In_Inlined_Body + then if Etype (Etype (Expr)) = Etype (Expected_Type) and then (Has_Private_Declaration (Expected_Type) -- cgit v1.1 From 86ae194fdb343487d37899f4f51fdf3e626822e0 Mon Sep 17 00:00:00 2001 From: Bob Duff Date: Tue, 17 Sep 2019 08:02:09 +0000 Subject: [Ada] Clarify documentation for Stack_Usage Clarify the documentation for Stack_Usage (both comments in the code, and user documentation) to note that tools like Valgrind won't work. 2019-09-17 Bob Duff gcc/ada/ * doc/gnat_ugn/gnat_and_program_execution.rst: Clarify documentation. * gnat_ugn.texi: Regenerate. * libgnat/s-stausa.ads: Clarify comments. From-SVN: r275787 --- gcc/ada/ChangeLog | 7 +++++++ gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst | 5 ++++- gcc/ada/gnat_ugn.texi | 7 +++++-- gcc/ada/libgnat/s-stausa.ads | 5 +++++ 4 files changed, 21 insertions(+), 3 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 32d35b9..f0d1f37 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,10 @@ +2019-09-17 Bob Duff + + * doc/gnat_ugn/gnat_and_program_execution.rst: Clarify + documentation. + * gnat_ugn.texi: Regenerate. + * libgnat/s-stausa.ads: Clarify comments. + 2019-09-17 Steve Baird * sem_util.adb (Wrong_Type): In deciding to suppress a message, diff --git a/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst b/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst index d2675c7..56ee103 100644 --- a/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst +++ b/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst @@ -3396,8 +3396,11 @@ adding a switch to ``gnatbind``, as: $ gnatbind -u0 file -With this option, at each task termination, its stack usage is output on +With this option, at each task termination, its stack usage is output on :file:`stderr`. +Note that this switch is not compatible with tools like +Valgrind and DrMemory; they will report errors. + It is not always convenient to output the stack usage when the program is still running. Hence, it is possible to delay this output until program termination. for a given number of tasks specified as the argument of the diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi index eddd9e4..5db9c76 100644 --- a/gcc/ada/gnat_ugn.texi +++ b/gcc/ada/gnat_ugn.texi @@ -21,7 +21,7 @@ @copying @quotation -GNAT User's Guide for Native Platforms , Sep 13, 2019 +GNAT User's Guide for Native Platforms , Sep 14, 2019 AdaCore @@ -23321,8 +23321,11 @@ $ gnatbind -u0 file @end example @end quotation -With this option, at each task termination, its stack usage is output on +With this option, at each task termination, its stack usage is output on @code{stderr}. +Note that this switch is not compatible with tools like +Valgrind and DrMemory; they will report errors. + It is not always convenient to output the stack usage when the program is still running. Hence, it is possible to delay this output until program termination. for a given number of tasks specified as the argument of the diff --git a/gcc/ada/libgnat/s-stausa.ads b/gcc/ada/libgnat/s-stausa.ads index 03bc760..2dfa735 100644 --- a/gcc/ada/libgnat/s-stausa.ads +++ b/gcc/ada/libgnat/s-stausa.ads @@ -67,6 +67,11 @@ package System.Stack_Usage is -- Type of the stack analyzer tool. It is used to fill a portion of the -- stack with Pattern, and to compute the stack used after some execution. + -- Note that Fill_Stack writes data past the current top of the stack + -- (i.e. at addresses less than the stack pointer register, assuming the + -- stack grows downward). Therefore, this package is incompatible with + -- tools like Valgrind and DrMemory. + -- Usage: -- A typical use of the package is something like: -- cgit v1.1 From 8df56dfc6991bda3c1cfa9d102c49d963763d5b4 Mon Sep 17 00:00:00 2001 From: Yannick Moy Date: Tue, 17 Sep 2019 08:02:15 +0000 Subject: [Ada] GNATprove: avoid crash on illegal borrow during package elaboration In GNATprove, a borrow during package elaboration is illegal, but a crash could be issued when analyzing the corresponding declaration. Now avoid analyzing the declaration in that case. There is no test as this does not impact compilation. 2019-09-17 Yannick Moy gcc/ada/ * sem_spark.adb (Check_Declaration): Do not check the assignment from an illegal declaration. From-SVN: r275788 --- gcc/ada/ChangeLog | 5 +++++ gcc/ada/sem_spark.adb | 12 ++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index f0d1f37..af3a2e7 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,8 @@ +2019-09-17 Yannick Moy + + * sem_spark.adb (Check_Declaration): Do not check the assignment + from an illegal declaration. + 2019-09-17 Bob Duff * doc/gnat_ugn/gnat_and_program_execution.rst: Clarify diff --git a/gcc/ada/sem_spark.adb b/gcc/ada/sem_spark.adb index af53f69..e4a8b3e 100644 --- a/gcc/ada/sem_spark.adb +++ b/gcc/ada/sem_spark.adb @@ -1419,12 +1419,12 @@ package body Sem_SPARK is Target : constant Entity_Id := Defining_Identifier (Decl); Target_Typ : constant Node_Id := Etype (Target); Expr : Node_Id; - Dummy : Boolean := True; + Legal : Boolean := True; begin -- Start with legality rules not related to permissions - Check_Declaration_Legality (Decl, Force => True, Legal => Dummy); + Check_Declaration_Legality (Decl, Force => True, Legal => Legal); -- Now check permission-related legality rules @@ -1432,7 +1432,7 @@ package body Sem_SPARK is when N_Full_Type_Declaration => null; - -- ??? What about component declarations with defaults. + -- ??? What about component declarations with defaults. when N_Subtype_Declaration => Check_Expression (Subtype_Indication (Decl), Read); @@ -1440,11 +1440,15 @@ package body Sem_SPARK is when N_Object_Declaration => Expr := Expression (Decl); - if Present (Expr) then + if Legal and then Present (Expr) then Check_Assignment (Target => Target, Expr => Expr); end if; + -- Always add variable to the current permission environment, + -- even in the illegal case, as the rest of the analysis expects + -- to find it. + if Is_Deep (Target_Typ) then declare Tree : constant Perm_Tree_Access := -- cgit v1.1 From 64989f18c04c7444ecb67da9a6ccecbe40bb1c12 Mon Sep 17 00:00:00 2001 From: Dmitriy Anisimkov Date: Tue, 17 Sep 2019 08:02:20 +0000 Subject: [Ada] Force even timestamp in Windows ALI files Old versions forced even file timestamp in Windows in GNAT.OS_Lib.GM_Split implementation. We removed this time distortion in GNAT.OS_Lib.GM_Split a few commits. But gprbuild became unnecessary recompiling the sources in 50% cases, when the source has odd file timestamp. This commit is restoring the compatibility between new gprbuild and old GNAT compilers. 2019-09-17 Dmitriy Anisimkov gcc/ada/ * make_util.ads (On_Windows): Move... * osint.ads (On_Windows): There. * osint.adb (OS_Time_To_GNAT_Time): If odd incremented on Windows before conversion to Time_Stamp_Type. From-SVN: r275789 --- gcc/ada/ChangeLog | 7 +++++++ gcc/ada/make_util.ads | 2 +- gcc/ada/osint.adb | 17 ++++++++++++++++- gcc/ada/osint.ads | 3 +++ 4 files changed, 27 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index af3a2e7..13a3a76 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,10 @@ +2019-09-17 Dmitriy Anisimkov + + * make_util.ads (On_Windows): Move... + * osint.ads (On_Windows): There. + * osint.adb (OS_Time_To_GNAT_Time): If odd incremented on + Windows before conversion to Time_Stamp_Type. + 2019-09-17 Yannick Moy * sem_spark.adb (Check_Declaration): Do not check the assignment diff --git a/gcc/ada/make_util.ads b/gcc/ada/make_util.ads index c9be894..9bd576a 100644 --- a/gcc/ada/make_util.ads +++ b/gcc/ada/make_util.ads @@ -50,7 +50,7 @@ package Make_Util is -- Name of the configuration file used by gprbuild and generated by -- gprconfig by default. - On_Windows : constant Boolean := Directory_Separator = '\'; + On_Windows : Boolean renames Osint.On_Windows; -- True when on Windows Source_Info_Option : constant String := "--source-info="; diff --git a/gcc/ada/osint.adb b/gcc/ada/osint.adb index d9d72d0..973f463 100644 --- a/gcc/ada/osint.adb +++ b/gcc/ada/osint.adb @@ -88,6 +88,10 @@ package body Osint is function OS_Time_To_GNAT_Time (T : OS_Time) return Time_Stamp_Type; -- Convert OS format time to GNAT format time stamp. If T is Invalid_Time, -- then returns Empty_Time_Stamp. + -- Round to even seconds on Windows before conversion. + -- Windows ALI files had timestamps rounded to even seconds historically. + -- The rounding was originally done in GM_Split. Now that GM_Split no + -- longer does it, we are rounding it here only for ALI files. function Executable_Prefix return String_Ptr; -- Returns the name of the root directory where the executable is stored. @@ -2179,6 +2183,7 @@ package body Osint is function OS_Time_To_GNAT_Time (T : OS_Time) return Time_Stamp_Type is GNAT_Time : Time_Stamp_Type; + TI : Long_Integer := To_C (T); Y : Year_Type; Mo : Month_Type; D : Day_Type; @@ -2191,7 +2196,17 @@ package body Osint is return Empty_Time_Stamp; end if; - GM_Split (T, Y, Mo, D, H, Mn, S); + if On_Windows and then TI mod 2 > 0 then + -- Windows ALI files had timestamps rounded to even seconds + -- historically. The rounding was originally done in GM_Split. + -- Now that GM_Split no longer does it, we are rounding it here + -- only for ALI files. + + TI := TI + 1; + end if; + + GM_Split (To_Ada (TI), Y, Mo, D, H, Mn, S); + Make_Time_Stamp (Year => Nat (Y), Month => Nat (Mo), diff --git a/gcc/ada/osint.ads b/gcc/ada/osint.ads index dda44e7..a0b046c 100644 --- a/gcc/ada/osint.ads +++ b/gcc/ada/osint.ads @@ -56,6 +56,9 @@ package Osint is -- File descriptor for current library info, list, tree, C, H, or binder -- output. Only one of these is open at a time, so we need only one FD. + On_Windows : constant Boolean := Directory_Separator = '\'; + -- True when on Windows + procedure Initialize; -- Initialize internal tables -- cgit v1.1 From 7197e2db28f10dec509967bb1cbd2d74cb03ee7e Mon Sep 17 00:00:00 2001 From: Yannick Moy Date: Tue, 17 Sep 2019 08:02:25 +0000 Subject: [Ada] Fix possible suppressed overflows in arithmetic run-time Function Double_Divide computes the division of its parameters (X / (Y*Z)) in a way that avoids overflows on signed integers, except in two specific cases, when X = -2**63, abs(Y) = abs(Z) = 1 (leading to an overflow in -To_Int(Qu)) and when X = -2**63 and Y*Z is large enough that Qu=0 and so the remainder Ru=2**63 (leading to an overflow in -To_Int(Ru)), for example with Y = Z = 2**32-1. This fix avoids the overflow by applying "-" on the unsigned value before the conversion to signed integer. The issue cannot manifest as an overflow check failure in our runtime, as overflow checks are suppressed by using pragma Suppress at the start of the file. Assuming a machine implements wraparound semantics here, the result was correct even with the suppressed overflow. As a result, there can be no test showing the difference. 2019-09-17 Yannick Moy gcc/ada/ * libgnat/s-arit64.adb (Double_Divide): Fix two possible overflows. From-SVN: r275790 --- gcc/ada/ChangeLog | 5 +++++ gcc/ada/libgnat/s-arit64.adb | 8 ++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 13a3a76..913b30f 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,8 @@ +2019-09-17 Yannick Moy + + * libgnat/s-arit64.adb (Double_Divide): Fix two possible + overflows. + 2019-09-17 Dmitriy Anisimkov * make_util.ads (On_Windows): Move... diff --git a/gcc/ada/libgnat/s-arit64.adb b/gcc/ada/libgnat/s-arit64.adb index 3a65ec0..a35a40d 100644 --- a/gcc/ada/libgnat/s-arit64.adb +++ b/gcc/ada/libgnat/s-arit64.adb @@ -204,9 +204,13 @@ package body System.Arith_64 is -- Case of dividend (X) sign negative + -- We perform the unary minus operation on the unsigned value + -- before conversion to signed, to avoid a possible overflow for + -- value -2**63, both for computing R and Q. + else - R := -To_Int (Ru); - Q := (if Den_Pos then -To_Int (Qu) else To_Int (Qu)); + R := To_Int (-Ru); + Q := (if Den_Pos then To_Int (-Qu) else To_Int (Qu)); end if; end Double_Divide; -- cgit v1.1 From d4ba72cbad263d9b4fd211534c117343ed5333a1 Mon Sep 17 00:00:00 2001 From: Yannick Moy Date: Tue, 17 Sep 2019 08:02:30 +0000 Subject: [Ada] Raise Constraint_Error in overflow case involving rounding Function Scaled_Divide in s-arith runtime unit computes the combined multiplication and division of its arguments ((X*Y) / Z). In a very special case where the quotient computed before rounding is 2**64-1, then rounding may lead to undesirable wrap-around, leading to a computed quotient of 0 instead of raising Constraint_Error as expected. This function is only called in the runtime for arithmetic operations involving fixed-point types. Rounding is performed only when the target type is of a decimal fixed-point type, and the attribute 'Round of the type is used to round the result of the arithmetic operation. This fix correctly raises Constraint_Error in this special case. 2019-09-17 Yannick Moy gcc/ada/ * libgnat/s-arit64.adb (Scaled_Divide): Add protection against undesirable wrap-around. gcc/testsuite/ * gnat.dg/multfixed.adb: New testcase. From-SVN: r275791 --- gcc/ada/ChangeLog | 5 +++++ gcc/ada/libgnat/s-arit64.adb | 8 ++++++++ gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gnat.dg/multfixed.adb | 24 ++++++++++++++++++++++++ 4 files changed, 41 insertions(+) create mode 100644 gcc/testsuite/gnat.dg/multfixed.adb (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 913b30f..9a07751 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,5 +1,10 @@ 2019-09-17 Yannick Moy + * libgnat/s-arit64.adb (Scaled_Divide): Add protection against + undesirable wrap-around. + +2019-09-17 Yannick Moy + * libgnat/s-arit64.adb (Double_Divide): Fix two possible overflows. diff --git a/gcc/ada/libgnat/s-arit64.adb b/gcc/ada/libgnat/s-arit64.adb index a35a40d..6773dd8 100644 --- a/gcc/ada/libgnat/s-arit64.adb +++ b/gcc/ada/libgnat/s-arit64.adb @@ -511,6 +511,14 @@ package body System.Arith_64 is -- Deal with rounding case if Round and then Ru > (Zu - Uns64'(1)) / Uns64'(2) then + + -- Protect against wrapping around when rounding, by signaling + -- an overflow when the quotient is too large. + + if Qu = Uns64'Last then + Raise_Error; + end if; + Qu := Qu + Uns64 (1); end if; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index caed11b..28d5f26 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-09-17 Yannick Moy + + * gnat.dg/multfixed.adb: New testcase. + 2019-09-17 Vadim Godunko * gnat.dg/expect3.adb: New testcase. diff --git a/gcc/testsuite/gnat.dg/multfixed.adb b/gcc/testsuite/gnat.dg/multfixed.adb new file mode 100644 index 0000000..2eca3cd --- /dev/null +++ b/gcc/testsuite/gnat.dg/multfixed.adb @@ -0,0 +1,24 @@ +-- { dg-do run } + +with Ada.Exceptions; use Ada.Exceptions; + +procedure Multfixed is + Z : constant := 4387648782261400837.0; + type F1 is delta 1.0 / Z range 0.0 .. (2.0**63-1.0) / Z + with Small => 1.0 / Z; + type F2 is delta 1.0 range 0.0 .. (2.0**63-1.0) + with Small => 1.0; + type D is delta 1.0 digits 18; + + X : F1 := 8914588002054909637.0 / Z; + Y : F2 := 9079256848778919936.0; + U : D; +begin + U := D'Round(X * Y); + raise Program_Error; +exception + when Exc : Constraint_Error => + if Exception_Message (Exc) /= "System.Arith_64.Raise_Error: 64-bit arithmetic overflow" then + raise Program_Error; + end if; +end Multfixed; \ No newline at end of file -- cgit v1.1 From fd339ba30825fa9de81db191beca5cf760347612 Mon Sep 17 00:00:00 2001 From: Yannick Moy Date: Tue, 17 Sep 2019 08:02:35 +0000 Subject: [Ada] Minor fixes mostly in comments of runtime arithmetic unit Multiple comments in functions Double_Divide and Scaled_Divide were incorrect. Now fixed. Also change the expression (if Zhi /= 0 then Ylo * Zhi else 0) to the simpler equivalent (Ylo * Zhi) in Double_Divide. Also add a comment explaining why the implementation of Algorithm D for multiple-precision division from the 2nd Edition of The Art of Computer Programming does not suffer from two bugs discovered on that version. There is no impact on execution, hence no test. 2019-09-17 Yannick Moy gcc/ada/ * libgnat/s-arit64.adb (Double_Divide): Simplify needlessly complex computation. Fix comments. (Scaled_Divide): Fix comments. Explain why implementation does not suffer from bugs in Algorithm D from 2nd Edition of TAOCP. From-SVN: r275792 --- gcc/ada/ChangeLog | 7 +++++++ gcc/ada/libgnat/s-arit64.adb | 26 ++++++++++++++++++++------ 2 files changed, 27 insertions(+), 6 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 9a07751..0d7fc8f 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,5 +1,12 @@ 2019-09-17 Yannick Moy + * libgnat/s-arit64.adb (Double_Divide): Simplify needlessly + complex computation. Fix comments. + (Scaled_Divide): Fix comments. Explain why implementation does + not suffer from bugs in Algorithm D from 2nd Edition of TAOCP. + +2019-09-17 Yannick Moy + * libgnat/s-arit64.adb (Scaled_Divide): Add protection against undesirable wrap-around. diff --git a/gcc/ada/libgnat/s-arit64.adb b/gcc/ada/libgnat/s-arit64.adb index 6773dd8..b5a5ac4 100644 --- a/gcc/ada/libgnat/s-arit64.adb +++ b/gcc/ada/libgnat/s-arit64.adb @@ -161,7 +161,7 @@ package body System.Arith_64 is end if; else - T2 := (if Zhi /= 0 then Ylo * Zhi else 0); + T2 := Ylo * Zhi; end if; T1 := Ylo * Zlo; @@ -179,7 +179,7 @@ package body System.Arith_64 is Den_Pos := (Y < 0) = (Z < 0); - -- Check overflow case of largest negative number divided by 1 + -- Check overflow case of largest negative number divided by -1 if X = Int64'First and then Du = 1 and then not Den_Pos then Raise_Error; @@ -404,15 +404,16 @@ package body System.Arith_64 is Ru := T2 rem Zlo; end if; - -- If divisor is double digit and too large, raise error + -- If divisor is double digit and dividend is too large, raise error elsif (D (1) & D (2)) >= Zu then Raise_Error; -- This is the complex case where we definitely have a double digit -- divisor and a dividend of at least three digits. We use the classical - -- multiple division algorithm (see section (4.3.1) of Knuth's "The Art - -- of Computer Programming", Vol. 2 for a description (algorithm D). + -- multiple-precision division algorithm (see section (4.3.1) of Knuth's + -- "The Art of Computer Programming", Vol. 2 for a description + -- (algorithm D). else -- First normalize the divisor so that it has the leading bit on. @@ -450,7 +451,7 @@ package body System.Arith_64 is -- Note that when we scale up the dividend, it still fits in four -- digits, since we already tested for overflow, and scaling does - -- not change the invariant that (D (1) & D (2)) >= Zu. + -- not change the invariant that (D (1) & D (2)) < Zu. T1 := Shift_Left (D (1) & D (2), Scale); D (1) := Hi (T1); @@ -485,6 +486,19 @@ package body System.Arith_64 is -- Adjust quotient digit if it was too high + -- We use the version of the algorithm in the 2nd Edition of + -- "The Art of Computer Programming". This had a bug not + -- discovered till 1995, see Vol 2 errata: + -- http://www-cs-faculty.stanford.edu/~uno/err2-2e.ps.gz. + -- Under rare circumstances the expression in the test could + -- overflow. This version was further corrected in 2005, see + -- Vol 2 errata: + -- http://www-cs-faculty.stanford.edu/~uno/all2-pre.ps.gz. + -- This implementation is not impacted by these bugs, due to the + -- use of a word-size comparison done in function Le3 instead of + -- a comparison on two-word integer quantities in the original + -- algorithm. + loop exit when Le3 (S1, S2, S3, D (J + 1), D (J + 2), D (J + 3)); Qd (J + 1) := Qd (J + 1) - 1; -- cgit v1.1 From 7afbd9419f78de69a9bbbd90ad10e38f4ed77d65 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Tue, 17 Sep 2019 08:02:41 +0000 Subject: [Ada] Update the character type comment in exp_dbug.ads The character type comment in exp_dbug.ads documented the QU and QW encodings, but did not document the plain "Qc" encoding, where 'c' is the character itself. This patch updates the comment to follow the implementation. 2019-09-17 Tom Tromey gcc/ada/ * exp_dbug.ads: Update character type comment. From-SVN: r275793 --- gcc/ada/ChangeLog | 4 ++++ gcc/ada/exp_dbug.ads | 17 ++++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 0d7fc8f..6ceb7ae 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,7 @@ +2019-09-17 Tom Tromey + + * exp_dbug.ads: Update character type comment. + 2019-09-17 Yannick Moy * libgnat/s-arit64.adb (Double_Divide): Simplify needlessly diff --git a/gcc/ada/exp_dbug.ads b/gcc/ada/exp_dbug.ads index 5768734..93b9783 100644 --- a/gcc/ada/exp_dbug.ads +++ b/gcc/ada/exp_dbug.ads @@ -1452,18 +1452,21 @@ package Exp_Dbug is -- a character literal, the name is encoded as described in the following -- paragraph. - -- A name QUhh, where each 'h' is a lower-case hexadecimal digit, stands - -- for a character whose Unicode encoding is hh, and QWhhhh likewise stands - -- for a wide character whose encoding is hhhh. The representation values - -- are encoded as for ordinary enumeration literals (and have no necessary - -- relationship to the values encoded in the names). + -- The characters 'a'..'z' and '0'..'9' are represented as Qc, where 'c' + -- stands for the character itself. A name QUhh, where each 'h' is a + -- lower-case hexadecimal digit, stands for a character whose Unicode + -- encoding is hh, and QWhhhh likewise stands for a wide character whose + -- encoding is hhhh. The representation values are encoded as for ordinary + -- enumeration literals (and have no necessary relationship to the values + -- encoded in the names). -- For example, given the type declaration - -- type x is (A, 'C', B); + -- type x is (A, 'C', 'b'); -- the second enumeration literal would be named QU43 and the value - -- assigned to it would be 1. + -- assigned to it would be 1, and the third enumeration literal would be + -- named Qb and the value assigned to it would be 2. ----------------------------------------------- -- Secondary Dispatch tables of tagged types -- -- cgit v1.1 From 1e0a3cc4ca87b57b2a9b8a02ff20bacdce6146a3 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Tue, 17 Sep 2019 08:02:46 +0000 Subject: [Ada] Fix ineffective -gnatyN for separate compilation units This fixes a recent regression introduced in the machinery giving style warnings: the -gnatyN switch no longer cancels an earlier -gnaty switch for separate compilation units. Running this command: gcc -c slib.adb -gnatyaAbcefhiIklmM25OnprStux -gnatyN On the following sources: package Slib is procedure I_Am_Short; end Slib; with Ada.Text_IO; use Ada.Text_IO; package body Slib is -- have a long line here as well. procedure I_Am_Short is separate; end Slib; separate (Slib) procedure I_Am_Short is begin Put_Line ("......................................................."); end I_Am_Short; Should execute silently. 2019-09-17 Eric Botcazou gcc/ada/ * sem.adb (Do_Analyze): Save Style_Check_Max_Line_Length on entry and restore it on exit instead of recomputing it. From-SVN: r275794 --- gcc/ada/ChangeLog | 5 +++++ gcc/ada/sem.adb | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 6ceb7ae..8f4d57e 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,8 @@ +2019-09-17 Eric Botcazou + + * sem.adb (Do_Analyze): Save Style_Check_Max_Line_Length on + entry and restore it on exit instead of recomputing it. + 2019-09-17 Tom Tromey * exp_dbug.ads: Update character type comment. diff --git a/gcc/ada/sem.adb b/gcc/ada/sem.adb index 2e99531..2967a18 100644 --- a/gcc/ada/sem.adb +++ b/gcc/ada/sem.adb @@ -1360,7 +1360,8 @@ package body Sem is -- unconditionally, and has no restore mechanism, because it is -- intended as a lowest-level Pure package. - Saved_ML : constant Int := Style_Max_Line_Length; + Saved_ML : constant Int := Style_Max_Line_Length; + Saved_CML : constant Boolean := Style_Check_Max_Line_Length; List : Elist_Id; @@ -1395,7 +1396,7 @@ package body Sem is Restore_Scope_Stack (List); Restore_Ghost_Region (Saved_GM, Saved_IGR); Style_Max_Line_Length := Saved_ML; - Style_Check_Max_Line_Length := Style_Max_Line_Length /= 0; + Style_Check_Max_Line_Length := Saved_CML; end Do_Analyze; -- Local variables -- cgit v1.1 From 0d4fcc9f622ee428849091c51108a4823819e9a6 Mon Sep 17 00:00:00 2001 From: Javier Miranda Date: Tue, 17 Sep 2019 08:02:51 +0000 Subject: [Ada] Missing propagation of Has_Predicates in cloned subtypes The frontend silently skips propagating attributes Has_Predicates and Predicate function to the internally built cloned subtype. This change does not affect the functionality of the compiler; it leaves more clean the decoration of internal entities. 2019-09-17 Javier Miranda gcc/ada/ * sem_ch3.adb (Complete_Private_Subtype): Propagate attributes Has_Attributes and Predicate_Function to the cloned subtype. From-SVN: r275795 --- gcc/ada/ChangeLog | 5 +++++ gcc/ada/sem_ch3.adb | 12 ++++++++++++ 2 files changed, 17 insertions(+) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 8f4d57e..36a7dde 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,8 @@ +2019-09-17 Javier Miranda + + * sem_ch3.adb (Complete_Private_Subtype): Propagate attributes + Has_Attributes and Predicate_Function to the cloned subtype. + 2019-09-17 Eric Botcazou * sem.adb (Do_Analyze): Save Style_Check_Max_Line_Length on diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb index 257761a..864b08e 100644 --- a/gcc/ada/sem_ch3.adb +++ b/gcc/ada/sem_ch3.adb @@ -12509,6 +12509,18 @@ package body Sem_Ch3 is -- Show Full is simply a renaming of Full_Base Set_Cloned_Subtype (Full, Full_Base); + + -- Propagate predicates + + if Has_Predicates (Full_Base) then + Set_Has_Predicates (Full); + + if Present (Predicate_Function (Full_Base)) + and then No (Predicate_Function (Full)) + then + Set_Predicate_Function (Full, Predicate_Function (Full_Base)); + end if; + end if; end if; -- It is unsafe to share the bounds of a scalar type, because the Itype -- cgit v1.1 From e34716b8dd8836a565b4cf0c26f7244161f194f1 Mon Sep 17 00:00:00 2001 From: Yannick Moy Date: Tue, 17 Sep 2019 08:02:56 +0000 Subject: [Ada] Fix rounding of fixed-point arithmetic operation Fixed-point multiplication, division and conversion may lead to calling the function Double_Divide in s-arit64 runtime unit. In the special case where arguments have the special values X = -2**63 and the absolute value of the product of its other arguments Y*Z = 2**64, the rounded value should be either -1 or 1, but currently Double_Divide returns a quotient of 0. Rounding only applies when Round attribute is called on the arithmetic operation for a decimal fixed-point result, or the result type is integer. This fixes correctly applies rounding away from 0 in that special case. 2019-09-17 Yannick Moy gcc/ada/ * libgnat/s-arit64.adb (Double_Divide): Correctly handle the special case when rounding. gcc/testsuite/ * gnat.dg/fixedpnt7.adb: New testcase. From-SVN: r275796 --- gcc/ada/ChangeLog | 5 +++++ gcc/ada/libgnat/s-arit64.adb | 43 ++++++++++++++++++++++++++++++------- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gnat.dg/fixedpnt7.adb | 20 +++++++++++++++++ 4 files changed, 64 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/fixedpnt7.adb (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 36a7dde..6c4eaf7 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,8 @@ +2019-09-17 Yannick Moy + + * libgnat/s-arit64.adb (Double_Divide): Correctly handle the + special case when rounding. + 2019-09-17 Javier Miranda * sem_ch3.adb (Complete_Private_Subtype): Propagate attributes diff --git a/gcc/ada/libgnat/s-arit64.adb b/gcc/ada/libgnat/s-arit64.adb index b5a5ac4..ede7562 100644 --- a/gcc/ada/libgnat/s-arit64.adb +++ b/gcc/ada/libgnat/s-arit64.adb @@ -147,13 +147,31 @@ package body System.Arith_64 is Raise_Error; end if; + -- Set final signs (RM 4.5.5(27-30)) + + Den_Pos := (Y < 0) = (Z < 0); + -- Compute Y * Z. Note that if the result overflows 64 bits unsigned, - -- then the rounded result is clearly zero (since the dividend is at - -- most 2**63 - 1, the extra bit of precision is nice here). + -- then the rounded result is zero, except for the very special case + -- where X = -2**63 and abs(Y*Z) = 2**64, when Round is True. if Yhi /= 0 then if Zhi /= 0 then - Q := 0; + + -- Handle the special case when Round is True + + if Yhi = 1 + and then Zhi = 1 + and then Ylo = 0 + and then Zlo = 0 + and then X = Int64'First + and then Round + then + Q := (if Den_Pos then -1 else 1); + else + Q := 0; + end if; + R := X; return; else @@ -168,17 +186,26 @@ package body System.Arith_64 is T2 := T2 + Hi (T1); if Hi (T2) /= 0 then - Q := 0; + + -- Handle the special case when Round is True + + if Hi (T2) = 1 + and then Lo (T2) = 0 + and then Lo (T1) = 0 + and then X = Int64'First + and then Round + then + Q := (if Den_Pos then -1 else 1); + else + Q := 0; + end if; + R := X; return; end if; Du := Lo (T2) & Lo (T1); - -- Set final signs (RM 4.5.5(27-30)) - - Den_Pos := (Y < 0) = (Z < 0); - -- Check overflow case of largest negative number divided by -1 if X = Int64'First and then Du = 1 and then not Den_Pos then diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 28d5f26..56d58cc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2019-09-17 Yannick Moy + * gnat.dg/fixedpnt7.adb: New testcase. + +2019-09-17 Yannick Moy + * gnat.dg/multfixed.adb: New testcase. 2019-09-17 Vadim Godunko diff --git a/gcc/testsuite/gnat.dg/fixedpnt7.adb b/gcc/testsuite/gnat.dg/fixedpnt7.adb new file mode 100644 index 0000000..635b984 --- /dev/null +++ b/gcc/testsuite/gnat.dg/fixedpnt7.adb @@ -0,0 +1,20 @@ +-- { dg-do run } + +procedure Fixedpnt7 is + type F1 is delta 1.0 range -2.0**63 .. 0.0 + with Small => 1.0; + type F2 is delta 4.0 range 0.0 .. 2.0**64 + with Small => 4.0; + type D is delta 1.0 digits 18; + + XX : constant := -2.0**63; + YY : constant := 2.0**64; + + X : F1 := XX; + Y : F2 := YY; + U : D := D'Round(X / Y); +begin + if U /= -1.0 then + raise Program_Error; + end if; +end Fixedpnt7; \ No newline at end of file -- cgit v1.1 From 994e33d27a6d0de5a3fdb646c93aaea72d003c6f Mon Sep 17 00:00:00 2001 From: Claire Dross Date: Tue, 17 Sep 2019 08:03:02 +0000 Subject: [Ada] Add Remove primitive on functional maps A primitive for removing a mapping from a functional map has been added. 2019-09-17 Claire Dross gcc/ada/ * libgnat/a-cofuma.ads, libgnat/a-cofuma.adb (Remove): New function which returns a copy of the input container without a given mapping. From-SVN: r275797 --- gcc/ada/ChangeLog | 6 ++++++ gcc/ada/libgnat/a-cofuma.adb | 12 ++++++++++++ gcc/ada/libgnat/a-cofuma.ads | 14 ++++++++++++++ 3 files changed, 32 insertions(+) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 6c4eaf7..b327857 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,9 @@ +2019-09-17 Claire Dross + + * libgnat/a-cofuma.ads, libgnat/a-cofuma.adb (Remove): New + function which returns a copy of the input container without a + given mapping. + 2019-09-17 Yannick Moy * libgnat/s-arit64.adb (Double_Divide): Correctly handle the diff --git a/gcc/ada/libgnat/a-cofuma.adb b/gcc/ada/libgnat/a-cofuma.adb index 1652efe..d963f6e 100644 --- a/gcc/ada/libgnat/a-cofuma.adb +++ b/gcc/ada/libgnat/a-cofuma.adb @@ -243,6 +243,18 @@ package body Ada.Containers.Functional_Maps with SPARK_Mode => Off is return Length (Container.Elements); end Length; + ------------ + -- Remove -- + ------------ + + function Remove (Container : Map; Key : Key_Type) return Map is + I : constant Extended_Index := Find (Container.Keys, Key); + begin + return + (Keys => Remove (Container.Keys, I), + Elements => Remove (Container.Elements, I)); + end Remove; + --------------- -- Same_Keys -- --------------- diff --git a/gcc/ada/libgnat/a-cofuma.ads b/gcc/ada/libgnat/a-cofuma.ads index bf6e5a8..e458b06 100644 --- a/gcc/ada/libgnat/a-cofuma.ads +++ b/gcc/ada/libgnat/a-cofuma.ads @@ -243,6 +243,20 @@ package Ada.Containers.Functional_Maps with SPARK_Mode is and Container <= Add'Result and Keys_Included_Except (Add'Result, Container, New_Key); + function Remove + (Container : Map; + Key : Key_Type) return Map + -- Returns Container without any mapping for Key + + with + Global => null, + Pre => Has_Key (Container, Key), + Post => + Length (Container) = Length (Remove'Result) + 1 + and not Has_Key (Remove'Result, Key) + and Remove'Result <= Container + and Keys_Included_Except (Container, Remove'Result, Key); + function Set (Container : Map; Key : Key_Type; -- cgit v1.1 From 8054d17a735e4e1a35e9a24556eea100249345ed Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 17 Sep 2019 08:08:40 +0000 Subject: re PR tree-optimization/91790 (ICE: verify_ssa failed (error: definition in block 2 follows the use)) 2019-09-17 Richard Biener PR tree-optimization/91790 * tree-vect-stmts.c (vectorizable_load): For BB vectorization use the correct DR for setting up realignment. From-SVN: r275798 --- gcc/ChangeLog | 6 ++++++ gcc/tree-vect-stmts.c | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2f4de49..3a9e637 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-09-17 Richard Biener + + PR tree-optimization/91790 + * tree-vect-stmts.c (vectorizable_load): For BB vectorization + use the correct DR for setting up realignment. + 2019-09-16 Uroš Bizjak PR target/91719 diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index edc7e0d..7f5f1c3 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -9169,7 +9169,9 @@ vectorizable_load (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, || alignment_support_scheme == dr_explicit_realign) && !compute_in_loop) { - msq = vect_setup_realignment (first_stmt_info, gsi, &realignment_token, + msq = vect_setup_realignment (first_stmt_info_for_drptr + ? first_stmt_info_for_drptr + : first_stmt_info, gsi, &realignment_token, alignment_support_scheme, NULL_TREE, &at_loop); if (alignment_support_scheme == dr_explicit_realign_optimized) -- cgit v1.1 From ecd4d80cb2ee6a72d46c59eff47860d2a0fa2daa Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Tue, 17 Sep 2019 08:13:11 +0000 Subject: [PR91749][arm] FDPIC: Handle -mflip-thumb 2019-09-16 Christophe Lyon PR target/91749 * config/arm/arm.c (arm_valid_target_attribute_rec): Make sure the mode attributed is supported by FDPIC. From-SVN: r275799 --- gcc/ChangeLog | 6 ++++++ gcc/config/arm/arm.c | 6 +++++- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3a9e637..144ed9b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-09-17 Christophe Lyon + + PR target/91749 + * config/arm/arm.c (arm_valid_target_attribute_rec): Make sure the + mode attributed is supported by FDPIC. + 2019-09-17 Richard Biener PR tree-optimization/91790 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index db7de5e..b59778c 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -31179,7 +31179,11 @@ arm_valid_target_attribute_rec (tree args, struct gcc_options *opts) { argstr = NULL; if (!strcmp (q, "thumb")) - opts->x_target_flags |= MASK_THUMB; + { + opts->x_target_flags |= MASK_THUMB; + if (TARGET_FDPIC && !arm_arch_thumb2) + sorry ("FDPIC mode is not supported in Thumb-1 mode"); + } else if (!strcmp (q, "arm")) opts->x_target_flags &= ~MASK_THUMB; -- cgit v1.1 From c4ccdc0e63150d1cab2686a16dafeb7520315cb2 Mon Sep 17 00:00:00 2001 From: Paul Thomas Date: Tue, 17 Sep 2019 08:30:50 +0000 Subject: re PR fortran/91588 (ICE in check_inquiry, at fortran/expr.c:2673) 2019-09-17 Paul Thomas PR fortran/91588 * expr.c (check_inquiry): Remove extended component refs by using symbol pointers. If a function argument is an associate variable with a constant target, copy the target expression in place of the argument expression. Check that the charlen is not NULL before using the string length. (gfc_check_assign): Remove extraneous space. 2019-09-17 Paul Thomas PR fortran/91588 * gfortran.dg/associate_49.f90 : New test. From-SVN: r275800 --- gcc/fortran/ChangeLog | 10 ++++ gcc/fortran/expr.c | 79 +++++++++++++++++------------- gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gfortran.dg/associate_49.f90 | 34 +++++++++++++ 4 files changed, 94 insertions(+), 34 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/associate_49.f90 (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 7b383b3..853bd32 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,13 @@ +2019-09-17 Paul Thomas + + PR fortran/91588 + * expr.c (check_inquiry): Remove extended component refs by + using symbol pointers. If a function argument is an associate + variable with a constant target, copy the target expression in + place of the argument expression. Check that the charlen is not + NULL before using the string length. + (gfc_check_assign): Remove extraneous space. + 2019-09-15 Steven G. Kargl PR fortran/91727 diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c index c6d17d6..5d3480e 100644 --- a/gcc/fortran/expr.c +++ b/gcc/fortran/expr.c @@ -2610,6 +2610,8 @@ check_inquiry (gfc_expr *e, int not_restricted) int i = 0; gfc_actual_arglist *ap; + gfc_symbol *sym; + gfc_symbol *asym; if (!e->value.function.isym || !e->value.function.isym->inquiry) @@ -2619,20 +2621,22 @@ check_inquiry (gfc_expr *e, int not_restricted) if (e->symtree == NULL) return MATCH_NO; - if (e->symtree->n.sym->from_intmod) + sym = e->symtree->n.sym; + + if (sym->from_intmod) { - if (e->symtree->n.sym->from_intmod == INTMOD_ISO_FORTRAN_ENV - && e->symtree->n.sym->intmod_sym_id != ISOFORTRAN_COMPILER_OPTIONS - && e->symtree->n.sym->intmod_sym_id != ISOFORTRAN_COMPILER_VERSION) + if (sym->from_intmod == INTMOD_ISO_FORTRAN_ENV + && sym->intmod_sym_id != ISOFORTRAN_COMPILER_OPTIONS + && sym->intmod_sym_id != ISOFORTRAN_COMPILER_VERSION) return MATCH_NO; - if (e->symtree->n.sym->from_intmod == INTMOD_ISO_C_BINDING - && e->symtree->n.sym->intmod_sym_id != ISOCBINDING_C_SIZEOF) + if (sym->from_intmod == INTMOD_ISO_C_BINDING + && sym->intmod_sym_id != ISOCBINDING_C_SIZEOF) return MATCH_NO; } else { - name = e->symtree->n.sym->name; + name = sym->name; functions = inquiry_func_gnu; if (gfc_option.warn_std & GFC_STD_F2003) @@ -2657,41 +2661,48 @@ check_inquiry (gfc_expr *e, int not_restricted) if (!ap->expr) continue; + asym = ap->expr->symtree ? ap->expr->symtree->n.sym : NULL; + if (ap->expr->ts.type == BT_UNKNOWN) { - if (ap->expr->symtree->n.sym->ts.type == BT_UNKNOWN - && !gfc_set_default_type (ap->expr->symtree->n.sym, 0, gfc_current_ns)) + if (asym && asym->ts.type == BT_UNKNOWN + && !gfc_set_default_type (asym, 0, gfc_current_ns)) return MATCH_NO; - ap->expr->ts = ap->expr->symtree->n.sym->ts; + ap->expr->ts = asym->ts; } - /* Assumed character length will not reduce to a constant expression - with LEN, as required by the standard. */ - if (i == 5 && not_restricted && ap->expr->symtree - && ap->expr->symtree->n.sym->ts.type == BT_CHARACTER - && (ap->expr->symtree->n.sym->ts.u.cl->length == NULL - || ap->expr->symtree->n.sym->ts.deferred)) - { - gfc_error ("Assumed or deferred character length variable %qs " - "in constant expression at %L", - ap->expr->symtree->n.sym->name, - &ap->expr->where); - return MATCH_ERROR; - } - else if (not_restricted && !gfc_check_init_expr (ap->expr)) - return MATCH_ERROR; + if (asym && asym->assoc && asym->assoc->target + && asym->assoc->target->expr_type == EXPR_CONSTANT) + { + gfc_free_expr (ap->expr); + ap->expr = gfc_copy_expr (asym->assoc->target); + } - if (not_restricted == 0 - && ap->expr->expr_type != EXPR_VARIABLE - && !check_restricted (ap->expr)) + /* Assumed character length will not reduce to a constant expression + with LEN, as required by the standard. */ + if (i == 5 && not_restricted && asym + && asym->ts.type == BT_CHARACTER + && ((asym->ts.u.cl && asym->ts.u.cl->length == NULL) + || asym->ts.deferred)) + { + gfc_error ("Assumed or deferred character length variable %qs " + "in constant expression at %L", + asym->name, &ap->expr->where); return MATCH_ERROR; + } + else if (not_restricted && !gfc_check_init_expr (ap->expr)) + return MATCH_ERROR; - if (not_restricted == 0 - && ap->expr->expr_type == EXPR_VARIABLE - && ap->expr->symtree->n.sym->attr.dummy - && ap->expr->symtree->n.sym->attr.optional) - return MATCH_NO; + if (not_restricted == 0 + && ap->expr->expr_type != EXPR_VARIABLE + && !check_restricted (ap->expr)) + return MATCH_ERROR; + + if (not_restricted == 0 + && ap->expr->expr_type == EXPR_VARIABLE + && asym->attr.dummy && asym->attr.optional) + return MATCH_NO; } return MATCH_YES; @@ -3683,7 +3694,7 @@ gfc_check_assign (gfc_expr *lvalue, gfc_expr *rvalue, int conform, gfc_error ("BOZ literal constant near %L cannot be assigned to a " "%qs variable", &rvalue->where, gfc_typename (&lvalue->ts)); - + return false; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 56d58cc..de8b5a6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-17 Paul Thomas + + PR fortran/91588 + * gfortran.dg/associate_49.f90 : New test. + 2019-09-17 Yannick Moy * gnat.dg/fixedpnt7.adb: New testcase. diff --git a/gcc/testsuite/gfortran.dg/associate_49.f90 b/gcc/testsuite/gfortran.dg/associate_49.f90 new file mode 100644 index 0000000..1b20595 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/associate_49.f90 @@ -0,0 +1,34 @@ +! { dg-do run } +! +! Test the fix for PR91588, in which the declaration of 'a' caused +! an ICE. +! +! Contributed by Gerhardt Steinmetz +! +program p + character(4), parameter :: parm = '7890' + associate (z => '1234') + block + integer(len(z)) :: a + if (kind(a) .ne. 4) stop 1 + end block + end associate + associate (z => '123') + block + integer(len(z)+1) :: a + if (kind(a) .ne. 4) stop 2 + end block + end associate + associate (z => 1_8) + block + integer(kind(z)) :: a + if (kind(a) .ne. 8) stop 3 + end block + end associate + associate (z => parm) + block + integer(len(z)) :: a + if (kind(a) .ne. 4) stop 4 + end block + end associate +end -- cgit v1.1 From 351e7c3b5fbd45bde3efb601f7fee9a31c4f2063 Mon Sep 17 00:00:00 2001 From: Feng Xue Date: Tue, 17 Sep 2019 12:30:08 +0000 Subject: PR ipa/91089 - Setup predicate for switch default case in IPA 2019-09-17 Feng Xue PR ipa/91089 * doc/invoke.texi (ipa-max-switch-predicate-bounds): Document new option. * params.def (PARAM_IPA_MAX_SWITCH_PREDICATE_BOUNDS): New. * ipa-fnsummary.c (set_switch_stmt_execution_predicate): Add predicate for switch default case using range analysis information. 2019-09-17 Feng Xue PR ipa/91089 * gcc.dg/ipa/pr91089.c: New test. From-SVN: r275802 --- gcc/ChangeLog | 9 +++ gcc/doc/invoke.texi | 6 ++ gcc/ipa-fnsummary.c | 123 ++++++++++++++++++++++++++++++++++--- gcc/params.def | 6 ++ gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.dg/ipa/pr91089.c | 62 +++++++++++++++++++ 6 files changed, 204 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/ipa/pr91089.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 144ed9b..0cbb512 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2019-09-17 Feng Xue + + PR ipa/91089 + * doc/invoke.texi (ipa-max-switch-predicate-bounds): Document new + option. + * params.def (PARAM_IPA_MAX_SWITCH_PREDICATE_BOUNDS): New. + * ipa-fnsummary.c (set_switch_stmt_execution_predicate): Add predicate + for switch default case using range analysis information. + 2019-09-17 Christophe Lyon PR target/91749 diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index fe5cf35..0e36935 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -11937,6 +11937,12 @@ not spend too much time analyzing huge functions, it gives up and consider all memory clobbered after examining @option{ipa-max-aa-steps} statements modifying memory. +@item ipa-max-switch-predicate-bounds +Maximal number of boundary endpoints of case ranges of switch statement. +For switch exceeding this limit, IPA-CP will not construct cloning cost +predicate, which is used to estimate cloning benefit, for default case +of the switch statement. + @item lto-partitions Specify desired number of partitions produced during WHOPR compilation. The number of partitions should exceed the number of CPUs used for compilation. diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c index 278bf60..1bf1806 100644 --- a/gcc/ipa-fnsummary.c +++ b/gcc/ipa-fnsummary.c @@ -1269,13 +1269,21 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi, if (!unmodified_parm_or_parm_agg_item (fbi, last, op, &index, &size, &aggpos)) return; + auto_vec > ranges; + tree type = TREE_TYPE (op); + int bound_limit = PARAM_VALUE (PARAM_IPA_MAX_SWITCH_PREDICATE_BOUNDS); + int bound_count = 0; + wide_int vr_wmin, vr_wmax; + value_range_kind vr_type = get_range_info (op, &vr_wmin, &vr_wmax); + FOR_EACH_EDGE (e, ei, bb->succs) { e->aux = edge_predicate_pool.allocate (); *(predicate *) e->aux = false; } + n = gimple_switch_num_labels (last); - for (case_idx = 0; case_idx < n; ++case_idx) + for (case_idx = 1; case_idx < n; ++case_idx) { tree cl = gimple_switch_label (last, case_idx); tree min, max; @@ -1285,12 +1293,7 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi, min = CASE_LOW (cl); max = CASE_HIGH (cl); - /* For default we might want to construct predicate that none - of cases is met, but it is bit hard to do not having negations - of conditionals handy. */ - if (!min && !max) - p = true; - else if (!max) + if (!max) p = add_condition (summary, index, size, &aggpos, EQ_EXPR, unshare_expr_without_location (min)); else @@ -1304,7 +1307,113 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi, } *(class predicate *) e->aux = p.or_with (summary->conds, *(class predicate *) e->aux); + + /* If there are too many disjoint case ranges, predicate for default + case might become too complicated. So add a limit here. */ + if (bound_count > bound_limit) + continue; + + bool new_range = true; + + if (!ranges.is_empty ()) + { + wide_int curr_wmin = wi::to_wide (min); + wide_int last_wmax = wi::to_wide (ranges.last ().second); + + /* Merge case ranges if they are continuous. */ + if (curr_wmin == last_wmax + 1) + new_range = false; + else if (vr_type == VR_ANTI_RANGE) + { + /* If two disjoint case ranges can be connected by anti-range + of switch index, combine them to one range. */ + if (wi::lt_p (vr_wmax, curr_wmin - 1, TYPE_SIGN (type))) + vr_type = VR_UNDEFINED; + else if (wi::le_p (vr_wmin, last_wmax + 1, TYPE_SIGN (type))) + new_range = false; + } + } + + if (!max) + max = min; + + /* Create/extend a case range. And we count endpoints of range set, + this number nearly equals to number of conditions that we will create + for predicate of default case. */ + if (new_range) + { + bound_count += (min == max) ? 1 : 2; + ranges.safe_push (std::make_pair (min, max)); + } + else + { + bound_count += (ranges.last ().first == ranges.last ().second); + ranges.last ().second = max; + } + } + + e = gimple_switch_edge (cfun, last, 0); + if (bound_count > bound_limit) + { + *(class predicate *) e->aux = true; + return; } + + predicate p_seg = true; + predicate p_all = false; + + if (vr_type != VR_RANGE) + { + vr_wmin = wi::to_wide (TYPE_MIN_VALUE (type)); + vr_wmax = wi::to_wide (TYPE_MAX_VALUE (type)); + } + + /* Construct predicate to represent default range set that is negation of + all case ranges. Case range is classified as containing single/non-single + values. Suppose a piece of case ranges in the following. + + [D1...D2] [S1] ... [Sn] [D3...D4] + + To represent default case's range sets between two non-single value + case ranges (From D2 to D3), we construct predicate as: + + D2 < x < D3 && x != S1 && ... && x != Sn + */ + for (size_t i = 0; i < ranges.length (); i++) + { + tree min = ranges[i].first; + tree max = ranges[i].second; + + if (min == max) + p_seg &= add_condition (summary, index, size, &aggpos, NE_EXPR, + unshare_expr_without_location (min)); + else + { + /* Do not create sub-predicate for range that is beyond low bound + of switch index. */ + if (wi::lt_p (vr_wmin, wi::to_wide (min), TYPE_SIGN (type))) + { + p_seg &= add_condition (summary, index, size, &aggpos, LT_EXPR, + unshare_expr_without_location (min)); + p_all = p_all.or_with (summary->conds, p_seg); + } + + /* Do not create sub-predicate for range that is beyond up bound + of switch index. */ + if (wi::le_p (vr_wmax, wi::to_wide (max), TYPE_SIGN (type))) + { + p_seg = false; + break; + } + + p_seg = add_condition (summary, index, size, &aggpos, GT_EXPR, + unshare_expr_without_location (max)); + } + } + + p_all = p_all.or_with (summary->conds, p_seg); + *(class predicate *) e->aux + = p_all.or_with (summary->conds, *(class predicate *) e->aux); } diff --git a/gcc/params.def b/gcc/params.def index 13001a7..5fe3397 100644 --- a/gcc/params.def +++ b/gcc/params.def @@ -1123,6 +1123,12 @@ DEFPARAM (PARAM_IPA_MAX_AA_STEPS, "parameter analysis based on alias analysis in any given function.", 25000, 0, 0) +DEFPARAM (PARAM_IPA_MAX_SWITCH_PREDICATE_BOUNDS, + "ipa-max-switch-predicate-bounds", + "Maximal number of boundary endpoints of case ranges of switch " + "statement used during IPA functoin summary generation.", + 5, 0, 0) + /* WHOPR partitioning configuration. */ DEFPARAM (PARAM_LTO_PARTITIONS, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index de8b5a6..1afad78 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-17 Feng Xue + + PR ipa/91089 + * gcc.dg/ipa/pr91089.c: New test. + 2019-09-17 Paul Thomas PR fortran/91588 diff --git a/gcc/testsuite/gcc.dg/ipa/pr91089.c b/gcc/testsuite/gcc.dg/ipa/pr91089.c new file mode 100644 index 0000000..e9e206f --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr91089.c @@ -0,0 +1,62 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fdump-ipa-cp-details -fdump-ipa-fnsummary-details --param ipa-max-switch-predicate-bounds=10 -fno-inline" } */ + +int fn (); + +int data; + +int callee (int i) +{ + switch (i) + { + case -126: return i + 13; + case -127: return i + 5; + case -8: return i * i; + case 0: return i % 9; + case 5: + case 7: + case 6: return 3; + default: + fn (); + fn (); + fn (); + fn (); + fn (); + fn (); + fn (); + fn (); + fn (); + fn (); + fn (); + fn (); + fn (); + fn (); + fn (); + fn (); + fn (); + fn (); + fn (); + } + + return data += i; +} + +int caller () +{ + return callee (-127) + + callee (-126) + + callee (-8) + + callee (0) + + callee (5) + + callee (6) + + callee (7) + + callee (100); +} + +/* { dg-final { scan-ipa-dump-times "Creating a specialized node of callee" 7 "cp" } } */ +/* { dg-final { scan-ipa-dump "op0 < -127" "fnsummary" } } */ +/* { dg-final { scan-ipa-dump "op0 > -126" "fnsummary" } } */ +/* { dg-final { scan-ipa-dump "op0 != -8" "fnsummary" } } */ +/* { dg-final { scan-ipa-dump "op0 != 0" "fnsummary" } } */ +/* { dg-final { scan-ipa-dump "op0 < 5" "fnsummary" } } */ +/* { dg-final { scan-ipa-dump "op0 > 7" "fnsummary" } } */ -- cgit v1.1 From 6fbb9dd1030a749e6055e8c7c1b3406055d3add8 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Tue, 17 Sep 2019 14:35:21 +0200 Subject: [ARM/FDPIC v6 20/24] [ARM][testsuite] FDPIC: Skip tests using architectures unsupported by FDPIC Since FDPIC currently supports arm and thumb-2 modes only, these tests fail because they enforce an architecture version that doesn't match these restrictions. This patch introduces new values for the arm_arch effective-target (v4t_thumb, v5t_thumb, v5te_thumb, v6_thumb, v6k_thumb, v6z_thumb) as needed, and adds them to the relevant tests. In addition, it adds v4t_arm, v5t_arm, v5te_arm, v6_arm, v6k_arm and v6z_arm to avoid skipping some tests when GCC is configured to generate Thumb code by default. It also adds the corresponding non-thumb effective-target to the tests that were missing it. The existing v4t, v5t, v5te, v6 v6k and v6z effective-targets now force -mfloat-abi=softfp since these thumb-1 targets do not support hard-float anyway. Finally, the patch removes the special case to detect the presence of -marm in the flags, since it makes atomic_loaddi tests unsupported: since the flags in question also include -march, the combination is supported, while -marm alone is not if GCC is configured to target an M-profile CPU. 2019-19-17 Christophe Lyon * lib/target-supports.exp (check_effective_target_arm_arch_FUNC_ok): Add v4t_arm, v4t_thumb, v5t_arm, v5t_thumb, v5te_arm, v5te_thumb, v6_arm, v6_thumb, v6k_arm, v6k_thumb, v6z_arm, v6z_thumb. Add -mfloat-abi=softfp to v4t, v5t, v5te, v6, v6k, v6z. Remove early exit for -marm. * gcc.target/arm/armv6-unaligned-load-ice.c: Add arm_arch effective-target. * gcc.target/arm/attr-unaligned-load-ice.c: Likewise. * gcc.target/arm/ftest-armv4-arm.c: Likewise. * gcc.target/arm/ftest-armv4t-arm.c: Likewise. * gcc.target/arm/ftest-armv4t-thumb.c: Likewise. * gcc.target/arm/ftest-armv5t-arm.c: Likewise. * gcc.target/arm/ftest-armv5t-thumb.c: Likewise. * gcc.target/arm/ftest-armv5te-arm.c: Likewise. * gcc.target/arm/ftest-armv5te-thumb.c: Likewise. * gcc.target/arm/ftest-armv6-arm.c: Likewise. * gcc.target/arm/ftest-armv6-thumb.c: Likewise. * gcc.target/arm/ftest-armv6k-arm.c: Likewise. * gcc.target/arm/ftest-armv6k-thumb.c: Likewise. * gcc.target/arm/ftest-armv6m-thumb.c: Likewise. * gcc.target/arm/ftest-armv6t2-arm.c: Likewise. * gcc.target/arm/ftest-armv6t2-thumb.c: Likewise. * gcc.target/arm/ftest-armv6z-arm.c: Likewise. * gcc.target/arm/ftest-armv6z-thumb.c: Likewise. * gcc.target/arm/g2.c: Likewise. * gcc.target/arm/macro_defs1.c: Likewise. * gcc.target/arm/pr59858.c: Likewise. * gcc.target/arm/pr65647-2.c: Likewise. * gcc.target/arm/pr79058.c: Likewise. * gcc.target/arm/pr83712.c: Likewise. * gcc.target/arm/pragma_arch_switch_2.c: Likewise. * gcc.target/arm/scd42-1.c: Likewise. * gcc.target/arm/scd42-2.c: Likewise. * gcc.target/arm/scd42-3.c: Likewise. * gcc.c-torture/compile/pr82096.c: Fix arm_arch effective-target. * gcc.target/arm/attr_arm-err.c: Likewise. * gcc.target/arm/di-longlong64-sync-withldrexd.c: Likewise. From-SVN: r275803 --- gcc/testsuite/ChangeLog | 41 ++++++++++++++++++++++ gcc/testsuite/gcc.c-torture/compile/pr82096.c | 2 +- .../gcc.target/arm/armv6-unaligned-load-ice.c | 1 + .../gcc.target/arm/attr-unaligned-load-ice.c | 1 + gcc/testsuite/gcc.target/arm/attr_arm-err.c | 2 +- .../gcc.target/arm/di-longlong64-sync-withldrexd.c | 3 +- gcc/testsuite/gcc.target/arm/ftest-armv4-arm.c | 1 + gcc/testsuite/gcc.target/arm/ftest-armv4t-arm.c | 1 + gcc/testsuite/gcc.target/arm/ftest-armv4t-thumb.c | 1 + gcc/testsuite/gcc.target/arm/ftest-armv5t-arm.c | 1 + gcc/testsuite/gcc.target/arm/ftest-armv5t-thumb.c | 1 + gcc/testsuite/gcc.target/arm/ftest-armv5te-arm.c | 1 + gcc/testsuite/gcc.target/arm/ftest-armv5te-thumb.c | 1 + gcc/testsuite/gcc.target/arm/ftest-armv6-arm.c | 1 + gcc/testsuite/gcc.target/arm/ftest-armv6-thumb.c | 1 + gcc/testsuite/gcc.target/arm/ftest-armv6k-arm.c | 1 + gcc/testsuite/gcc.target/arm/ftest-armv6k-thumb.c | 1 + gcc/testsuite/gcc.target/arm/ftest-armv6m-thumb.c | 1 + gcc/testsuite/gcc.target/arm/ftest-armv6t2-arm.c | 1 + gcc/testsuite/gcc.target/arm/ftest-armv6t2-thumb.c | 1 + gcc/testsuite/gcc.target/arm/ftest-armv6z-arm.c | 1 + gcc/testsuite/gcc.target/arm/ftest-armv6z-thumb.c | 1 + gcc/testsuite/gcc.target/arm/g2.c | 1 + gcc/testsuite/gcc.target/arm/macro_defs1.c | 1 + gcc/testsuite/gcc.target/arm/pr59858.c | 1 + gcc/testsuite/gcc.target/arm/pr65647-2.c | 1 + gcc/testsuite/gcc.target/arm/pr79058.c | 1 + gcc/testsuite/gcc.target/arm/pr83712.c | 1 + .../gcc.target/arm/pragma_arch_switch_2.c | 1 + gcc/testsuite/gcc.target/arm/scd42-1.c | 1 + gcc/testsuite/gcc.target/arm/scd42-2.c | 1 + gcc/testsuite/gcc.target/arm/scd42-3.c | 1 + gcc/testsuite/lib/target-supports.exp | 28 +++++++++------ 33 files changed, 90 insertions(+), 14 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1afad78..918cd4b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,44 @@ +2019-19-17 Christophe Lyon + + * lib/target-supports.exp + (check_effective_target_arm_arch_FUNC_ok): Add v4t_arm, v4t_thumb, + v5t_arm, v5t_thumb, v5te_arm, v5te_thumb, v6_arm, v6_thumb, + v6k_arm, v6k_thumb, v6z_arm, v6z_thumb. + Add -mfloat-abi=softfp to v4t, v5t, v5te, v6, v6k, v6z. + Remove early exit for -marm. + * gcc.target/arm/armv6-unaligned-load-ice.c: Add arm_arch + effective-target. + * gcc.target/arm/attr-unaligned-load-ice.c: Likewise. + * gcc.target/arm/ftest-armv4-arm.c: Likewise. + * gcc.target/arm/ftest-armv4t-arm.c: Likewise. + * gcc.target/arm/ftest-armv4t-thumb.c: Likewise. + * gcc.target/arm/ftest-armv5t-arm.c: Likewise. + * gcc.target/arm/ftest-armv5t-thumb.c: Likewise. + * gcc.target/arm/ftest-armv5te-arm.c: Likewise. + * gcc.target/arm/ftest-armv5te-thumb.c: Likewise. + * gcc.target/arm/ftest-armv6-arm.c: Likewise. + * gcc.target/arm/ftest-armv6-thumb.c: Likewise. + * gcc.target/arm/ftest-armv6k-arm.c: Likewise. + * gcc.target/arm/ftest-armv6k-thumb.c: Likewise. + * gcc.target/arm/ftest-armv6m-thumb.c: Likewise. + * gcc.target/arm/ftest-armv6t2-arm.c: Likewise. + * gcc.target/arm/ftest-armv6t2-thumb.c: Likewise. + * gcc.target/arm/ftest-armv6z-arm.c: Likewise. + * gcc.target/arm/ftest-armv6z-thumb.c: Likewise. + * gcc.target/arm/g2.c: Likewise. + * gcc.target/arm/macro_defs1.c: Likewise. + * gcc.target/arm/pr59858.c: Likewise. + * gcc.target/arm/pr65647-2.c: Likewise. + * gcc.target/arm/pr79058.c: Likewise. + * gcc.target/arm/pr83712.c: Likewise. + * gcc.target/arm/pragma_arch_switch_2.c: Likewise. + * gcc.target/arm/scd42-1.c: Likewise. + * gcc.target/arm/scd42-2.c: Likewise. + * gcc.target/arm/scd42-3.c: Likewise. + * gcc.c-torture/compile/pr82096.c: Fix arm_arch effective-target. + * gcc.target/arm/attr_arm-err.c: Likewise. + * gcc.target/arm/di-longlong64-sync-withldrexd.c: Likewise. + 2019-09-17 Feng Xue PR ipa/91089 diff --git a/gcc/testsuite/gcc.c-torture/compile/pr82096.c b/gcc/testsuite/gcc.c-torture/compile/pr82096.c index d144b70..4e695cd 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr82096.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr82096.c @@ -1,4 +1,4 @@ -/* { dg-require-effective-target arm_arch_v5t_ok { target arm*-*-* } } */ +/* { dg-require-effective-target arm_arch_v5t_thumb_ok { target arm*-*-* } } */ /* { dg-skip-if "Do not combine float-abi values" { arm*-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=soft" } } */ /* { dg-additional-options "-march=armv5t -mthumb -mfloat-abi=soft" { target arm*-*-* } } */ diff --git a/gcc/testsuite/gcc.target/arm/armv6-unaligned-load-ice.c b/gcc/testsuite/gcc.target/arm/armv6-unaligned-load-ice.c index 88528f1..886a012 100644 --- a/gcc/testsuite/gcc.target/arm/armv6-unaligned-load-ice.c +++ b/gcc/testsuite/gcc.target/arm/armv6-unaligned-load-ice.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-march=*" } { "-march=armv6k" } } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-marm" } { "" } } */ +/* { dg-require-effective-target arm_arch_v6k_thumb_ok } */ /* { dg-options "-mthumb -Os -mfloat-abi=softfp" } */ /* { dg-add-options arm_arch_v6k } */ diff --git a/gcc/testsuite/gcc.target/arm/attr-unaligned-load-ice.c b/gcc/testsuite/gcc.target/arm/attr-unaligned-load-ice.c index e1ed1c1..2eeb522 100644 --- a/gcc/testsuite/gcc.target/arm/attr-unaligned-load-ice.c +++ b/gcc/testsuite/gcc.target/arm/attr-unaligned-load-ice.c @@ -2,6 +2,7 @@ Verify that unaligned_access is correctly with attribute target. */ /* { dg-do compile } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-march=*" } { "-march=armv6" } } */ +/* { dg-require-effective-target arm_arch_v6_ok } */ /* { dg-options "-Os -mfloat-abi=softfp -mtp=soft" } */ /* { dg-add-options arm_arch_v6 } */ diff --git a/gcc/testsuite/gcc.target/arm/attr_arm-err.c b/gcc/testsuite/gcc.target/arm/attr_arm-err.c index 630c06a..67d572a 100644 --- a/gcc/testsuite/gcc.target/arm/attr_arm-err.c +++ b/gcc/testsuite/gcc.target/arm/attr_arm-err.c @@ -1,7 +1,7 @@ /* Check that attribute target arm is rejected for M profile. */ /* { dg-do compile } */ -/* { dg-require-effective-target arm_arm_ok } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-march=*" } { "-march=armv6-m" } } */ +/* { dg-require-effective-target arm_arch_v6m_ok } */ /* { dg-add-options arm_arch_v6m } */ int __attribute__((target("arm"))) diff --git a/gcc/testsuite/gcc.target/arm/di-longlong64-sync-withldrexd.c b/gcc/testsuite/gcc.target/arm/di-longlong64-sync-withldrexd.c index 517c4a8..befb7ec 100644 --- a/gcc/testsuite/gcc.target/arm/di-longlong64-sync-withldrexd.c +++ b/gcc/testsuite/gcc.target/arm/di-longlong64-sync-withldrexd.c @@ -1,7 +1,6 @@ /* { dg-do compile } */ -/* { dg-require-effective-target arm_arm_ok } */ /* { dg-options "-marm -std=gnu99" } */ -/* { dg-require-effective-target arm_arch_v6k_ok } */ +/* { dg-require-effective-target arm_arch_v6k_arm_ok } */ /* { dg-add-options arm_arch_v6k } */ /* { dg-message "note: '__sync_fetch_and_nand' changed semantics in GCC 4.4" "fetch_and_nand" { target *-*-* } 0 } */ /* { dg-message "note: '__sync_nand_and_fetch' changed semantics in GCC 4.4" "nand_and_fetch" { target *-*-* } 0 } */ diff --git a/gcc/testsuite/gcc.target/arm/ftest-armv4-arm.c b/gcc/testsuite/gcc.target/arm/ftest-armv4-arm.c index 4b48ef8..447a8ec 100644 --- a/gcc/testsuite/gcc.target/arm/ftest-armv4-arm.c +++ b/gcc/testsuite/gcc.target/arm/ftest-armv4-arm.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-march=*" } { "-march=armv4" } } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-mthumb" } { "" } } */ +/* { dg-require-effective-target arm_arch_v4_ok } */ /* { dg-options "-marm" } */ /* { dg-add-options arm_arch_v4 } */ diff --git a/gcc/testsuite/gcc.target/arm/ftest-armv4t-arm.c b/gcc/testsuite/gcc.target/arm/ftest-armv4t-arm.c index 016506f..28fd2f7 100644 --- a/gcc/testsuite/gcc.target/arm/ftest-armv4t-arm.c +++ b/gcc/testsuite/gcc.target/arm/ftest-armv4t-arm.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-march=*" } { "-march=armv4t" } } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-mthumb" } { "" } } */ +/* { dg-require-effective-target arm_arch_v4t_arm_ok } */ /* { dg-options "-marm" } */ /* { dg-add-options arm_arch_v4t } */ diff --git a/gcc/testsuite/gcc.target/arm/ftest-armv4t-thumb.c b/gcc/testsuite/gcc.target/arm/ftest-armv4t-thumb.c index 9ef944e..78878f7 100644 --- a/gcc/testsuite/gcc.target/arm/ftest-armv4t-thumb.c +++ b/gcc/testsuite/gcc.target/arm/ftest-armv4t-thumb.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-march=*" } { "-march=armv4t" } } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-marm" } { "" } } */ +/* { dg-require-effective-target arm_arch_v4t_thumb_ok } */ /* { dg-options "-mthumb" } */ /* { dg-add-options arm_arch_v4t } */ diff --git a/gcc/testsuite/gcc.target/arm/ftest-armv5t-arm.c b/gcc/testsuite/gcc.target/arm/ftest-armv5t-arm.c index a9403e9..8191299 100644 --- a/gcc/testsuite/gcc.target/arm/ftest-armv5t-arm.c +++ b/gcc/testsuite/gcc.target/arm/ftest-armv5t-arm.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-march=*" } { "-march=armv5t" } } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-mthumb" } { "" } } */ +/* { dg-require-effective-target arm_arch_v5t_arm_ok } */ /* { dg-options "-marm" } */ /* { dg-add-options arm_arch_v5t } */ diff --git a/gcc/testsuite/gcc.target/arm/ftest-armv5t-thumb.c b/gcc/testsuite/gcc.target/arm/ftest-armv5t-thumb.c index f3ad07e..b25d17d 100644 --- a/gcc/testsuite/gcc.target/arm/ftest-armv5t-thumb.c +++ b/gcc/testsuite/gcc.target/arm/ftest-armv5t-thumb.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-march=*" } { "-march=armv5t" } } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-marm" } { "" } } */ +/* { dg-require-effective-target arm_arch_v5t_thumb_ok } */ /* { dg-options "-mthumb" } */ /* { dg-add-options arm_arch_v5t } */ diff --git a/gcc/testsuite/gcc.target/arm/ftest-armv5te-arm.c b/gcc/testsuite/gcc.target/arm/ftest-armv5te-arm.c index f98c01a..e0c0d5c 100644 --- a/gcc/testsuite/gcc.target/arm/ftest-armv5te-arm.c +++ b/gcc/testsuite/gcc.target/arm/ftest-armv5te-arm.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-march=*" } { "-march=armv5te" } } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-mthumb" } { "" } } */ +/* { dg-require-effective-target arm_arch_v5te_arm_ok } */ /* { dg-options "-marm" } */ /* { dg-add-options arm_arch_v5te } */ diff --git a/gcc/testsuite/gcc.target/arm/ftest-armv5te-thumb.c b/gcc/testsuite/gcc.target/arm/ftest-armv5te-thumb.c index 5d71787..27a64a2 100644 --- a/gcc/testsuite/gcc.target/arm/ftest-armv5te-thumb.c +++ b/gcc/testsuite/gcc.target/arm/ftest-armv5te-thumb.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-march=*" } { "-march=armv5te" } } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-marm" } { "" } } */ +/* { dg-require-effective-target arm_arch_v5te_thumb_ok } */ /* { dg-options "-mthumb" } */ /* { dg-add-options arm_arch_v5te } */ diff --git a/gcc/testsuite/gcc.target/arm/ftest-armv6-arm.c b/gcc/testsuite/gcc.target/arm/ftest-armv6-arm.c index 88a5089..5d447c3 100644 --- a/gcc/testsuite/gcc.target/arm/ftest-armv6-arm.c +++ b/gcc/testsuite/gcc.target/arm/ftest-armv6-arm.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-march=*" } { "-march=armv6" } } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-mthumb" } { "" } } */ +/* { dg-require-effective-target arm_arch_v6_arm_ok } */ /* { dg-options "-marm" } */ /* { dg-add-options arm_arch_v6 } */ diff --git a/gcc/testsuite/gcc.target/arm/ftest-armv6-thumb.c b/gcc/testsuite/gcc.target/arm/ftest-armv6-thumb.c index 90ef9d2..15a6d75 100644 --- a/gcc/testsuite/gcc.target/arm/ftest-armv6-thumb.c +++ b/gcc/testsuite/gcc.target/arm/ftest-armv6-thumb.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-march=*" } { "-march=armv6" } } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-marm" } { "" } } */ +/* { dg-require-effective-target arm_arch_v6_thumb_ok } */ /* { dg-options "-mthumb" } */ /* { dg-add-options arm_arch_v6 } */ diff --git a/gcc/testsuite/gcc.target/arm/ftest-armv6k-arm.c b/gcc/testsuite/gcc.target/arm/ftest-armv6k-arm.c index 8de021a..0656e8f 100644 --- a/gcc/testsuite/gcc.target/arm/ftest-armv6k-arm.c +++ b/gcc/testsuite/gcc.target/arm/ftest-armv6k-arm.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-march=*" } { "-march=armv6k" } } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-mthumb" } { "" } } */ +/* { dg-require-effective-target arm_arch_v6k_arm_ok } */ /* { dg-options "-marm" } */ /* { dg-add-options arm_arch_v6k } */ diff --git a/gcc/testsuite/gcc.target/arm/ftest-armv6k-thumb.c b/gcc/testsuite/gcc.target/arm/ftest-armv6k-thumb.c index c2fc270..b3b6ecf 100644 --- a/gcc/testsuite/gcc.target/arm/ftest-armv6k-thumb.c +++ b/gcc/testsuite/gcc.target/arm/ftest-armv6k-thumb.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-march=*" } { "-march=armv6k" } } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-marm" } { "" } } */ +/* { dg-require-effective-target arm_arch_v6k_thumb_ok } */ /* { dg-options "-mthumb" } */ /* { dg-add-options arm_arch_v6k } */ diff --git a/gcc/testsuite/gcc.target/arm/ftest-armv6m-thumb.c b/gcc/testsuite/gcc.target/arm/ftest-armv6m-thumb.c index ee075e2..27f71be 100644 --- a/gcc/testsuite/gcc.target/arm/ftest-armv6m-thumb.c +++ b/gcc/testsuite/gcc.target/arm/ftest-armv6m-thumb.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-march=*" } { "-march=armv6-m" } } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-marm" } { "" } } */ +/* { dg-require-effective-target arm_arch_v6m_ok } */ /* { dg-options "-mthumb" } */ /* { dg-add-options arm_arch_v6m } */ diff --git a/gcc/testsuite/gcc.target/arm/ftest-armv6t2-arm.c b/gcc/testsuite/gcc.target/arm/ftest-armv6t2-arm.c index 83b4bc4..259d2b5 100644 --- a/gcc/testsuite/gcc.target/arm/ftest-armv6t2-arm.c +++ b/gcc/testsuite/gcc.target/arm/ftest-armv6t2-arm.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-march=*" } { "-march=armv6t2" } } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-mthumb" } { "" } } */ +/* { dg-require-effective-target arm_arch_v6t2_ok } */ /* { dg-options "-marm" } */ /* { dg-add-options arm_arch_v6t2 } */ diff --git a/gcc/testsuite/gcc.target/arm/ftest-armv6t2-thumb.c b/gcc/testsuite/gcc.target/arm/ftest-armv6t2-thumb.c index 1a1cbc5..e624ec5 100644 --- a/gcc/testsuite/gcc.target/arm/ftest-armv6t2-thumb.c +++ b/gcc/testsuite/gcc.target/arm/ftest-armv6t2-thumb.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-march=*" } { "-march=armv6t2" } } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-marm" } { "" } } */ +/* { dg-require-effective-target arm_arch_v6t2_ok } */ /* { dg-options "-mthumb" } */ /* { dg-add-options arm_arch_v6t2 } */ diff --git a/gcc/testsuite/gcc.target/arm/ftest-armv6z-arm.c b/gcc/testsuite/gcc.target/arm/ftest-armv6z-arm.c index e2df0d4..6e3a966 100644 --- a/gcc/testsuite/gcc.target/arm/ftest-armv6z-arm.c +++ b/gcc/testsuite/gcc.target/arm/ftest-armv6z-arm.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-march=*" } { "-march=armv6z" } } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-mthumb" } { "" } } */ +/* { dg-require-effective-target arm_arch_v6z_arm_ok } */ /* { dg-options "-marm" } */ /* { dg-add-options arm_arch_v6z } */ diff --git a/gcc/testsuite/gcc.target/arm/ftest-armv6z-thumb.c b/gcc/testsuite/gcc.target/arm/ftest-armv6z-thumb.c index e4b94ef..23a4fcd 100644 --- a/gcc/testsuite/gcc.target/arm/ftest-armv6z-thumb.c +++ b/gcc/testsuite/gcc.target/arm/ftest-armv6z-thumb.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-march=*" } { "-march=armv6z" } } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-marm" } { "" } } */ +/* { dg-require-effective-target arm_arch_v6z_thumb_ok } */ /* { dg-options "-mthumb" } */ /* { dg-add-options arm_arch_v6z } */ diff --git a/gcc/testsuite/gcc.target/arm/g2.c b/gcc/testsuite/gcc.target/arm/g2.c index e368017..ca5e3cc 100644 --- a/gcc/testsuite/gcc.target/arm/g2.c +++ b/gcc/testsuite/gcc.target/arm/g2.c @@ -4,6 +4,7 @@ /* { dg-skip-if "Test is specific to the Xscale" { arm*-*-* } { "-march=*" } { "-march=xscale" } } */ /* { dg-skip-if "Test is specific to the Xscale" { arm*-*-* } { "-mcpu=*" } { "-mcpu=xscale" } } */ /* { dg-skip-if "Test is specific to ARM mode" { arm*-*-* } { "-mthumb" } { "" } } */ +/* { dg-require-effective-target arm_arch_v5te_arm_ok } */ /* { dg-require-effective-target arm32 } */ /* Brett Gaines' test case. */ diff --git a/gcc/testsuite/gcc.target/arm/macro_defs1.c b/gcc/testsuite/gcc.target/arm/macro_defs1.c index 4cc9ae6..655ba93 100644 --- a/gcc/testsuite/gcc.target/arm/macro_defs1.c +++ b/gcc/testsuite/gcc.target/arm/macro_defs1.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-march=*" } { "-march=armv6-m" } } */ /* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-marm" } { "" } } */ +/* { dg-require-effective-target arm_arch_v6m_ok } */ /* { dg-options "-march=armv6-m -mthumb" } */ #ifdef __ARM_NEON_FP diff --git a/gcc/testsuite/gcc.target/arm/pr59858.c b/gcc/testsuite/gcc.target/arm/pr59858.c index a944b9a..bcfd5d5 100644 --- a/gcc/testsuite/gcc.target/arm/pr59858.c +++ b/gcc/testsuite/gcc.target/arm/pr59858.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-options "-march=armv5te -fno-builtin -mfloat-abi=soft -mthumb -fno-stack-protector -Os -fno-tree-loop-optimize -fno-tree-dominator-opts -fPIC -w" } */ /* { dg-skip-if "Incompatible command line options: -mfloat-abi=soft -mfloat-abi=hard" { *-*-* } { "-mfloat-abi=hard" } { "" } } */ +/* { dg-require-effective-target arm_arch_v5te_thumb_ok } */ typedef enum { REG_ENOSYS = -1, diff --git a/gcc/testsuite/gcc.target/arm/pr65647-2.c b/gcc/testsuite/gcc.target/arm/pr65647-2.c index f2985f8..e3978e5 100644 --- a/gcc/testsuite/gcc.target/arm/pr65647-2.c +++ b/gcc/testsuite/gcc.target/arm/pr65647-2.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-require-effective-target arm_arch_v6_arm_ok } */ /* { dg-options "-O3 -marm -march=armv6 -std=c99" } */ typedef struct { diff --git a/gcc/testsuite/gcc.target/arm/pr79058.c b/gcc/testsuite/gcc.target/arm/pr79058.c index 54a1d8a..7d078ac 100644 --- a/gcc/testsuite/gcc.target/arm/pr79058.c +++ b/gcc/testsuite/gcc.target/arm/pr79058.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-require-effective-target arm_arm_ok } */ +/* { dg-require-effective-target arm_arch_v4_ok } */ /* { dg-skip-if "do not override -mcpu" { *-*-* } { "-mcpu=*" } { "-mcpu=arm7tdmi" } } */ /* { dg-options "-Os -mbig-endian -marm -mcpu=arm7tdmi" } */ diff --git a/gcc/testsuite/gcc.target/arm/pr83712.c b/gcc/testsuite/gcc.target/arm/pr83712.c index 8ed8cdf..4902ec9 100644 --- a/gcc/testsuite/gcc.target/arm/pr83712.c +++ b/gcc/testsuite/gcc.target/arm/pr83712.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-require-effective-target arm_arch_v5t_thumb_ok } */ /* { dg-options "-mfloat-abi=softfp -mthumb -march=armv5t -O2" } */ #pragma GCC optimize ("-O2") diff --git a/gcc/testsuite/gcc.target/arm/pragma_arch_switch_2.c b/gcc/testsuite/gcc.target/arm/pragma_arch_switch_2.c index b6211f9..5080d2c 100644 --- a/gcc/testsuite/gcc.target/arm/pragma_arch_switch_2.c +++ b/gcc/testsuite/gcc.target/arm/pragma_arch_switch_2.c @@ -2,6 +2,7 @@ /* { dg-skip-if "instruction not valid on thumb" { *-*-* } { "-mthumb" } { "" } } */ /* { dg-do assemble } */ /* { dg-require-effective-target arm_arm_ok } */ +/* { dg-require-effective-target arm_arch_v5te_arm_ok } */ /* { dg-additional-options "-Wall -O2 -march=armv5te -std=gnu99 -marm" } */ #pragma GCC target ("arch=armv6") diff --git a/gcc/testsuite/gcc.target/arm/scd42-1.c b/gcc/testsuite/gcc.target/arm/scd42-1.c index be60e64..2b8fc0b 100644 --- a/gcc/testsuite/gcc.target/arm/scd42-1.c +++ b/gcc/testsuite/gcc.target/arm/scd42-1.c @@ -3,6 +3,7 @@ /* { dg-skip-if "Test is specific to Xscale" { arm*-*-* } { "-march=*" } { "-march=xscale" } } */ /* { dg-skip-if "Test is specific to Xscale" { arm*-*-* } { "-mcpu=*" } { "-mcpu=xscale" } } */ /* { dg-skip-if "do not override -mfloat-abi" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=softfp" } } */ +/* { dg-require-effective-target arm_arch_v5te_ok } */ /* { dg-options "-mcpu=xscale -O -mfloat-abi=softfp" } */ unsigned load1(void) __attribute__ ((naked)); diff --git a/gcc/testsuite/gcc.target/arm/scd42-2.c b/gcc/testsuite/gcc.target/arm/scd42-2.c index 6d9e5e1..3c9768d 100644 --- a/gcc/testsuite/gcc.target/arm/scd42-2.c +++ b/gcc/testsuite/gcc.target/arm/scd42-2.c @@ -4,6 +4,7 @@ /* { dg-skip-if "Test is specific to the Xscale" { arm*-*-* } { "-mcpu=*" } { "-mcpu=xscale" } } */ /* { dg-skip-if "Test is specific to ARM mode" { arm*-*-* } { "-mthumb" } { "" } } */ /* { dg-require-effective-target arm32 } */ +/* { dg-require-effective-target arm_arch_v5te_arm_ok } */ /* { dg-options "-mcpu=xscale -O -marm" } */ unsigned load2(void) __attribute__ ((naked)); diff --git a/gcc/testsuite/gcc.target/arm/scd42-3.c b/gcc/testsuite/gcc.target/arm/scd42-3.c index e566cb2..0afd121 100644 --- a/gcc/testsuite/gcc.target/arm/scd42-3.c +++ b/gcc/testsuite/gcc.target/arm/scd42-3.c @@ -3,6 +3,7 @@ /* { dg-skip-if "Test is specific to Xscale" { arm*-*-* } { "-march=*" } { "-march=xscale" } } */ /* { dg-skip-if "Test is specific to Xscale" { arm*-*-* } { "-mcpu=*" } { "-mcpu=xscale" } } */ /* { dg-skip-if "do not override -mfloat-abi" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=softfp" } } */ +/* { dg-require-effective-target arm_arch_v5te_ok } */ /* { dg-options "-mcpu=xscale -O -mfloat-abi=softfp" } */ unsigned load4(void) __attribute__ ((naked)); diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 6760e59..414bf80 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -4188,13 +4188,25 @@ proc check_effective_target_arm_fp16_hw { } { # /* { dg-require-effective-target arm_arch_v5t_multilib } */ foreach { armfunc armflag armdefs } { v4 "-march=armv4 -marm" __ARM_ARCH_4__ - v4t "-march=armv4t" __ARM_ARCH_4T__ - v5t "-march=armv5t" __ARM_ARCH_5T__ - v5te "-march=armv5te" __ARM_ARCH_5TE__ - v6 "-march=armv6" __ARM_ARCH_6__ - v6k "-march=armv6k" __ARM_ARCH_6K__ + v4t "-march=armv4t -mfloat-abi=softfp" __ARM_ARCH_4T__ + v4t_arm "-march=armv4t -marm" __ARM_ARCH_4T__ + v4t_thumb "-march=armv4t -mthumb -mfloat-abi=softfp" __ARM_ARCH_4T__ + v5t "-march=armv5t -mfloat-abi=softfp" __ARM_ARCH_5T__ + v5t_arm "-march=armv5t -marm" __ARM_ARCH_5T__ + v5t_thumb "-march=armv5t -mthumb -mfloat-abi=softfp" __ARM_ARCH_5T__ + v5te "-march=armv5te -mfloat-abi=softfp" __ARM_ARCH_5TE__ + v5te_arm "-march=armv5te -marm" __ARM_ARCH_5TE__ + v5te_thumb "-march=armv5te -mthumb -mfloat-abi=softfp" __ARM_ARCH_5TE__ + v6 "-march=armv6 -mfloat-abi=softfp" __ARM_ARCH_6__ + v6_arm "-march=armv6 -marm" __ARM_ARCH_6__ + v6_thumb "-march=armv6 -mthumb -mfloat-abi=softfp" __ARM_ARCH_6__ + v6k "-march=armv6k -mfloat-abi=softfp" __ARM_ARCH_6K__ + v6k_arm "-march=armv6k -marm" __ARM_ARCH_6K__ + v6k_thumb "-march=armv6k -mthumb -mfloat-abi=softfp" __ARM_ARCH_6K__ v6t2 "-march=armv6t2" __ARM_ARCH_6T2__ - v6z "-march=armv6z" __ARM_ARCH_6Z__ + v6z "-march=armv6z -mfloat-abi=softfp" __ARM_ARCH_6Z__ + v6z_arm "-march=armv6z -marm" __ARM_ARCH_6Z__ + v6z_thumb "-march=armv6z -mthumb -mfloat-abi=softfp" __ARM_ARCH_6Z__ v6m "-march=armv6-m -mthumb -mfloat-abi=soft" __ARM_ARCH_6M__ v7a "-march=armv7-a" __ARM_ARCH_7A__ v7r "-march=armv7-r" __ARM_ARCH_7R__ @@ -4211,10 +4223,6 @@ foreach { armfunc armflag armdefs } { v8r "-march=armv8-r" __ARM_ARCH_8R__ } { eval [string map [list FUNC $armfunc FLAG $armflag DEFS $armdefs ] { proc check_effective_target_arm_arch_FUNC_ok { } { - if { [ string match "*-marm*" "FLAG" ] && - ![check_effective_target_arm_arm_ok] } { - return 0 - } return [check_no_compiler_messages arm_arch_FUNC_ok assembly { #if !(DEFS) #error !(DEFS) -- cgit v1.1 From 1160be126809af874f3d68a514bf38b63076d1cd Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 17 Sep 2019 13:52:20 +0000 Subject: re PR debug/91772 (ICE in add_dwarf_attr, at dwarf2out.c:4412 since r259749) 2019-09-17 Richard Biener PR debug/91772 * dwarf2out.c (dwarf2out_late_global_decl): If early dwarf was missing generate locations only once. From-SVN: r275804 --- gcc/ChangeLog | 6 ++++++ gcc/dwarf2out.c | 10 +++------- 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0cbb512..6d03377 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-09-17 Richard Biener + + PR debug/91772 + * dwarf2out.c (dwarf2out_late_global_decl): If early dwarf + was missing generate locations only once. + 2019-09-17 Feng Xue PR ipa/91089 diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index c359c2d..5698c82 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -26660,16 +26660,12 @@ dwarf2out_late_global_decl (tree decl) { dw_die_ref die = lookup_decl_die (decl); - /* We may have to generate early debug late for LTO in case debug + /* We may have to generate full debug late for LTO in case debug was not enabled at compile-time or the target doesn't support the LTO early debug scheme. */ if (! die && in_lto_p) - { - dwarf2out_decl (decl); - die = lookup_decl_die (decl); - } - - if (die) + dwarf2out_decl (decl); + else if (die) { /* We get called via the symtab code invoking late_global_decl for symbols that are optimized out. -- cgit v1.1 From 7dbc2e3b6d3613473844273f24649db0b5b8461b Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 17 Sep 2019 14:27:54 +0000 Subject: Remove name of unused parameter in array-traits.h 2019-09-17 Richard Sandiford gcc/ * array-traits.h (array_traits::size): Remove parameter name. From-SVN: r275805 --- gcc/ChangeLog | 4 ++++ gcc/array-traits.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6d03377..b050369 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2019-09-17 Richard Sandiford + + * array-traits.h (array_traits::size): Remove parameter name. + 2019-09-17 Richard Biener PR debug/91772 diff --git a/gcc/array-traits.h b/gcc/array-traits.h index eb65ede..8b269a3 100644 --- a/gcc/array-traits.h +++ b/gcc/array-traits.h @@ -42,7 +42,7 @@ struct array_traits static const bool has_constant_size = true; static const size_t constant_size = N; static const T *base (const T (&x)[N]) { return x; } - static size_t size (const T (&x)[N]) { return N; } + static size_t size (const T (&)[N]) { return N; } }; #endif -- cgit v1.1 From 5d4efa795e09a17e1773e8862db8f55aa7fe90c5 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 17 Sep 2019 15:02:15 +0000 Subject: [arm] Fix insn type of *thumb1_tablejump *thumb1_tablejump had type "no_insn", which doesn't seems to correspond to its documented use: an insn which does not represent an instruction in the final output, thus having no impact on scheduling. Indirect jumps use the same instruction and have type "branch", so the patch uses "branch" here too. 2019-09-17 Richard Sandiford gcc/ * config/arm/thumb1.md (*thumb1_tablejump): Change type from "no_insn" to "branch". From-SVN: r275806 --- gcc/ChangeLog | 5 +++++ gcc/config/arm/thumb1.md | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b050369..b0a1185 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2019-09-17 Richard Sandiford + * config/arm/thumb1.md (*thumb1_tablejump): Change type from + "no_insn" to "branch". + +2019-09-17 Richard Sandiford + * array-traits.h (array_traits::size): Remove parameter name. 2019-09-17 Richard Biener diff --git a/gcc/config/arm/thumb1.md b/gcc/config/arm/thumb1.md index b142bfc..5c70200 100644 --- a/gcc/config/arm/thumb1.md +++ b/gcc/config/arm/thumb1.md @@ -1944,7 +1944,7 @@ "TARGET_THUMB1" "mov\\t%|pc, %0" [(set_attr "length" "2") - (set_attr "type" "no_insn")] + (set_attr "type" "branch")] ) (define_insn_and_split "thumb_eh_return" -- cgit v1.1 From f62281dc1b3d751977266d8c30b4488833fcb9dd Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 17 Sep 2019 17:00:58 +0000 Subject: [arm][aarch64] Make no_insn issue to nothing no_insn is documented as: an insn which does not represent an instruction in the final output, thus having no impact on scheduling. and is used in that way by the arm port (e.g. for define_insns that expand to comments). However, most scheduling descriptions instead assigned units to no_insn patterns, in some cases treating them as more expensive than a plain move. This patch removes the no_insn handling from individual scheduling descriptions and uses a common define_insn_reservation for all CPUs. 2019-09-17 Richard Sandiford gcc/ * config/arm/types.md (no_reservation): New reservation. * config/aarch64/falkor.md (falkor_other_0_nothing): Don't handle no_insn here. * config/aarch64/saphira.md (saphira_other_0_nothing): Likewise. * config/aarch64/thunderx2t99.md (thunderx2t99_nothing): Likewise. * config/aarch64/tsv110.md (tsv110_alu): Likewise. * config/arm/arm1020e.md (1020alu_op): Likewise. * config/arm/arm1026ejs.md (alu_op): Likewise. * config/arm/arm1136jfs.md (11_alu_op): Likewise. * config/arm/arm926ejs.md (9_alu_op): Likewise. * config/arm/cortex-a15.md (cortex_a15_alu): Likewise. * config/arm/cortex-a17.md (cortex_a17_alu): Likewise. * config/arm/cortex-a5.md (cortex_a5_alu): Likewise. * config/arm/cortex-a53.md (cortex_a53_alu): Likewise. * config/arm/cortex-a57.md (cortex_a57_alu): Likewise. * config/arm/cortex-a7.md (cortex_a7_alu_shift): Likewise. * config/arm/cortex-a8.md (cortex_a8_alu): Likewise. * config/arm/cortex-a9.md (cortex_a9_dp): Likewise. * config/arm/cortex-m4.md (cortex_m4_alu): Likewise. * config/arm/cortex-m7.md (cortex_m7_alu_simple): Likewise. * config/arm/cortex-r4.md (cortex_r4_alu_shift_reg): Likewise. * config/arm/fa526.md (526_alu_op): Likewise. * config/arm/fa606te.md (606te_alu_op): Likewise. * config/arm/fa626te.md (626te_alu_op): Likewise. * config/arm/fa726te.md (726te_alu_op): Likewise. * config/arm/xgene1.md (xgene1_nop): Likewise. From-SVN: r275807 --- gcc/ChangeLog | 29 +++++++++++++++++++++++++++++ gcc/config/aarch64/falkor.md | 2 +- gcc/config/aarch64/saphira.md | 2 +- gcc/config/aarch64/thunderx2t99.md | 2 +- gcc/config/aarch64/tsv110.md | 2 +- gcc/config/arm/arm1020e.md | 2 +- gcc/config/arm/arm1026ejs.md | 2 +- gcc/config/arm/arm1136jfs.md | 2 +- gcc/config/arm/arm926ejs.md | 2 +- gcc/config/arm/cortex-a15.md | 2 +- gcc/config/arm/cortex-a17.md | 2 +- gcc/config/arm/cortex-a5.md | 2 +- gcc/config/arm/cortex-a53.md | 2 +- gcc/config/arm/cortex-a57.md | 2 +- gcc/config/arm/cortex-a7.md | 2 +- gcc/config/arm/cortex-a8.md | 2 +- gcc/config/arm/cortex-a9.md | 2 +- gcc/config/arm/cortex-m4.md | 2 +- gcc/config/arm/cortex-m7.md | 2 +- gcc/config/arm/cortex-r4.md | 2 +- gcc/config/arm/fa526.md | 2 +- gcc/config/arm/fa606te.md | 2 +- gcc/config/arm/fa626te.md | 2 +- gcc/config/arm/fa726te.md | 2 +- gcc/config/arm/types.md | 4 ++++ gcc/config/arm/xgene1.md | 5 ----- 26 files changed, 56 insertions(+), 28 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b0a1185..26d0619 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,34 @@ 2019-09-17 Richard Sandiford + * config/arm/types.md (no_reservation): New reservation. + * config/aarch64/falkor.md (falkor_other_0_nothing): Don't handle + no_insn here. + * config/aarch64/saphira.md (saphira_other_0_nothing): Likewise. + * config/aarch64/thunderx2t99.md (thunderx2t99_nothing): Likewise. + * config/aarch64/tsv110.md (tsv110_alu): Likewise. + * config/arm/arm1020e.md (1020alu_op): Likewise. + * config/arm/arm1026ejs.md (alu_op): Likewise. + * config/arm/arm1136jfs.md (11_alu_op): Likewise. + * config/arm/arm926ejs.md (9_alu_op): Likewise. + * config/arm/cortex-a15.md (cortex_a15_alu): Likewise. + * config/arm/cortex-a17.md (cortex_a17_alu): Likewise. + * config/arm/cortex-a5.md (cortex_a5_alu): Likewise. + * config/arm/cortex-a53.md (cortex_a53_alu): Likewise. + * config/arm/cortex-a57.md (cortex_a57_alu): Likewise. + * config/arm/cortex-a7.md (cortex_a7_alu_shift): Likewise. + * config/arm/cortex-a8.md (cortex_a8_alu): Likewise. + * config/arm/cortex-a9.md (cortex_a9_dp): Likewise. + * config/arm/cortex-m4.md (cortex_m4_alu): Likewise. + * config/arm/cortex-m7.md (cortex_m7_alu_simple): Likewise. + * config/arm/cortex-r4.md (cortex_r4_alu_shift_reg): Likewise. + * config/arm/fa526.md (526_alu_op): Likewise. + * config/arm/fa606te.md (606te_alu_op): Likewise. + * config/arm/fa626te.md (626te_alu_op): Likewise. + * config/arm/fa726te.md (726te_alu_op): Likewise. + * config/arm/xgene1.md (xgene1_nop): Likewise. + +2019-09-17 Richard Sandiford + * config/arm/thumb1.md (*thumb1_tablejump): Change type from "no_insn" to "branch". diff --git a/gcc/config/aarch64/falkor.md b/gcc/config/aarch64/falkor.md index 41955af..2bcc661 100644 --- a/gcc/config/aarch64/falkor.md +++ b/gcc/config/aarch64/falkor.md @@ -648,7 +648,7 @@ (define_insn_reservation "falkor_other_0_nothing" 0 (and (eq_attr "tune" "falkor") - (eq_attr "type" "no_insn,trap,block")) + (eq_attr "type" "trap,block")) "nothing") (define_insn_reservation "falkor_other_2_z" 2 diff --git a/gcc/config/aarch64/saphira.md b/gcc/config/aarch64/saphira.md index 853deee..3cc7bc4 100644 --- a/gcc/config/aarch64/saphira.md +++ b/gcc/config/aarch64/saphira.md @@ -520,7 +520,7 @@ (define_insn_reservation "saphira_other_0_nothing" 0 (and (eq_attr "tune" "saphira") - (eq_attr "type" "no_insn,trap,block")) + (eq_attr "type" "trap,block")) "nothing") (define_insn_reservation "saphira_other_2_ld" 2 diff --git a/gcc/config/aarch64/thunderx2t99.md b/gcc/config/aarch64/thunderx2t99.md index c43c39e..bb6e0ab 100644 --- a/gcc/config/aarch64/thunderx2t99.md +++ b/gcc/config/aarch64/thunderx2t99.md @@ -74,7 +74,7 @@ (define_insn_reservation "thunderx2t99_nothing" 0 (and (eq_attr "tune" "thunderx2t99") - (eq_attr "type" "no_insn,block")) + (eq_attr "type" "block")) "nothing") (define_insn_reservation "thunderx2t99_mrs" 0 diff --git a/gcc/config/aarch64/tsv110.md b/gcc/config/aarch64/tsv110.md index 680c48a..f20055d 100644 --- a/gcc/config/aarch64/tsv110.md +++ b/gcc/config/aarch64/tsv110.md @@ -281,7 +281,7 @@ shift_imm,shift_reg,\ mov_imm,mov_reg,\ mvn_imm,mvn_reg,\ - mrs,multiple,no_insn")) + mrs,multiple")) "tsv110_alu1|tsv110_alu2|tsv110_alu3") (define_insn_reservation "tsv110_alus" 1 diff --git a/gcc/config/arm/arm1020e.md b/gcc/config/arm/arm1020e.md index b835cba..c4c038b 100644 --- a/gcc/config/arm/arm1020e.md +++ b/gcc/config/arm/arm1020e.md @@ -72,7 +72,7 @@ adr,bfm,rev,\ shift_imm,shift_reg,\ mov_imm,mov_reg,mvn_imm,mvn_reg,\ - multiple,no_insn")) + multiple")) "1020a_e,1020a_m,1020a_w") ;; ALU operations with a shift-by-constant operand diff --git a/gcc/config/arm/arm1026ejs.md b/gcc/config/arm/arm1026ejs.md index 05f4d72..8854687 100644 --- a/gcc/config/arm/arm1026ejs.md +++ b/gcc/config/arm/arm1026ejs.md @@ -72,7 +72,7 @@ adr,bfm,rev,\ shift_imm,shift_reg,\ mov_imm,mov_reg,mvn_imm,mvn_reg,\ - multiple,no_insn")) + multiple")) "a_e,a_m,a_w") ;; ALU operations with a shift-by-constant operand diff --git a/gcc/config/arm/arm1136jfs.md b/gcc/config/arm/arm1136jfs.md index ae0b54f..e7fd53a 100644 --- a/gcc/config/arm/arm1136jfs.md +++ b/gcc/config/arm/arm1136jfs.md @@ -81,7 +81,7 @@ adr,bfm,rev,\ shift_imm,shift_reg,\ mov_imm,mov_reg,mvn_imm,mvn_reg,\ - multiple,no_insn")) + multiple")) "e_1,e_2,e_3,e_wb") ;; ALU operations with a shift-by-constant operand diff --git a/gcc/config/arm/arm926ejs.md b/gcc/config/arm/arm926ejs.md index db4c7db..b4f5031 100644 --- a/gcc/config/arm/arm926ejs.md +++ b/gcc/config/arm/arm926ejs.md @@ -67,7 +67,7 @@ shift_imm,shift_reg,extend,\ mov_imm,mov_reg,mov_shift,\ mvn_imm,mvn_reg,mvn_shift,\ - multiple,no_insn")) + multiple")) "e,m,w") ;; ALU operations with a shift-by-register operand diff --git a/gcc/config/arm/cortex-a15.md b/gcc/config/arm/cortex-a15.md index f57f986..26765c3 100644 --- a/gcc/config/arm/cortex-a15.md +++ b/gcc/config/arm/cortex-a15.md @@ -68,7 +68,7 @@ shift_imm,shift_reg,\ mov_imm,mov_reg,\ mvn_imm,mvn_reg,\ - mrs,multiple,no_insn")) + mrs,multiple")) "ca15_issue1,(ca15_sx1,ca15_sx1_alu)|(ca15_sx2,ca15_sx2_alu)") ;; ALU ops with immediate shift diff --git a/gcc/config/arm/cortex-a17.md b/gcc/config/arm/cortex-a17.md index a0c6e51..97b7164 100644 --- a/gcc/config/arm/cortex-a17.md +++ b/gcc/config/arm/cortex-a17.md @@ -42,7 +42,7 @@ adc_imm,adcs_imm,adc_reg,adcs_reg,\ adr, mov_imm,mov_reg,\ mvn_imm,mvn_reg,extend,\ - mrs,multiple,no_insn")) + mrs,multiple")) "ca17_alu") (define_insn_reservation "cortex_a17_alu_shiftimm" 2 diff --git a/gcc/config/arm/cortex-a5.md b/gcc/config/arm/cortex-a5.md index efced64..08aa908 100644 --- a/gcc/config/arm/cortex-a5.md +++ b/gcc/config/arm/cortex-a5.md @@ -64,7 +64,7 @@ adr,bfm,clz,rbit,rev,alu_dsp_reg,\ shift_imm,shift_reg,\ mov_imm,mov_reg,mvn_imm,mvn_reg,\ - mrs,multiple,no_insn")) + mrs,multiple")) "cortex_a5_ex1") (define_insn_reservation "cortex_a5_alu_shift" 2 diff --git a/gcc/config/arm/cortex-a53.md b/gcc/config/arm/cortex-a53.md index 58619aa..c6992fa 100644 --- a/gcc/config/arm/cortex-a53.md +++ b/gcc/config/arm/cortex-a53.md @@ -86,7 +86,7 @@ alu_sreg,alus_sreg,logic_reg,logics_reg, adc_imm,adcs_imm,adc_reg,adcs_reg, csel,clz,rbit,rev,alu_dsp_reg, - mov_reg,mvn_reg,mrs,multiple,no_insn")) + mov_reg,mvn_reg,mrs,multiple")) "cortex_a53_slot_any") (define_insn_reservation "cortex_a53_alu_shift" 3 diff --git a/gcc/config/arm/cortex-a57.md b/gcc/config/arm/cortex-a57.md index 2d96a9c..0460243 100644 --- a/gcc/config/arm/cortex-a57.md +++ b/gcc/config/arm/cortex-a57.md @@ -306,7 +306,7 @@ rotate_imm,shift_imm,shift_reg,\ mov_imm,mov_reg,\ mvn_imm,mvn_reg,\ - mrs,multiple,no_insn")) + mrs,multiple")) "ca57_sx1|ca57_sx2") ;; ALU ops with immediate shift diff --git a/gcc/config/arm/cortex-a7.md b/gcc/config/arm/cortex-a7.md index 1f9d641..f1b60aa 100644 --- a/gcc/config/arm/cortex-a7.md +++ b/gcc/config/arm/cortex-a7.md @@ -149,7 +149,7 @@ logic_shift_reg,logics_shift_reg,\ mov_shift,mov_shift_reg,\ mvn_shift,mvn_shift_reg,\ - mrs,multiple,no_insn")) + mrs,multiple")) "cortex_a7_ex1") ;; Forwarding path for unshifted operands. diff --git a/gcc/config/arm/cortex-a8.md b/gcc/config/arm/cortex-a8.md index 980aed8..e337245 100644 --- a/gcc/config/arm/cortex-a8.md +++ b/gcc/config/arm/cortex-a8.md @@ -90,7 +90,7 @@ adc_imm,adcs_imm,adc_reg,adcs_reg,\ adr,bfm,clz,rbit,rev,alu_dsp_reg,\ shift_imm,shift_reg,\ - multiple,no_insn")) + multiple")) "cortex_a8_default") (define_insn_reservation "cortex_a8_alu_shift" 2 diff --git a/gcc/config/arm/cortex-a9.md b/gcc/config/arm/cortex-a9.md index 6402a44..c847415 100644 --- a/gcc/config/arm/cortex-a9.md +++ b/gcc/config/arm/cortex-a9.md @@ -87,7 +87,7 @@ cortex_a9_p1_e2 + cortex_a9_p0_e1 + cortex_a9_p1_e1") shift_imm,shift_reg,\ mov_imm,mov_reg,mvn_imm,mvn_reg,\ mov_shift_reg,mov_shift,\ - mrs,multiple,no_insn")) + mrs,multiple")) "cortex_a9_p0_default|cortex_a9_p1_default") ;; An instruction using the shifter will go down E1. diff --git a/gcc/config/arm/cortex-m4.md b/gcc/config/arm/cortex-m4.md index 60038c1..f8efcfc 100644 --- a/gcc/config/arm/cortex-m4.md +++ b/gcc/config/arm/cortex-m4.md @@ -42,7 +42,7 @@ logic_shift_reg,logics_shift_reg,\ mov_imm,mov_reg,mov_shift,mov_shift_reg,\ mvn_imm,mvn_reg,mvn_shift,mvn_shift_reg,\ - mrs,multiple,no_insn") + mrs,multiple") (ior (eq_attr "mul32" "yes") (eq_attr "widen_mul64" "yes")))) "cortex_m4_ex") diff --git a/gcc/config/arm/cortex-m7.md b/gcc/config/arm/cortex-m7.md index e4695ad..dfe9a74 100644 --- a/gcc/config/arm/cortex-m7.md +++ b/gcc/config/arm/cortex-m7.md @@ -48,7 +48,7 @@ logic_shift_imm,logics_shift_imm,\ alu_shift_reg,alus_shift_reg,\ logic_shift_reg,logics_shift_reg,\ - mrs,clz,f_mcr,f_mrc,multiple,no_insn")) + mrs,clz,f_mcr,f_mrc,multiple")) "cm7_i0|cm7_i1,cm7_a0|cm7_a1") ;; Simple alu with inline shift operation. diff --git a/gcc/config/arm/cortex-r4.md b/gcc/config/arm/cortex-r4.md index d7c0135..af5db23 100644 --- a/gcc/config/arm/cortex-r4.md +++ b/gcc/config/arm/cortex-r4.md @@ -102,7 +102,7 @@ (eq_attr "type" "alu_shift_reg,alus_shift_reg,\ logic_shift_reg,logics_shift_reg,\ mov_shift_reg,mvn_shift_reg,\ - mrs,multiple,no_insn")) + mrs,multiple")) "cortex_r4_alu_shift_reg") ;; An ALU instruction followed by an ALU instruction with no early dep. diff --git a/gcc/config/arm/fa526.md b/gcc/config/arm/fa526.md index e6625b01..294b796 100644 --- a/gcc/config/arm/fa526.md +++ b/gcc/config/arm/fa526.md @@ -68,7 +68,7 @@ adr,bfm,rev,\ shift_imm,shift_reg,\ mov_imm,mov_reg,mvn_imm,mvn_reg,\ - mrs,multiple,no_insn")) + mrs,multiple")) "fa526_core") (define_insn_reservation "526_alu_shift_op" 2 diff --git a/gcc/config/arm/fa606te.md b/gcc/config/arm/fa606te.md index f2c104f..9007050 100644 --- a/gcc/config/arm/fa606te.md +++ b/gcc/config/arm/fa606te.md @@ -73,7 +73,7 @@ logic_shift_reg,logics_shift_reg,\ mov_imm,mov_reg,mov_shift,mov_shift_reg,\ mvn_imm,mvn_reg,mvn_shift,mvn_shift_reg,\ - mrs,multiple,no_insn")) + mrs,multiple")) "fa606te_core") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/gcc/config/arm/fa626te.md b/gcc/config/arm/fa626te.md index 880090f..6bdc2e8 100644 --- a/gcc/config/arm/fa626te.md +++ b/gcc/config/arm/fa626te.md @@ -74,7 +74,7 @@ adr,bfm,rev,\ shift_imm,shift_reg,\ mov_imm,mov_reg,mvn_imm,mvn_reg,\ - mrs,multiple,no_insn")) + mrs,multiple")) "fa626te_core") (define_insn_reservation "626te_alu_shift_op" 2 diff --git a/gcc/config/arm/fa726te.md b/gcc/config/arm/fa726te.md index cb5fbaf..f6f2531 100644 --- a/gcc/config/arm/fa726te.md +++ b/gcc/config/arm/fa726te.md @@ -91,7 +91,7 @@ adc_imm,adcs_imm,adc_reg,adcs_reg,\ adr,bfm,rev,\ shift_imm,shift_reg,\ - mrs,multiple,no_insn")) + mrs,multiple")) "fa726te_issue+(fa726te_alu0_pipe|fa726te_alu1_pipe)") ;; ALU operations with a shift-by-register operand. diff --git a/gcc/config/arm/types.md b/gcc/config/arm/types.md index 03d6b67..60faad6 100644 --- a/gcc/config/arm/types.md +++ b/gcc/config/arm/types.md @@ -1220,3 +1220,7 @@ crypto_sha256_fast, crypto_sha256_slow") (const_string "yes") (const_string "no"))) + +(define_insn_reservation "no_reservation" 0 + (eq_attr "type" "no_insn") + "nothing") diff --git a/gcc/config/arm/xgene1.md b/gcc/config/arm/xgene1.md index 1415642..81498da 100644 --- a/gcc/config/arm/xgene1.md +++ b/gcc/config/arm/xgene1.md @@ -64,11 +64,6 @@ (eq_attr "type" "branch")) "xgene1_decode1op") -(define_insn_reservation "xgene1_nop" 1 - (and (eq_attr "tune" "xgene1") - (eq_attr "type" "no_insn")) - "xgene1_decode1op") - (define_insn_reservation "xgene1_call" 1 (and (eq_attr "tune" "xgene1") (eq_attr "type" "call")) -- cgit v1.1 From d0bc0cb66bcb0e6a5a5a31a9e900e8ccc98e34e5 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 17 Sep 2019 17:01:10 +0000 Subject: [arm][aarch64] Handle no_insn in TARGET_SCHED_VARIABLE_ISSUE Since no_insn patterns expand to no instructions, they shouldn't count against the issue rate, just like USEs and CLOBBERs don't. 2019-09-17 Richard Sandiford gcc/ * config/aarch64/aarch64.c (aarch64_sched_variable_issue): New function. (TARGET_SCHED_VARIABLE_ISSUE): New macro. * config/arm/arm.c (arm_sched_variable_issue): New function. (TARGET_SCHED_VARIABLE_ISSUE): New macro. From-SVN: r275808 --- gcc/ChangeLog | 8 ++++++++ gcc/config/aarch64/aarch64.c | 20 ++++++++++++++++++++ gcc/config/arm/arm.c | 21 +++++++++++++++++++++ 3 files changed, 49 insertions(+) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 26d0619..5a4fc2c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 2019-09-17 Richard Sandiford + * config/aarch64/aarch64.c (aarch64_sched_variable_issue): New + function. + (TARGET_SCHED_VARIABLE_ISSUE): New macro. + * config/arm/arm.c (arm_sched_variable_issue): New function. + (TARGET_SCHED_VARIABLE_ISSUE): New macro. + +2019-09-17 Richard Sandiford + * config/arm/types.md (no_reservation): New reservation. * config/aarch64/falkor.md (falkor_other_0_nothing): Don't handle no_insn here. diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index ed04060..232317d 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -11804,6 +11804,23 @@ aarch64_sched_issue_rate (void) return aarch64_tune_params.issue_rate; } +/* Implement TARGET_SCHED_VARIABLE_ISSUE. */ +static int +aarch64_sched_variable_issue (FILE *, int, rtx_insn *insn, int more) +{ + if (DEBUG_INSN_P (insn)) + return more; + + rtx_code code = GET_CODE (PATTERN (insn)); + if (code == USE || code == CLOBBER) + return more; + + if (get_attr_type (insn) == TYPE_NO_INSN) + return more; + + return more - 1; +} + static int aarch64_sched_first_cycle_multipass_dfa_lookahead (void) { @@ -20584,6 +20601,9 @@ aarch64_libgcc_floating_mode_supported_p #undef TARGET_SCHED_ISSUE_RATE #define TARGET_SCHED_ISSUE_RATE aarch64_sched_issue_rate +#undef TARGET_SCHED_VARIABLE_ISSUE +#define TARGET_SCHED_VARIABLE_ISSUE aarch64_sched_variable_issue + #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \ aarch64_sched_first_cycle_multipass_dfa_lookahead diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index b59778c..c9ab71e 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -257,6 +257,7 @@ static bool arm_sched_can_speculate_insn (rtx_insn *); static bool arm_macro_fusion_p (void); static bool arm_cannot_copy_insn_p (rtx_insn *); static int arm_issue_rate (void); +static int arm_sched_variable_issue (FILE *, int, rtx_insn *, int); static int arm_first_cycle_multipass_dfa_lookahead (void); static int arm_first_cycle_multipass_dfa_lookahead_guard (rtx_insn *, int); static void arm_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED; @@ -665,6 +666,9 @@ static const struct attribute_spec arm_attribute_table[] = #undef TARGET_SCHED_ISSUE_RATE #define TARGET_SCHED_ISSUE_RATE arm_issue_rate +#undef TARGET_SCHED_VARIABLE_ISSUE +#define TARGET_SCHED_VARIABLE_ISSUE arm_sched_variable_issue + #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \ arm_first_cycle_multipass_dfa_lookahead @@ -28495,6 +28499,23 @@ arm_issue_rate (void) return current_tune->issue_rate; } +/* Implement TARGET_SCHED_VARIABLE_ISSUE. */ +static int +arm_sched_variable_issue (FILE *, int, rtx_insn *insn, int more) +{ + if (DEBUG_INSN_P (insn)) + return more; + + rtx_code code = GET_CODE (PATTERN (insn)); + if (code == USE || code == CLOBBER) + return more; + + if (get_attr_type (insn) == TYPE_NO_INSN) + return more; + + return more - 1; +} + /* Return how many instructions should scheduler lookahead to choose the best one. */ static int -- cgit v1.1 From 99a28ee8c18fd1f452c002f0548c54eb0a7be817 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 17 Sep 2019 17:22:18 +0000 Subject: reflect: unexport FFICallbackGo; use go:linkname instead The function was always intended to be internal-only, but was exported so that C code could call it. Now that have go:linkname for that, use it. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/195857 From-SVN: r275809 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 1456026..ab30040 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -722990deeede7801e4ed3ca5d53ce312a19fcd7a +ff18e041624b8c23ffcd747f51e9dda945777d2a The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From 033425d0ed0092748fc919e5c40dc47421dcdd89 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 17 Sep 2019 20:24:00 +0000 Subject: re PR go/91781 (r275691 breaks go test "reflect") PR go/91781 reflect: promote integer closure return to full word The libffi library expects an integer return type to be promoted to a full word. Implement that when returning from a closure written in Go. This only matters on big-endian systems when returning an integer smaller than the pointer size, which is why we didn't notice it until now. Fixes https://gcc.gnu.org/PR91781. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/195858 From-SVN: r275813 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index ab30040..4a81caa 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -ff18e041624b8c23ffcd747f51e9dda945777d2a +7aabaf8623cf88e2378057476a034093abbe5aab The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From 7e6fecf5008038b466d350a0d7676f8d8ba59ff1 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 17 Sep 2019 20:26:21 +0000 Subject: runtime: for FFI, treat directIface types as pointers This only matters on systems that pass a struct with a single pointer field differently than passing a single pointer. I noticed it on 32-bit PPC, where the reflect package TestDirectIfaceMethod failed. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/195878 From-SVN: r275814 --- gcc/go/gofrontend/MERGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 4a81caa..4b7a4b3 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -7aabaf8623cf88e2378057476a034093abbe5aab +09ca3c1ea8a52b5d3d6c4331c59d44e0b6bfab57 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. -- cgit v1.1 From 6a6341917f9e6d8cf500c24883e543caf3b6af8b Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Wed, 18 Sep 2019 00:16:15 +0000 Subject: Daily bump. From-SVN: r275833 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 2dd6da8..2d37305 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20190917 +20190918 -- cgit v1.1 From ad4644f378fe2f731cd987a4aff14b935f530b88 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 18 Sep 2019 07:38:32 +0000 Subject: [x86] Tweak testcases for PR82361 gcc/testsuite/gcc.target/i386/pr82361-[12].c check whether we can optimise away a 32-to-64-bit zero extension of a 32-bit division or modulus result. Currently this fails for the modulus part of f1 and f2 in pr82361-1.c: /* FIXME: We are still not able to optimize the modulo in f1/f2, only manage one. */ /* { dg-final { scan-assembler-times "movl\t%edx" 2 } } */ pr82361-2.c instead expects no failures: /* Ditto %edx to %rdx zero extensions. */ /* { dg-final { scan-assembler-not "movl\t%edx, %edx" } } */ But we actually get the same zero-extensions for f1 and f2 in pr82361-2.c. The reason they don't trigger a failure is that the RA allocates the asm input for "d" to %rdi rather than %rdx, so we have: movl %rdx, %rdi instead of: movl %rdx, %rdx For the tests to work as expected, I think they have to force "c" and "d" to be %rax and %rdx respectively. We then see the same failure in pr82361-2.c as for pr82361-1.c (but doubled, due to the 8-bit division path). 2019-09-18 Richard Sandiford gcc/testsuite/ * gcc.target/i386/pr82361-1.c (f1, f2, f3, f4, f5, f6): Force "c" to be in %rax and "d" to be in %rdx. * gcc.target/i386/pr82361-2.c: Expect 4 instances of "movl\t%edx". From-SVN: r275836 --- gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/gcc.target/i386/pr82361-1.c | 20 ++++++++++---------- gcc/testsuite/gcc.target/i386/pr82361-2.c | 5 +++-- 3 files changed, 19 insertions(+), 12 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 918cd4b..cc27ca3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2019-09-18 Richard Sandiford + + * gcc.target/i386/pr82361-1.c (f1, f2, f3, f4, f5, f6): Force + "c" to be in %rax and "d" to be in %rdx. + * gcc.target/i386/pr82361-2.c: Expect 4 instances of "movl\t%edx". + 2019-19-17 Christophe Lyon * lib/target-supports.exp diff --git a/gcc/testsuite/gcc.target/i386/pr82361-1.c b/gcc/testsuite/gcc.target/i386/pr82361-1.c index e7c3565..dec1792 100644 --- a/gcc/testsuite/gcc.target/i386/pr82361-1.c +++ b/gcc/testsuite/gcc.target/i386/pr82361-1.c @@ -4,50 +4,50 @@ /* We should be able to optimize all %eax to %rax zero extensions, because div and idiv instructions with 32-bit operands zero-extend both results. */ /* { dg-final { scan-assembler-not "movl\t%eax, %eax" } } */ -/* FIXME: We are still not able to optimize the modulo in f1/f2, only manage - one. */ +/* FIXME: The compiler does not merge zero-extension to the modulo part + of f1 and f2. */ /* { dg-final { scan-assembler-times "movl\t%edx" 2 } } */ void f1 (unsigned int a, unsigned int b) { - unsigned long long c = a / b; - unsigned long long d = a % b; + register unsigned long long c asm ("rax") = a / b; + register unsigned long long d asm ("rdx") = a % b; asm volatile ("" : : "r" (c), "r" (d)); } void f2 (int a, int b) { - unsigned long long c = (unsigned int) (a / b); - unsigned long long d = (unsigned int) (a % b); + register unsigned long long c asm ("rax") = (unsigned int) (a / b); + register unsigned long long d asm ("rdx") = (unsigned int) (a % b); asm volatile ("" : : "r" (c), "r" (d)); } void f3 (unsigned int a, unsigned int b) { - unsigned long long c = a / b; + register unsigned long long c asm ("rax") = a / b; asm volatile ("" : : "r" (c)); } void f4 (int a, int b) { - unsigned long long c = (unsigned int) (a / b); + register unsigned long long c asm ("rax") = (unsigned int) (a / b); asm volatile ("" : : "r" (c)); } void f5 (unsigned int a, unsigned int b) { - unsigned long long d = a % b; + register unsigned long long d asm ("rdx") = a % b; asm volatile ("" : : "r" (d)); } void f6 (int a, int b) { - unsigned long long d = (unsigned int) (a % b); + register unsigned long long d asm ("rdx") = (unsigned int) (a % b); asm volatile ("" : : "r" (d)); } diff --git a/gcc/testsuite/gcc.target/i386/pr82361-2.c b/gcc/testsuite/gcc.target/i386/pr82361-2.c index c1e484d..2d87de1 100644 --- a/gcc/testsuite/gcc.target/i386/pr82361-2.c +++ b/gcc/testsuite/gcc.target/i386/pr82361-2.c @@ -4,7 +4,8 @@ /* We should be able to optimize all %eax to %rax zero extensions, because div and idiv instructions with 32-bit operands zero-extend both results. */ /* { dg-final { scan-assembler-not "movl\t%eax, %eax" } } */ -/* Ditto %edx to %rdx zero extensions. */ -/* { dg-final { scan-assembler-not "movl\t%edx, %edx" } } */ +/* FIXME: The compiler does not merge zero-extension to the modulo part + of f1 and f2. */ +/* { dg-final { scan-assembler-times "movl\t%edx" 4 } } */ #include "pr82361-1.c" -- cgit v1.1 From 2778553904f1653be5f90679570f8a60eabf2cfc Mon Sep 17 00:00:00 2001 From: Arnaud Charlet Date: Wed, 18 Sep 2019 08:31:27 +0000 Subject: [Ada] Refine previous change for -gnatn and LLVM 2019-09-18 Arnaud Charlet gcc/ada/ * exp_unst.adb (Unnest_Subprograms): Refine previous change. From-SVN: r275837 --- gcc/ada/ChangeLog | 4 ++++ gcc/ada/exp_unst.adb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index b327857..75ceaf1 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,7 @@ +2019-09-18 Arnaud Charlet + + * exp_unst.adb (Unnest_Subprograms): Refine previous change. + 2019-09-17 Claire Dross * libgnat/a-cofuma.ads, libgnat/a-cofuma.adb (Remove): New diff --git a/gcc/ada/exp_unst.adb b/gcc/ada/exp_unst.adb index 7cc9a6a4..8c492bc 100644 --- a/gcc/ada/exp_unst.adb +++ b/gcc/ada/exp_unst.adb @@ -2592,9 +2592,9 @@ package body Exp_Unst is then Subp_Body := Parent (Declaration_Node (Corresponding_Body (Subp_Body))); - Unnest_Subprogram (Subp, Subp_Body, For_Inline => True); end if; + Unnest_Subprogram (Subp, Subp_Body, For_Inline => True); Next_Inlined_Subprogram (Subp); end loop; end Unnest_Subprograms; -- cgit v1.1 From 2b6cd962513387303661614b292397cb6432590c Mon Sep 17 00:00:00 2001 From: Claire Dross Date: Wed, 18 Sep 2019 08:31:32 +0000 Subject: [Ada] Fix style issues in functional maps Rename global constants from I to J. No functional changes. 2019-09-18 Claire Dross gcc/ada/ * libgnat/a-cofuma.adb (Remove, Elements_Equal_Except, Keys_Included, Keys_Included_Except): Rename loop indexes and global constants from I to J. From-SVN: r275838 --- gcc/ada/ChangeLog | 6 ++++++ gcc/ada/libgnat/a-cofuma.adb | 30 +++++++++++++++--------------- 2 files changed, 21 insertions(+), 15 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 75ceaf1..8906ea1 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,9 @@ +2019-09-18 Claire Dross + + * libgnat/a-cofuma.adb (Remove, Elements_Equal_Except, + Keys_Included, Keys_Included_Except): Rename loop indexes and + global constants from I to J. + 2019-09-18 Arnaud Charlet * exp_unst.adb (Unnest_Subprograms): Refine previous change. diff --git a/gcc/ada/libgnat/a-cofuma.adb b/gcc/ada/libgnat/a-cofuma.adb index d963f6e..e8da187 100644 --- a/gcc/ada/libgnat/a-cofuma.adb +++ b/gcc/ada/libgnat/a-cofuma.adb @@ -88,15 +88,15 @@ package body Ada.Containers.Functional_Maps with SPARK_Mode => Off is New_Key : Key_Type) return Boolean is begin - for I in 1 .. Length (Left.Keys) loop + for J in 1 .. Length (Left.Keys) loop declare - K : constant Key_Type := Get (Left.Keys, I); + K : constant Key_Type := Get (Left.Keys, J); begin if not Equivalent_Keys (K, New_Key) and then (Find (Right.Keys, K) = 0 or else Get (Right.Elements, Find (Right.Keys, K)) /= - Get (Left.Elements, I)) + Get (Left.Elements, J)) then return False; end if; @@ -112,16 +112,16 @@ package body Ada.Containers.Functional_Maps with SPARK_Mode => Off is Y : Key_Type) return Boolean is begin - for I in 1 .. Length (Left.Keys) loop + for J in 1 .. Length (Left.Keys) loop declare - K : constant Key_Type := Get (Left.Keys, I); + K : constant Key_Type := Get (Left.Keys, J); begin if not Equivalent_Keys (K, X) and then not Equivalent_Keys (K, Y) and then (Find (Right.Keys, K) = 0 or else Get (Right.Elements, Find (Right.Keys, K)) /= - Get (Left.Elements, I)) + Get (Left.Elements, J)) then return False; end if; @@ -173,9 +173,9 @@ package body Ada.Containers.Functional_Maps with SPARK_Mode => Off is function Keys_Included (Left : Map; Right : Map) return Boolean is begin - for I in 1 .. Length (Left.Keys) loop + for J in 1 .. Length (Left.Keys) loop declare - K : constant Key_Type := Get (Left.Keys, I); + K : constant Key_Type := Get (Left.Keys, J); begin if Find (Right.Keys, K) = 0 then return False; @@ -196,9 +196,9 @@ package body Ada.Containers.Functional_Maps with SPARK_Mode => Off is New_Key : Key_Type) return Boolean is begin - for I in 1 .. Length (Left.Keys) loop + for J in 1 .. Length (Left.Keys) loop declare - K : constant Key_Type := Get (Left.Keys, I); + K : constant Key_Type := Get (Left.Keys, J); begin if not Equivalent_Keys (K, New_Key) and then Find (Right.Keys, K) = 0 @@ -218,9 +218,9 @@ package body Ada.Containers.Functional_Maps with SPARK_Mode => Off is Y : Key_Type) return Boolean is begin - for I in 1 .. Length (Left.Keys) loop + for J in 1 .. Length (Left.Keys) loop declare - K : constant Key_Type := Get (Left.Keys, I); + K : constant Key_Type := Get (Left.Keys, J); begin if not Equivalent_Keys (K, X) and then not Equivalent_Keys (K, Y) @@ -248,11 +248,11 @@ package body Ada.Containers.Functional_Maps with SPARK_Mode => Off is ------------ function Remove (Container : Map; Key : Key_Type) return Map is - I : constant Extended_Index := Find (Container.Keys, Key); + J : constant Extended_Index := Find (Container.Keys, Key); begin return - (Keys => Remove (Container.Keys, I), - Elements => Remove (Container.Elements, I)); + (Keys => Remove (Container.Keys, J), + Elements => Remove (Container.Elements, J)); end Remove; --------------- -- cgit v1.1 From 5ce1c7733b720d583eb46910e738adc932ecf7ce Mon Sep 17 00:00:00 2001 From: Bob Duff Date: Wed, 18 Sep 2019 08:31:37 +0000 Subject: [Ada] Avoid uninitialized variable in bounded containers In function Copy in Ada.Containers.Bounded_Ordered_Sets and other bounded containers packages, remove a possible use of an uninitialized variable. This was not a bug, because the uninitialized variable could be used only if checks are suppressed, and the checks would have failed, leading to erroneous execution. However, it seems more robust this way, and is probably equally efficient, and avoids a warning that is given if checks are suppressed, and the -Wall switch is given, and optimization is turned on. 2019-09-18 Bob Duff gcc/ada/ * libgnat/a-cbhama.adb, libgnat/a-cbhase.adb, libgnat/a-cbmutr.adb, libgnat/a-cborma.adb, libgnat/a-cborse.adb, libgnat/a-cobove.adb (Copy): Avoid reading the uninitialized variable C in the Checks = False case. Change variable to be a constant. gcc/testsuite/ * gnat.dg/containers1.adb, gnat.dg/containers1.ads: New testcase. From-SVN: r275839 --- gcc/ada/ChangeLog | 8 ++++++++ gcc/ada/libgnat/a-cbhama.adb | 14 +++++--------- gcc/ada/libgnat/a-cbhase.adb | 12 +++++------- gcc/ada/libgnat/a-cbmutr.adb | 13 +++++-------- gcc/ada/libgnat/a-cborma.adb | 15 +++++---------- gcc/ada/libgnat/a-cborse.adb | 13 +++++-------- gcc/ada/libgnat/a-cobove.adb | 16 +++++----------- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gnat.dg/containers1.adb | 5 +++++ gcc/testsuite/gnat.dg/containers1.ads | 6 ++++++ 10 files changed, 54 insertions(+), 53 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/containers1.adb create mode 100644 gcc/testsuite/gnat.dg/containers1.ads (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 8906ea1..d4c51d1 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,11 @@ +2019-09-18 Bob Duff + + * libgnat/a-cbhama.adb, libgnat/a-cbhase.adb, + libgnat/a-cbmutr.adb, libgnat/a-cborma.adb, + libgnat/a-cborse.adb, libgnat/a-cobove.adb (Copy): Avoid reading + the uninitialized variable C in the Checks = False case. Change + variable to be a constant. + 2019-09-18 Claire Dross * libgnat/a-cofuma.adb (Remove, Elements_Equal_Except, diff --git a/gcc/ada/libgnat/a-cbhama.adb b/gcc/ada/libgnat/a-cbhama.adb index 68e3602..74e3d95 100644 --- a/gcc/ada/libgnat/a-cbhama.adb +++ b/gcc/ada/libgnat/a-cbhama.adb @@ -262,18 +262,14 @@ package body Ada.Containers.Bounded_Hashed_Maps is Capacity : Count_Type := 0; Modulus : Hash_Type := 0) return Map is - C : Count_Type; + C : constant Count_Type := + (if Capacity = 0 then Source.Length + else Capacity); M : Hash_Type; begin - if Capacity = 0 then - C := Source.Length; - - elsif Capacity >= Source.Length then - C := Capacity; - - elsif Checks then - raise Capacity_Error with "Capacity value too small"; + if Checks and then C < Source.Length then + raise Capacity_Error with "Capacity too small"; end if; if Modulus = 0 then diff --git a/gcc/ada/libgnat/a-cbhase.adb b/gcc/ada/libgnat/a-cbhase.adb index 796cb97..390e82b 100644 --- a/gcc/ada/libgnat/a-cbhase.adb +++ b/gcc/ada/libgnat/a-cbhase.adb @@ -254,16 +254,14 @@ package body Ada.Containers.Bounded_Hashed_Sets is Capacity : Count_Type := 0; Modulus : Hash_Type := 0) return Set is - C : Count_Type; + C : constant Count_Type := + (if Capacity = 0 then Source.Length + else Capacity); M : Hash_Type; begin - if Capacity = 0 then - C := Source.Length; - elsif Capacity >= Source.Length then - C := Capacity; - elsif Checks then - raise Capacity_Error with "Capacity value too small"; + if Checks and then C < Source.Length then + raise Capacity_Error with "Capacity too small"; end if; if Modulus = 0 then diff --git a/gcc/ada/libgnat/a-cbmutr.adb b/gcc/ada/libgnat/a-cbmutr.adb index fb8585a..4c0f8fe 100644 --- a/gcc/ada/libgnat/a-cbmutr.adb +++ b/gcc/ada/libgnat/a-cbmutr.adb @@ -625,15 +625,12 @@ package body Ada.Containers.Bounded_Multiway_Trees is (Source : Tree; Capacity : Count_Type := 0) return Tree is - C : Count_Type; - + C : constant Count_Type := + (if Capacity = 0 then Source.Count + else Capacity); begin - if Capacity = 0 then - C := Source.Count; - elsif Capacity >= Source.Count then - C := Capacity; - elsif Checks then - raise Capacity_Error with "Capacity value too small"; + if Checks and then C < Source.Count then + raise Capacity_Error with "Capacity too small"; end if; return Target : Tree (Capacity => C) do diff --git a/gcc/ada/libgnat/a-cborma.adb b/gcc/ada/libgnat/a-cborma.adb index 55be7ad..e4e4b57 100644 --- a/gcc/ada/libgnat/a-cborma.adb +++ b/gcc/ada/libgnat/a-cborma.adb @@ -464,17 +464,12 @@ package body Ada.Containers.Bounded_Ordered_Maps is ---------- function Copy (Source : Map; Capacity : Count_Type := 0) return Map is - C : Count_Type; - + C : constant Count_Type := + (if Capacity = 0 then Source.Length + else Capacity); begin - if Capacity = 0 then - C := Source.Length; - - elsif Capacity >= Source.Length then - C := Capacity; - - elsif Checks then - raise Capacity_Error with "Capacity value too small"; + if Checks and then C < Source.Length then + raise Capacity_Error with "Capacity too small"; end if; return Target : Map (Capacity => C) do diff --git a/gcc/ada/libgnat/a-cborse.adb b/gcc/ada/libgnat/a-cborse.adb index 9fdba26..7b98378 100644 --- a/gcc/ada/libgnat/a-cborse.adb +++ b/gcc/ada/libgnat/a-cborse.adb @@ -442,15 +442,12 @@ package body Ada.Containers.Bounded_Ordered_Sets is ---------- function Copy (Source : Set; Capacity : Count_Type := 0) return Set is - C : Count_Type; - + C : constant Count_Type := + (if Capacity = 0 then Source.Length + else Capacity); begin - if Capacity = 0 then - C := Source.Length; - elsif Capacity >= Source.Length then - C := Capacity; - elsif Checks then - raise Capacity_Error with "Capacity value too small"; + if Checks and then C < Source.Length then + raise Capacity_Error with "Capacity too small"; end if; return Target : Set (Capacity => C) do diff --git a/gcc/ada/libgnat/a-cobove.adb b/gcc/ada/libgnat/a-cobove.adb index 8d80fb7..3e48bc6 100644 --- a/gcc/ada/libgnat/a-cobove.adb +++ b/gcc/ada/libgnat/a-cobove.adb @@ -451,18 +451,12 @@ package body Ada.Containers.Bounded_Vectors is (Source : Vector; Capacity : Count_Type := 0) return Vector is - C : Count_Type; - + C : constant Count_Type := + (if Capacity = 0 then Source.Length + else Capacity); begin - if Capacity = 0 then - C := Source.Length; - - elsif Capacity >= Source.Length then - C := Capacity; - - elsif Checks then - raise Capacity_Error - with "Requested capacity is less than Source length"; + if Checks and then C < Source.Length then + raise Capacity_Error with "Capacity too small"; end if; return Target : Vector (C) do diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cc27ca3..5e143b57 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-18 Bob Duff + + * gnat.dg/containers1.adb, gnat.dg/containers1.ads: New + testcase. + 2019-09-18 Richard Sandiford * gcc.target/i386/pr82361-1.c (f1, f2, f3, f4, f5, f6): Force diff --git a/gcc/testsuite/gnat.dg/containers1.adb b/gcc/testsuite/gnat.dg/containers1.adb new file mode 100644 index 0000000..47ac655 --- /dev/null +++ b/gcc/testsuite/gnat.dg/containers1.adb @@ -0,0 +1,5 @@ +-- { dg-do compile } +-- { dg-options "-Wall -O2" } +package body Containers1 is + procedure Dummy is null; +end Containers1; diff --git a/gcc/testsuite/gnat.dg/containers1.ads b/gcc/testsuite/gnat.dg/containers1.ads new file mode 100644 index 0000000..3c1fd89 --- /dev/null +++ b/gcc/testsuite/gnat.dg/containers1.ads @@ -0,0 +1,6 @@ +with Ada.Containers.Bounded_Ordered_Sets; use Ada.Containers; +package Containers1 is + pragma Suppress (All_Checks); + package Sets is new Bounded_Ordered_Sets (Boolean); + procedure Dummy; +end Containers1; \ No newline at end of file -- cgit v1.1 From aeb68a2b4729e5b918b996c0ab11d34466164cfb Mon Sep 17 00:00:00 2001 From: Arnaud Charlet Date: Wed, 18 Sep 2019 08:31:42 +0000 Subject: [Ada] System.Stack_Usage: fix a typo 2019-09-18 Arnaud Charlet gcc/ada/ * libgnat/s-stausa.adb: Fix a typo From-SVN: r275840 --- gcc/ada/ChangeLog | 4 ++++ gcc/ada/libgnat/s-stausa.adb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index d4c51d1..8ee1422 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,7 @@ +2019-09-18 Arnaud Charlet + + * libgnat/s-stausa.adb: Fix a typo + 2019-09-18 Bob Duff * libgnat/a-cbhama.adb, libgnat/a-cbhase.adb, diff --git a/gcc/ada/libgnat/s-stausa.adb b/gcc/ada/libgnat/s-stausa.adb index f93d1d9..597634a 100644 --- a/gcc/ada/libgnat/s-stausa.adb +++ b/gcc/ada/libgnat/s-stausa.adb @@ -42,7 +42,7 @@ package body System.Stack_Usage is -- Stack_Slots -- ----------------- - -- Stackl_Slots is an internal data type to represent a sequence of real + -- Stack_Slots is an internal data type to represent a sequence of real -- stack slots initialized with a provided pattern, with operations to -- abstract away the target call stack growth direction. -- cgit v1.1 From e58fc8977c671ebb4a50cc3170c3bc7988e3e99b Mon Sep 17 00:00:00 2001 From: Arnaud Charlet Date: Wed, 18 Sep 2019 08:31:46 +0000 Subject: [Ada] Remove remaining references to VMS support 2019-09-18 Arnaud Charlet gcc/ada/ * doc/gnat_rm/implementation_defined_characteristics.rst, doc/gnat_rm/implementation_defined_pragmas.rst, doc/gnat_rm/implementation_of_specific_ada_features.rst: Remove remaining references to VMS support * gnat_rm.texi: Regenerate. From-SVN: r275841 --- gcc/ada/ChangeLog | 8 ++++++++ .../doc/gnat_rm/implementation_defined_characteristics.rst | 5 ++--- gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst | 4 ++-- .../gnat_rm/implementation_of_specific_ada_features.rst | 3 --- gcc/ada/gnat_rm.texi | 14 +++++--------- 5 files changed, 17 insertions(+), 17 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 8ee1422..07221d3 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,5 +1,13 @@ 2019-09-18 Arnaud Charlet + * doc/gnat_rm/implementation_defined_characteristics.rst, + doc/gnat_rm/implementation_defined_pragmas.rst, + doc/gnat_rm/implementation_of_specific_ada_features.rst: Remove + remaining references to VMS support + * gnat_rm.texi: Regenerate. + +2019-09-18 Arnaud Charlet + * libgnat/s-stausa.adb: Fix a typo 2019-09-18 Bob Duff diff --git a/gcc/ada/doc/gnat_rm/implementation_defined_characteristics.rst b/gcc/ada/doc/gnat_rm/implementation_defined_characteristics.rst index 67ad7e7..a5425da 100644 --- a/gcc/ada/doc/gnat_rm/implementation_defined_characteristics.rst +++ b/gcc/ada/doc/gnat_rm/implementation_defined_characteristics.rst @@ -772,9 +772,8 @@ Convention Name Interpretation be present at all. This convention is useful during development for the inclusion of subprograms whose body has not yet been written. In addition, all otherwise unrecognized convention names are also - treated as being synonymous with convention C. In all implementations - except for VMS, use of such other names results in a warning. In VMS - implementations, these names are accepted silently. + treated as being synonymous with convention C. In all implementations, + use of such other names results in a warning. ======================= ============================================================================== * diff --git a/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst b/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst index 1498475..551401f 100644 --- a/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst +++ b/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst @@ -3254,7 +3254,7 @@ Ada exceptions, or used to implement run-time functions such as the Pragma ``Interrupt_State`` provides a general mechanism for overriding such uses of interrupts. It subsumes the functionality of pragma ``Unreserve_All_Interrupts``. Pragma ``Interrupt_State`` is not -available on Windows or VMS. On all other platforms than VxWorks, +available on Windows. On all other platforms than VxWorks, it applies to signals; on VxWorks, it applies to vectored hardware interrupts and may be used to mark interrupts required by the board support package as reserved. @@ -7689,7 +7689,7 @@ asterisks is similar in effect to specifying ``pragma Warnings (Off)`` except (i ``pragma Warnings (On, "***")`` will be required. This can be helpful in avoiding forgetting to turn warnings back on. -Note: the debug flag :switch:`-gnatd.i` (``/NOWARNINGS_PRAGMAS`` in VMS) can be +Note: the debug flag :switch:`-gnatd.i` can be used to cause the compiler to entirely ignore all WARNINGS pragmas. This can be useful in checking whether obsolete pragmas in existing programs are hiding real problems. diff --git a/gcc/ada/doc/gnat_rm/implementation_of_specific_ada_features.rst b/gcc/ada/doc/gnat_rm/implementation_of_specific_ada_features.rst index 3f55dc3..e818ab5 100644 --- a/gcc/ada/doc/gnat_rm/implementation_of_specific_ada_features.rst +++ b/gcc/ada/doc/gnat_rm/implementation_of_specific_ada_features.rst @@ -410,9 +410,6 @@ is created in the shared memory directory. This is used to provide the required locking semantics for proper protected object synchronization. -GNAT supports shared passive packages on all platforms -except for OpenVMS. - .. _Code_Generation_for_Array_Aggregates: Code Generation for Array Aggregates diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi index 23b822c..921dd16 100644 --- a/gcc/ada/gnat_rm.texi +++ b/gcc/ada/gnat_rm.texi @@ -21,7 +21,7 @@ @copying @quotation -GNAT Reference Manual , Sep 13, 2019 +GNAT Reference Manual , Sep 14, 2019 AdaCore @@ -4714,7 +4714,7 @@ Ada exceptions, or used to implement run-time functions such as the Pragma @code{Interrupt_State} provides a general mechanism for overriding such uses of interrupts. It subsumes the functionality of pragma @code{Unreserve_All_Interrupts}. Pragma @code{Interrupt_State} is not -available on Windows or VMS. On all other platforms than VxWorks, +available on Windows. On all other platforms than VxWorks, it applies to signals; on VxWorks, it applies to vectored hardware interrupts and may be used to mark interrupts required by the board support package as reserved. @@ -9187,7 +9187,7 @@ asterisks is similar in effect to specifying @code{pragma Warnings (Off)} except @code{pragma Warnings (On, "***")} will be required. This can be helpful in avoiding forgetting to turn warnings back on. -Note: the debug flag @code{-gnatd.i} (@code{/NOWARNINGS_PRAGMAS} in VMS) can be +Note: the debug flag @code{-gnatd.i} can be used to cause the compiler to entirely ignore all WARNINGS pragmas. This can be useful in checking whether obsolete pragmas in existing programs are hiding real problems. @@ -17249,9 +17249,8 @@ pragma @code{Import} specifies convention @code{stubbed} then no body need be present at all. This convention is useful during development for the inclusion of subprograms whose body has not yet been written. In addition, all otherwise unrecognized convention names are also -treated as being synonymous with convention C. In all implementations -except for VMS, use of such other names results in a warning. In VMS -implementations, these names are accepted silently. +treated as being synonymous with convention C. In all implementations, +use of such other names results in a warning. @end multitable @@ -26293,9 +26292,6 @@ is created in the shared memory directory. This is used to provide the required locking semantics for proper protected object synchronization. -GNAT supports shared passive packages on all platforms -except for OpenVMS. - @node Code Generation for Array Aggregates,The Size of Discriminated Records with Default Discriminants,GNAT Implementation of Shared Passive Packages,Implementation of Specific Ada Features @anchor{gnat_rm/implementation_of_specific_ada_features code-generation-for-array-aggregates}@anchor{422}@anchor{gnat_rm/implementation_of_specific_ada_features id7}@anchor{423} @section Code Generation for Array Aggregates -- cgit v1.1 From 6f934861c1eb93234e63483e04975bf0cd612da7 Mon Sep 17 00:00:00 2001 From: Arnaud Charlet Date: Wed, 18 Sep 2019 08:31:51 +0000 Subject: [Ada] Improve doc on Warning_As_Error 2019-09-18 Arnaud Charlet gcc/ada/ * doc/gnat_rm/implementation_defined_pragmas.rst: Improve doc on Warning_As_Error. * gnat_rm.texi: Regenerate. From-SVN: r275842 --- gcc/ada/ChangeLog | 6 ++++++ gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst | 6 ++++-- gcc/ada/gnat_rm.texi | 6 ++++-- 3 files changed, 14 insertions(+), 4 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 07221d3..77089cc 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,5 +1,11 @@ 2019-09-18 Arnaud Charlet + * doc/gnat_rm/implementation_defined_pragmas.rst: Improve doc on + Warning_As_Error. + * gnat_rm.texi: Regenerate. + +2019-09-18 Arnaud Charlet + * doc/gnat_rm/implementation_defined_characteristics.rst, doc/gnat_rm/implementation_defined_pragmas.rst, doc/gnat_rm/implementation_of_specific_ada_features.rst: Remove diff --git a/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst b/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst index 551401f..8ce22f1 100644 --- a/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst +++ b/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst @@ -7489,9 +7489,11 @@ message string (it is not necessary to put an asterisk at the start and the end of the message, since this is implied). Another possibility for the static_string_EXPRESSION which works whether -or not error tags are enabled (*-gnatw.d*) is to use the +or not error tags are enabled (*-gnatw.d*) is to use a single *-gnatw* tag string, enclosed in brackets, -as shown in the example below, to treat a class of warnings as errors. +as shown in the example below, to treat one category of warnings as errors. +Note that if you want to treat multiple categories of warnings as errors, +you can use multiple pragma Warning_As_Error. The above use of patterns to match the message applies only to warning messages generated by the front end. This pragma can also be applied to diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi index 921dd16..1f5616f 100644 --- a/gcc/ada/gnat_rm.texi +++ b/gcc/ada/gnat_rm.texi @@ -8994,9 +8994,11 @@ message string (it is not necessary to put an asterisk at the start and the end of the message, since this is implied). Another possibility for the static_string_EXPRESSION which works whether -or not error tags are enabled (@emph{-gnatw.d}) is to use the +or not error tags are enabled (@emph{-gnatw.d}) is to use a single @emph{-gnatw} tag string, enclosed in brackets, -as shown in the example below, to treat a class of warnings as errors. +as shown in the example below, to treat one category of warnings as errors. +Note that if you want to treat multiple categories of warnings as errors, +you can use multiple pragma Warning_As_Error. The above use of patterns to match the message applies only to warning messages generated by the front end. This pragma can also be applied to -- cgit v1.1 From 600db6ca89bc1f93d9f6f72c629e1c5d5c176068 Mon Sep 17 00:00:00 2001 From: Olivier Hainque Date: Wed, 18 Sep 2019 08:31:56 +0000 Subject: [Ada] Fix 32/64bit mistake on SYSTEM_INFO component in s-win32 The dwActiveProcessorMask field in a SYSTEM_INFO structure on Windows should be DWORD_PTR, an integer the size of a pointer. In s-win32, it is currently declared as DWORD. This happens to work on 32bit hosts and is wrong on 64bit hosts, causing mishaps in accesses to this component and all the following ones. The proposed correction adds a definition for DWORD_PTR and uses it for dwActiveProcessorMask in System.Win32.SYSTEM_INFO. 2019-09-18 Olivier Hainque gcc/ada/ * libgnat/s-win32.ads (DWORD_PTR): New type, pointer size unsigned int. (SYSTEM_INFO): Use it for dwActiveProcessorMask. gcc/testsuite/ * gnat.dg/system_info1.adb: New testcase. From-SVN: r275843 --- gcc/ada/ChangeLog | 6 ++++++ gcc/ada/libgnat/s-win32.ads | 21 +++++++++++---------- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gnat.dg/system_info1.adb | 23 +++++++++++++++++++++++ 4 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/system_info1.adb (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 77089cc..02628c9 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,9 @@ +2019-09-18 Olivier Hainque + + * libgnat/s-win32.ads (DWORD_PTR): New type, pointer size + unsigned int. + (SYSTEM_INFO): Use it for dwActiveProcessorMask. + 2019-09-18 Arnaud Charlet * doc/gnat_rm/implementation_defined_pragmas.rst: Improve doc on diff --git a/gcc/ada/libgnat/s-win32.ads b/gcc/ada/libgnat/s-win32.ads index ab832cd..853cef0 100644 --- a/gcc/ada/libgnat/s-win32.ads +++ b/gcc/ada/libgnat/s-win32.ads @@ -57,15 +57,16 @@ package System.Win32 is INVALID_HANDLE_VALUE : constant HANDLE := -1; INVALID_FILE_SIZE : constant := 16#FFFFFFFF#; - type ULONG is new Interfaces.C.unsigned_long; - type DWORD is new Interfaces.C.unsigned_long; - type WORD is new Interfaces.C.unsigned_short; - type BYTE is new Interfaces.C.unsigned_char; - type LONG is new Interfaces.C.long; - type CHAR is new Interfaces.C.char; - type SIZE_T is new Interfaces.C.size_t; - - type BOOL is new Interfaces.C.int; + type ULONG is new Interfaces.C.unsigned_long; + type DWORD is new Interfaces.C.unsigned_long; + type WORD is new Interfaces.C.unsigned_short; + type BYTE is new Interfaces.C.unsigned_char; + type LONG is new Interfaces.C.long; + type CHAR is new Interfaces.C.char; + type SIZE_T is new Interfaces.C.size_t; + type DWORD_PTR is mod 2 ** Standard'Address_Size; + + type BOOL is new Interfaces.C.int; for BOOL'Size use Interfaces.C.int'Size; type Bits1 is range 0 .. 2 ** 1 - 1; @@ -265,7 +266,7 @@ package System.Win32 is dwPageSize : DWORD; lpMinimumApplicationAddress : PVOID; lpMaximumApplicationAddress : PVOID; - dwActiveProcessorMask : DWORD; + dwActiveProcessorMask : DWORD_PTR; dwNumberOfProcessors : DWORD; dwProcessorType : DWORD; dwAllocationGranularity : DWORD; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5e143b57..1db62e2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-09-18 Olivier Hainque + + * gnat.dg/system_info1.adb: New testcase. + 2019-09-18 Bob Duff * gnat.dg/containers1.adb, gnat.dg/containers1.ads: New diff --git a/gcc/testsuite/gnat.dg/system_info1.adb b/gcc/testsuite/gnat.dg/system_info1.adb new file mode 100644 index 0000000..493a18e --- /dev/null +++ b/gcc/testsuite/gnat.dg/system_info1.adb @@ -0,0 +1,23 @@ +-- { dg-do run } + +with System.Multiprocessors; +with System.Task_Info; + +procedure System_Info1 is + Ncpus : constant System.Multiprocessors.CPU := + System.Multiprocessors.Number_Of_CPUS; + Nprocs : constant Integer := + System.Task_Info.Number_Of_Processors; + + use type System.Multiprocessors.CPU; +begin + if Nprocs <= 0 or else Nprocs > 1024 then + raise Program_Error; + end if; + if Ncpus <= 0 or else Ncpus > 1024 then + raise Program_Error; + end if; + if Nprocs /= Integer (Ncpus) then + raise Program_Error; + end if; +end; \ No newline at end of file -- cgit v1.1 From e42183e72bf600aff07cdf051c2166d36fb1889d Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Wed, 18 Sep 2019 08:32:00 +0000 Subject: [Ada] Fix typo in error message An error message mentions "gnamake", where it meant to mention "gnatmake". 2019-09-18 Tom Tromey gcc/ada/ * make.adb (Initialize): Fix typo. From-SVN: r275844 --- gcc/ada/ChangeLog | 4 ++++ gcc/ada/make.adb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 02628c9..c13fa24 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,7 @@ +2019-09-18 Tom Tromey + + * make.adb (Initialize): Fix typo. + 2019-09-18 Olivier Hainque * libgnat/s-win32.ads (DWORD_PTR): New type, pointer size diff --git a/gcc/ada/make.adb b/gcc/ada/make.adb index 3c9df7e..377072c 100644 --- a/gcc/ada/make.adb +++ b/gcc/ada/make.adb @@ -3789,7 +3789,7 @@ package body Make is if Gprbuild = null then Fail_Program - ("project files are no longer supported by gnamake;" & + ("project files are no longer supported by gnatmake;" & " use gprbuild instead"); end if; -- cgit v1.1 From dcbe49a6c41e586e961664512726799a540757ee Mon Sep 17 00:00:00 2001 From: Steve Baird Date: Wed, 18 Sep 2019 08:32:05 +0000 Subject: [Ada] No Storage_Error for an oversized disabled ghost array object In some cases where the size computation for an object declaration will unconditionally overflow, the FE generates code to raise Storage_Error at the point of the object declaration (and may generate an associated warning). Don't do this if the object declaration is an ignored (i.e., disabled) ghost declaration. 2019-09-18 Steve Baird gcc/ada/ * freeze.adb (Freeze_Object_Declaration): Do not call Check_Large_Modular_Array when the object declaration being frozen is an ignored ghost entity. gcc/testsuite/ * gnat.dg/ghost7.adb, gnat.dg/ghost7.ads: New testcase. From-SVN: r275845 --- gcc/ada/ChangeLog | 6 ++++++ gcc/ada/freeze.adb | 3 ++- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gnat.dg/ghost7.adb | 6 ++++++ gcc/testsuite/gnat.dg/ghost7.ads | 8 ++++++++ 5 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gnat.dg/ghost7.adb create mode 100644 gcc/testsuite/gnat.dg/ghost7.ads (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index c13fa24..0c1c554 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,9 @@ +2019-09-18 Steve Baird + + * freeze.adb (Freeze_Object_Declaration): Do not call + Check_Large_Modular_Array when the object declaration being + frozen is an ignored ghost entity. + 2019-09-18 Tom Tromey * make.adb (Initialize): Fix typo. diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb index bb17e42..93e91b2 100644 --- a/gcc/ada/freeze.adb +++ b/gcc/ada/freeze.adb @@ -3569,7 +3569,8 @@ package body Freeze is Error_Msg_N ("\??use explicit size clause to set size", E); end if; - if Is_Array_Type (Typ) then + -- Declaring a too-big array in disabled ghost code is OK + if Is_Array_Type (Typ) and then not Is_Ignored_Ghost_Entity (E) then Check_Large_Modular_Array (Typ); end if; end Freeze_Object_Declaration; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1db62e2..c3f82a5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-09-18 Steve Baird + + * gnat.dg/ghost7.adb, gnat.dg/ghost7.ads: New testcase. + 2019-09-18 Olivier Hainque * gnat.dg/system_info1.adb: New testcase. diff --git a/gcc/testsuite/gnat.dg/ghost7.adb b/gcc/testsuite/gnat.dg/ghost7.adb new file mode 100644 index 0000000..977cdd2 --- /dev/null +++ b/gcc/testsuite/gnat.dg/ghost7.adb @@ -0,0 +1,6 @@ +-- { dg-do compile } +-- { dg-options "-gnatwa" } + +package body Ghost7 is + procedure Dummy is null; +end Ghost7; diff --git a/gcc/testsuite/gnat.dg/ghost7.ads b/gcc/testsuite/gnat.dg/ghost7.ads new file mode 100644 index 0000000..4042aa3 --- /dev/null +++ b/gcc/testsuite/gnat.dg/ghost7.ads @@ -0,0 +1,8 @@ +pragma Restrictions (No_Exception_Propagation); + +package Ghost7 is + type Word64 is mod 2**64; + type My_Array_Type is array (Word64) of Boolean; + My_Array : My_Array_Type with Ghost; + procedure Dummy; +end Ghost7; \ No newline at end of file -- cgit v1.1 From 82fa20a21141a1394d7188b21eb9c486ab16f8ea Mon Sep 17 00:00:00 2001 From: Frederic Konrad Date: Wed, 18 Sep 2019 08:32:09 +0000 Subject: [Ada] Fix errno for rename for the VxWorks 6 target This fixes the wrong errno for rename when the file is not existing on a dosFs. In the end it makes Ada.Directories.Rename raising the right exception in the case we are trying to move a file in a non existing directory. 2019-09-18 Frederic Konrad gcc/ada/ * adaint.c: Include dosFsLib.h and vwModNum.h for VxWorks 6. (__gnat_rename): Map S_dosFsLib_FILE_NOT_FOUND to ENOENT. From-SVN: r275846 --- gcc/ada/ChangeLog | 5 +++++ gcc/ada/adaint.c | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 0c1c554..38c5a7e 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,8 @@ +2019-09-18 Frederic Konrad + + * adaint.c: Include dosFsLib.h and vwModNum.h for VxWorks 6. + (__gnat_rename): Map S_dosFsLib_FILE_NOT_FOUND to ENOENT. + 2019-09-18 Steve Baird * freeze.adb (Freeze_Object_Declaration): Do not call diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c index c76e9ad..595abf8 100644 --- a/gcc/ada/adaint.c +++ b/gcc/ada/adaint.c @@ -74,6 +74,12 @@ (such as chmod) are only available on VxWorks 6. */ #include "version.h" +/* vwModNum.h and dosFsLib.h are needed for the VxWorks 6 rename workaround. + See below. */ +#if (_WRS_VXWORKS_MAJOR == 6) +#include +#include +#endif /* 6.x */ #endif /* VxWorks */ #if defined (__APPLE__) @@ -754,6 +760,20 @@ __gnat_rename (char *from, char *to) S2WSC (wto, to, GNAT_MAX_PATH_LEN); return _trename (wfrom, wto); } +#elif defined (__vxworks) && (_WRS_VXWORKS_MAJOR == 6) + { + /* When used on a dos filesystem under VxWorks 6.9 rename will trigger a + S_dosFsLib_FILE_NOT_FOUND errno when the file is not found. Let's map + that to ENOENT so Ada.Directory.Rename can detect that and raise the + Name_Error exception. */ + int ret = rename (from, to); + + if (ret && (errno == S_dosFsLib_FILE_NOT_FOUND)) + { + errno = ENOENT; + } + return ret; + } #else return rename (from, to); #endif -- cgit v1.1 From 209a0094c4b1a8603b73beb77f28ea6c314d5875 Mon Sep 17 00:00:00 2001 From: Vadim Godunko Date: Wed, 18 Sep 2019 08:32:14 +0000 Subject: [Ada] Raise exception on call to Expect for a dead process Call to Expect for a dead process results in SIGBUS signal on Linux systems. Process_Died exception is raised in this case now. 2019-09-18 Vadim Godunko gcc/ada/ * libgnat/g-expect.adb (Expect_Internal): Don't include invalid file descriptors into the set of file descriptors for Poll. Raise Process_Died exception when computed set of file descriptors to monitor is empty. gcc/testsuite/ * gnat.dg/expect4.adb: New testcase. From-SVN: r275847 --- gcc/ada/ChangeLog | 7 +++++++ gcc/ada/libgnat/g-expect.adb | 12 +++++++++++- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gnat.dg/expect4.adb | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gnat.dg/expect4.adb (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 38c5a7e..b110539 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,10 @@ +2019-09-18 Vadim Godunko + + * libgnat/g-expect.adb (Expect_Internal): Don't include invalid + file descriptors into the set of file descriptors for Poll. + Raise Process_Died exception when computed set of file + descriptors to monitor is empty. + 2019-09-18 Frederic Konrad * adaint.c: Include dosFsLib.h and vwModNum.h for VxWorks 6. diff --git a/gcc/ada/libgnat/g-expect.adb b/gcc/ada/libgnat/g-expect.adb index 0ee010e..4efd98d 100644 --- a/gcc/ada/libgnat/g-expect.adb +++ b/gcc/ada/libgnat/g-expect.adb @@ -653,7 +653,9 @@ package body GNAT.Expect is begin for J in Descriptors'Range loop - if Descriptors (J) /= null then + if Descriptors (J) /= null + and then Descriptors (J).Output_Fd /= Invalid_FD + then Fds (Fds'First + Fds_Count) := Descriptors (J).Output_Fd; Fds_To_Descriptor (Fds'First + Fds_Count) := J; Fds_Count := Fds_Count + 1; @@ -667,6 +669,14 @@ package body GNAT.Expect is end if; end loop; + if Fds_Count = 0 then + -- There are no descriptors to monitor, it means that process died. + + Result := Expect_Process_Died; + + return; + end if; + declare Buffer : aliased String (1 .. Buffer_Size); -- Buffer used for input. This is allocated only once, not for diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c3f82a5..e0ac529 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-09-18 Vadim Godunko + + * gnat.dg/expect4.adb: New testcase. + 2019-09-18 Steve Baird * gnat.dg/ghost7.adb, gnat.dg/ghost7.ads: New testcase. diff --git a/gcc/testsuite/gnat.dg/expect4.adb b/gcc/testsuite/gnat.dg/expect4.adb new file mode 100644 index 0000000..7a974cc --- /dev/null +++ b/gcc/testsuite/gnat.dg/expect4.adb @@ -0,0 +1,35 @@ +-- { dg-do run } + +with GNAT.Expect.TTY; +with GNAT.OS_Lib; + +procedure Expect4 is + Pid : GNAT.Expect.TTY.TTY_Process_Descriptor; + Args : GNAT.OS_Lib.Argument_List (1 .. 0); + Result : GNAT.Expect.Expect_Match; + +begin + Pid.Non_Blocking_Spawn ("true", Args); + + begin + Pid.Expect (Result, ".*"); + + raise Program_Error; + + exception + when GNAT.Expect.Process_Died => + null; + end; + + begin + Pid.Expect (Result, ".*"); + + raise Program_Error; + + exception + when GNAT.Expect.Process_Died => + null; + end; + + Pid.Close; +end Expect4; \ No newline at end of file -- cgit v1.1 From d2880e695410cf607d77be03908d7107e41a5271 Mon Sep 17 00:00:00 2001 From: Claire Dross Date: Wed, 18 Sep 2019 08:32:19 +0000 Subject: [Ada] Factor out code for deciding statically known Constrained attributes Create a separate routine in Exp_Util for deciding the value of the Constrained attribute when it is statically known. This routine is used in Exp_Attr and will be reused in the backend of GNATprove. There is no impact on compilation and hence no test. 2019-09-18 Claire Dross gcc/ada/ * exp_attr.adb (Expand_N_Attribute_Reference): Call routine from Exp_Util to know the value of the Constrained attribute in the static case. * exp_spark.adb (Expand_SPARK_N_Attribute_Reference): Make implicit dereferences inside the Constrained attribute explicit. * exp_util.ads, exp_util.adb (Attribute_Constrained_Static_Value): New routine to compute the value of a statically known reference to the Constrained attribute. From-SVN: r275848 --- gcc/ada/ChangeLog | 12 ++++ gcc/ada/exp_attr.adb | 152 ++++------------------------------------------ gcc/ada/exp_spark.adb | 15 +++++ gcc/ada/exp_util.adb | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++ gcc/ada/exp_util.ads | 4 ++ 5 files changed, 208 insertions(+), 139 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index b110539..b5c319b 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,15 @@ +2019-09-18 Claire Dross + + * exp_attr.adb (Expand_N_Attribute_Reference): Call routine from + Exp_Util to know the value of the Constrained attribute in the + static case. + * exp_spark.adb (Expand_SPARK_N_Attribute_Reference): Make + implicit dereferences inside the Constrained attribute explicit. + * exp_util.ads, exp_util.adb + (Attribute_Constrained_Static_Value): New routine to compute the + value of a statically known reference to the Constrained + attribute. + 2019-09-18 Vadim Godunko * libgnat/g-expect.adb (Expect_Internal): Don't include invalid diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb index c5ff9b5..a8e68bb 100644 --- a/gcc/ada/exp_attr.adb +++ b/gcc/ada/exp_attr.adb @@ -2770,40 +2770,6 @@ package body Exp_Attr is when Attribute_Constrained => Constrained : declare Formal_Ent : constant Entity_Id := Param_Entity (Pref); - function Is_Constrained_Aliased_View (Obj : Node_Id) return Boolean; - -- Ada 2005 (AI-363): Returns True if the object name Obj denotes a - -- view of an aliased object whose subtype is constrained. - - --------------------------------- - -- Is_Constrained_Aliased_View -- - --------------------------------- - - function Is_Constrained_Aliased_View (Obj : Node_Id) return Boolean is - E : Entity_Id; - - begin - if Is_Entity_Name (Obj) then - E := Entity (Obj); - - if Present (Renamed_Object (E)) then - return Is_Constrained_Aliased_View (Renamed_Object (E)); - else - return Is_Aliased (E) and then Is_Constrained (Etype (E)); - end if; - - else - return Is_Aliased_View (Obj) - and then - (Is_Constrained (Etype (Obj)) - or else - (Nkind (Obj) = N_Explicit_Dereference - and then - not Object_Type_Has_Constrained_Partial_View - (Typ => Base_Type (Etype (Obj)), - Scop => Current_Scope))); - end if; - end Is_Constrained_Aliased_View; - -- Start of processing for Constrained begin @@ -2844,115 +2810,23 @@ package body Exp_Attr is New_Occurrence_Of (Extra_Constrained (Entity (Pref)), Sloc (N))); - -- For all other entity names, we can tell at compile time + -- For all other cases, we can tell at compile time - elsif Is_Entity_Name (Pref) then - declare - Ent : constant Entity_Id := Entity (Pref); - Res : Boolean; - - begin - -- (RM J.4) obsolescent cases - - if Is_Type (Ent) then - - -- Private type - - if Is_Private_Type (Ent) then - Res := not Has_Discriminants (Ent) - or else Is_Constrained (Ent); - - -- It not a private type, must be a generic actual type - -- that corresponded to a private type. We know that this - -- correspondence holds, since otherwise the reference - -- within the generic template would have been illegal. - - else - if Is_Composite_Type (Underlying_Type (Ent)) then - Res := Is_Constrained (Ent); - else - Res := True; - end if; - end if; - - else - -- For access type, apply access check as needed - - if Is_Access_Type (Ptyp) then - Apply_Access_Check (N); - end if; - - -- If the prefix is not a variable or is aliased, then - -- definitely true; if it's a formal parameter without an - -- associated extra formal, then treat it as constrained. - - -- Ada 2005 (AI-363): An aliased prefix must be known to be - -- constrained in order to set the attribute to True. - - if not Is_Variable (Pref) - or else Present (Formal_Ent) - or else (Ada_Version < Ada_2005 - and then Is_Aliased_View (Pref)) - or else (Ada_Version >= Ada_2005 - and then Is_Constrained_Aliased_View (Pref)) - then - Res := True; - - -- Variable case, look at type to see if it is constrained. - -- Note that the one case where this is not accurate (the - -- procedure formal case), has been handled above. - - -- We use the Underlying_Type here (and below) in case the - -- type is private without discriminants, but the full type - -- has discriminants. This case is illegal, but we generate - -- it internally for passing to the Extra_Constrained - -- parameter. - - else - -- In Ada 2012, test for case of a limited tagged type, - -- in which case the attribute is always required to - -- return True. The underlying type is tested, to make - -- sure we also return True for cases where there is an - -- unconstrained object with an untagged limited partial - -- view which has defaulted discriminants (such objects - -- always produce a False in earlier versions of - -- Ada). (Ada 2012: AI05-0214) - - Res := - Is_Constrained (Underlying_Type (Etype (Ent))) - or else - (Ada_Version >= Ada_2012 - and then Is_Tagged_Type (Underlying_Type (Ptyp)) - and then Is_Limited_Type (Ptyp)); - end if; - end if; - - Rewrite (N, New_Occurrence_Of (Boolean_Literals (Res), Loc)); - end; + else + -- For access type, apply access check as needed - -- Prefix is not an entity name. These are also cases where we can - -- always tell at compile time by looking at the form and type of the - -- prefix. If an explicit dereference of an object with constrained - -- partial view, this is unconstrained (Ada 2005: AI95-0363). If the - -- underlying type is a limited tagged type, then Constrained is - -- required to always return True (Ada 2012: AI05-0214). + if Is_Entity_Name (Pref) + and then not Is_Type (Entity (Pref)) + and then Is_Access_Type (Ptyp) + then + Apply_Access_Check (N); + end if; - else Rewrite (N, - New_Occurrence_Of ( - Boolean_Literals ( - not Is_Variable (Pref) - or else - (Nkind (Pref) = N_Explicit_Dereference - and then - not Object_Type_Has_Constrained_Partial_View - (Typ => Base_Type (Ptyp), - Scop => Current_Scope)) - or else Is_Constrained (Underlying_Type (Ptyp)) - or else (Ada_Version >= Ada_2012 - and then Is_Tagged_Type (Underlying_Type (Ptyp)) - and then Is_Limited_Type (Ptyp))), - Loc)); + New_Occurrence_Of + (Boolean_Literals + (Exp_Util.Attribute_Constrained_Static_Value + (Pref)), Sloc (N))); end if; Analyze_And_Resolve (N, Standard_Boolean); diff --git a/gcc/ada/exp_spark.adb b/gcc/ada/exp_spark.adb index e64babe..28484aa 100644 --- a/gcc/ada/exp_spark.adb +++ b/gcc/ada/exp_spark.adb @@ -176,6 +176,7 @@ package body Exp_SPARK is Aname : constant Name_Id := Attribute_Name (N); Attr_Id : constant Attribute_Id := Get_Attribute_Id (Aname); Loc : constant Source_Ptr := Sloc (N); + Pref : constant Node_Id := Prefix (N); Typ : constant Entity_Id := Etype (N); Expr : Node_Id; @@ -302,6 +303,20 @@ package body Exp_SPARK is Set_Do_Overflow_Check (N); end if; end; + + elsif Attr_Id = Attribute_Constrained then + + -- If the prefix is an access to object, the attribute applies to + -- the designated object, so rewrite with an explicit dereference. + + if Is_Access_Type (Etype (Pref)) + and then + (not Is_Entity_Name (Pref) or else Is_Object (Entity (Pref))) + then + Rewrite (Pref, + Make_Explicit_Dereference (Loc, Relocate_Node (Pref))); + Analyze_And_Resolve (N, Standard_Boolean); + end if; end if; end Expand_SPARK_N_Attribute_Reference; diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb index c3c5e79..06f5cc3 100644 --- a/gcc/ada/exp_util.adb +++ b/gcc/ada/exp_util.adb @@ -32,6 +32,7 @@ with Einfo; use Einfo; with Elists; use Elists; with Errout; use Errout; with Exp_Aggr; use Exp_Aggr; +with Exp_Ch2; use Exp_Ch2; with Exp_Ch6; use Exp_Ch6; with Exp_Ch7; use Exp_Ch7; with Exp_Ch11; use Exp_Ch11; @@ -472,6 +473,169 @@ package body Exp_Util is end if; end Append_Freeze_Actions; + -------------------------------------- + -- Attr_Constrained_Statically_True -- + -------------------------------------- + + function Attribute_Constrained_Static_Value (Pref : Node_Id) return Boolean + is + Ptyp : constant Entity_Id := Etype (Pref); + Formal_Ent : constant Entity_Id := Param_Entity (Pref); + + function Is_Constrained_Aliased_View (Obj : Node_Id) return Boolean; + -- Ada 2005 (AI-363): Returns True if the object name Obj denotes a + -- view of an aliased object whose subtype is constrained. + + --------------------------------- + -- Is_Constrained_Aliased_View -- + --------------------------------- + + function Is_Constrained_Aliased_View (Obj : Node_Id) return Boolean is + E : Entity_Id; + + begin + if Is_Entity_Name (Obj) then + E := Entity (Obj); + + if Present (Renamed_Object (E)) then + return Is_Constrained_Aliased_View (Renamed_Object (E)); + else + return Is_Aliased (E) and then Is_Constrained (Etype (E)); + end if; + + else + return Is_Aliased_View (Obj) + and then + (Is_Constrained (Etype (Obj)) + or else + (Nkind (Obj) = N_Explicit_Dereference + and then + not Object_Type_Has_Constrained_Partial_View + (Typ => Base_Type (Etype (Obj)), + Scop => Current_Scope))); + end if; + end Is_Constrained_Aliased_View; + + -- Start of processing for Attribute_Constrained_Static_Value + + begin + -- We are in a case where the attribute is known statically, and + -- implicit dereferences have been rewritten. + + pragma Assert + (not (Present (Formal_Ent) + and then Ekind (Formal_Ent) /= E_Constant + and then Present (Extra_Constrained (Formal_Ent))) + and then + not (Is_Access_Type (Etype (Pref)) + and then (not Is_Entity_Name (Pref) + or else Is_Object (Entity (Pref)))) + and then + not (Nkind (Pref) = N_Identifier + and then Ekind (Entity (Pref)) = E_Variable + and then Present (Extra_Constrained (Entity (Pref))))); + + if Is_Entity_Name (Pref) then + declare + Ent : constant Entity_Id := Entity (Pref); + Res : Boolean; + + begin + -- (RM J.4) obsolescent cases + + if Is_Type (Ent) then + + -- Private type + + if Is_Private_Type (Ent) then + Res := not Has_Discriminants (Ent) + or else Is_Constrained (Ent); + + -- It not a private type, must be a generic actual type + -- that corresponded to a private type. We know that this + -- correspondence holds, since otherwise the reference + -- within the generic template would have been illegal. + + else + if Is_Composite_Type (Underlying_Type (Ent)) then + Res := Is_Constrained (Ent); + else + Res := True; + end if; + end if; + + else + + -- If the prefix is not a variable or is aliased, then + -- definitely true; if it's a formal parameter without an + -- associated extra formal, then treat it as constrained. + + -- Ada 2005 (AI-363): An aliased prefix must be known to be + -- constrained in order to set the attribute to True. + + if not Is_Variable (Pref) + or else Present (Formal_Ent) + or else (Ada_Version < Ada_2005 + and then Is_Aliased_View (Pref)) + or else (Ada_Version >= Ada_2005 + and then Is_Constrained_Aliased_View (Pref)) + then + Res := True; + + -- Variable case, look at type to see if it is constrained. + -- Note that the one case where this is not accurate (the + -- procedure formal case), has been handled above. + + -- We use the Underlying_Type here (and below) in case the + -- type is private without discriminants, but the full type + -- has discriminants. This case is illegal, but we generate + -- it internally for passing to the Extra_Constrained + -- parameter. + + else + -- In Ada 2012, test for case of a limited tagged type, + -- in which case the attribute is always required to + -- return True. The underlying type is tested, to make + -- sure we also return True for cases where there is an + -- unconstrained object with an untagged limited partial + -- view which has defaulted discriminants (such objects + -- always produce a False in earlier versions of + -- Ada). (Ada 2012: AI05-0214) + + Res := + Is_Constrained (Underlying_Type (Etype (Ent))) + or else + (Ada_Version >= Ada_2012 + and then Is_Tagged_Type (Underlying_Type (Ptyp)) + and then Is_Limited_Type (Ptyp)); + end if; + end if; + + return Res; + end; + + -- Prefix is not an entity name. These are also cases where we can + -- always tell at compile time by looking at the form and type of the + -- prefix. If an explicit dereference of an object with constrained + -- partial view, this is unconstrained (Ada 2005: AI95-0363). If the + -- underlying type is a limited tagged type, then Constrained is + -- required to always return True (Ada 2012: AI05-0214). + + else + return not Is_Variable (Pref) + or else + (Nkind (Pref) = N_Explicit_Dereference + and then + not Object_Type_Has_Constrained_Partial_View + (Typ => Base_Type (Ptyp), + Scop => Current_Scope)) + or else Is_Constrained (Underlying_Type (Ptyp)) + or else (Ada_Version >= Ada_2012 + and then Is_Tagged_Type (Underlying_Type (Ptyp)) + and then Is_Limited_Type (Ptyp)); + end if; + end Attribute_Constrained_Static_Value; + ------------------------------------ -- Build_Allocate_Deallocate_Proc -- ------------------------------------ diff --git a/gcc/ada/exp_util.ads b/gcc/ada/exp_util.ads index 30a3c71..ab33e8d 100644 --- a/gcc/ada/exp_util.ads +++ b/gcc/ada/exp_util.ads @@ -240,6 +240,10 @@ package Exp_Util is -- Note that the added nodes are not analyzed. The analyze call is found in -- Exp_Ch13.Expand_N_Freeze_Entity. + function Attribute_Constrained_Static_Value (Pref : Node_Id) return Boolean; + -- Return the static value of a statically known attribute reference + -- Pref'Constrained. + procedure Build_Allocate_Deallocate_Proc (N : Node_Id; Is_Allocate : Boolean); -- cgit v1.1 From b67723ddeea0206e68f122a26b1a7b46382b79e7 Mon Sep 17 00:00:00 2001 From: Nicolas Roche Date: Wed, 18 Sep 2019 08:32:23 +0000 Subject: [Ada] Ensure that Scan_Real result does not depend on trailing zeros Previous change in that procedure to handle overflow issues during scanning removed the special handling for trailing zeros in the decimal part. Beside the absence of overflow during scanning the special handling of these zeros is still necessary. 2019-09-18 Nicolas Roche gcc/ada/ * libgnat/s-valrea.adb (Scan_Integral_Digits): New procedure. (Scan_Decimal_Digits): New procedure. (As_Digit): New function. (Scan_Real): Use Scan_Integral_Digits and Scan_Decimal_Digits. gcc/testsuite/ * gnat.dg/float_value2.adb: New testcase. From-SVN: r275849 --- gcc/ada/ChangeLog | 7 + gcc/ada/libgnat/s-valrea.adb | 652 ++++++++++++++++++++------------- gcc/testsuite/ChangeLog | 4 + gcc/testsuite/gnat.dg/float_value2.adb | 10 + 4 files changed, 409 insertions(+), 264 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/float_value2.adb (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index b5c319b..e77725c 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,10 @@ +2019-09-18 Nicolas Roche + + * libgnat/s-valrea.adb (Scan_Integral_Digits): New procedure. + (Scan_Decimal_Digits): New procedure. + (As_Digit): New function. + (Scan_Real): Use Scan_Integral_Digits and Scan_Decimal_Digits. + 2019-09-18 Claire Dross * exp_attr.adb (Expand_N_Attribute_Reference): Call routine from diff --git a/gcc/ada/libgnat/s-valrea.adb b/gcc/ada/libgnat/s-valrea.adb index 99c7360..519e369 100644 --- a/gcc/ada/libgnat/s-valrea.adb +++ b/gcc/ada/libgnat/s-valrea.adb @@ -29,346 +29,469 @@ -- -- ------------------------------------------------------------------------------ -with System.Powten_Table; use System.Powten_Table; with System.Val_Util; use System.Val_Util; with System.Float_Control; package body System.Val_Real is - --------------- - -- Scan_Real -- - --------------- + procedure Scan_Integral_Digits + (Str : String; + Index : in out Integer; + Max : Integer; + Value : out Long_Long_Integer; + Scale : out Integer; + Base_Violation : in out Boolean; + Base : Long_Long_Integer := 10; + Base_Specified : Boolean := False); + -- Scan the integral part of a real (i.e: before decimal separator) + -- + -- The string parsed is Str (Index .. Max), and after the call Index will + -- point to the first non parsed character. + -- + -- For each digit parsed either value := value * base + digit, or scale + -- is incremented by 1. + -- + -- Base_Violation will be set to True a digit found is not part of the Base + + procedure Scan_Decimal_Digits + (Str : String; + Index : in out Integer; + Max : Integer; + Value : in out Long_Long_Integer; + Scale : in out Integer; + Base_Violation : in out Boolean; + Base : Long_Long_Integer := 10; + Base_Specified : Boolean := False); + -- Scan the decimal part of a real (i.e: after decimal separator) + -- + -- The string parsed is Str (Index .. Max), and after the call Index will + -- point to the first non parsed character. + -- + -- For each digit parsed value = value * base + digit and scale is + -- decremented by 1. If precision limit is reached remaining digits are + -- still parsed but ignored. + -- + -- Base_Violation will be set to True a digit found is not part of the Base + + subtype Char_As_Digit is Long_Long_Integer range -2 .. 15; + subtype Valid_Digit is Char_As_Digit range 0 .. Char_As_Digit'Last; + Underscore : constant Char_As_Digit := -2; + E_Digit : constant Char_As_Digit := 14; + + function As_Digit (C : Character) return Char_As_Digit; + -- Given a character return the digit it represent. If the character is + -- not a digit then a negative value is returned, -2 for underscore and + -- -1 for any other character. + + Precision_Limit : constant Long_Long_Integer := + 2 ** (Long_Long_Float'Machine_Mantissa - 1) - 1; + -- This is an upper bound for the number of bits used to represent the + -- mantissa. Beyond that number, any digits parsed are useless. + + -------------- + -- As_Digit -- + -------------- + + function As_Digit (C : Character) return Char_As_Digit + is + begin + case C is + when '0' .. '9' => + return Character'Pos (C) - Character'Pos ('0'); + when 'a' .. 'f' => + return Character'Pos (C) - (Character'Pos ('a') - 10); + when 'A' .. 'F' => + return Character'Pos (C) - (Character'Pos ('A') - 10); + when '_' => + return Underscore; + when others => + return -1; + end case; + end As_Digit; + + ------------------------- + -- Scan_Decimal_Digits -- + ------------------------- + + procedure Scan_Decimal_Digits + (Str : String; + Index : in out Integer; + Max : Integer; + Value : in out Long_Long_Integer; + Scale : in out Integer; + Base_Violation : in out Boolean; + Base : Long_Long_Integer := 10; + Base_Specified : Boolean := False) - function Scan_Real - (Str : String; - Ptr : not null access Integer; - Max : Integer) return Long_Long_Float is - P : Integer; - -- Local copy of string pointer + Precision_Limit_Reached : Boolean := False; + -- Set to True if addition of a digit will cause Value to be superior + -- to Precision_Limit. - Base : Long_Long_Float; - -- Base value + Digit : Char_As_Digit; + -- The current digit. - Uval : Long_Long_Float; - -- Accumulated float result + Trailing_Zeros : Natural := 0; + -- Number of trailing zeros at a given point. + begin - subtype Digs is Character range '0' .. '9'; - -- Used to check for decimal digit + -- If initial Scale is not 0 then it means that Precision_Limit was + -- reached during integral part scanning. + if Scale > 0 then + Precision_Limit_Reached := True; + end if; - Scale : Integer := 0; - -- Power of Base to multiply result by + -- The function precondition is that the first character is a valid + -- digit. + Digit := As_Digit (Str (Index)); + + loop + -- Check if base is correct. If the base is not specified the digit + -- E or e cannot be considered as a base violation as it can be used + -- for exponentiation. + if Digit >= Base then + if Base_Specified then + Base_Violation := True; + elsif Digit = E_Digit then + return; + else + Base_Violation := True; + end if; + end if; - Start : Positive; - -- Position of starting non-blank character + -- If precision limit has been reached just ignore any remaining + -- digits for the computation of Value and Scale. The scanning + -- should continue only to assess the validity of the string + if not Precision_Limit_Reached then + if Digit = 0 then + -- Trailing '0' digits are ignored unless a non-zero digit is + -- found. + Trailing_Zeros := Trailing_Zeros + 1; + else - Minus : Boolean; - -- Set to True if minus sign is present, otherwise to False + -- Handle accumulated zeros. + for J in 1 .. Trailing_Zeros loop + if Value > Precision_Limit / Base then + Precision_Limit_Reached := True; + exit; + else + Value := Value * Base; + Scale := Scale - 1; + end if; + end loop; - Bad_Base : Boolean := False; - -- Set True if Base out of range or if out of range digit - - After_Point : Natural := 0; - -- Set to 1 after the point - - Precision_Limit : constant Long_Long_Float := - 2.0 ** (Long_Long_Float'Machine_Mantissa - 1); - -- This is an upper bound for the number of bits used to represent the - -- mantissa. Beyond that number, any digits parsed by Scanf are useless. - -- Thus, only the scale should be updated. This ensures that infinity is - -- not reached by the temporary Uval, which could lead to erroneous - -- rounding (for example: 0.4444444... or 1E-n). - - procedure Scanf; - -- Scans integer literal value starting at current character position. - -- For each digit encountered, Uval is multiplied by 10.0, and the new - -- digit value is incremented. In addition Scale is decremented for each - -- digit encountered if we are after the point (After_Point = 1). The - -- longest possible syntactically valid numeral is scanned out, and on - -- return P points past the last character. On entry, the current - -- character is known to be a digit, so a numeral is definitely present. - - ----------- - -- Scanf -- - ----------- - - procedure Scanf is - Digit : Natural; - Uval_Tmp : Long_Long_Float; - Precision_Limit_Reached : Boolean := False; - begin - loop - Digit := Character'Pos (Str (P)) - Character'Pos ('0'); - - if not Precision_Limit_Reached then - -- Compute potential new value - Uval_Tmp := Uval * 10.0 + Long_Long_Float (Digit); - - if Uval_Tmp > Precision_Limit then + -- Reset trailing zero counter + Trailing_Zeros := 0; + + -- Handle current non zero digit + if Value > (Precision_Limit - Digit) / Base then Precision_Limit_Reached := True; + else + Value := Value * Base + Digit; + Scale := Scale - 1; end if; end if; + end if; - if Precision_Limit_Reached then - -- If beyond the precision of the mantissa then just ignore the - -- digit, to avoid rounding issues. - if After_Point = 0 then - Scale := Scale + 1; - end if; - else - Uval := Uval_Tmp; - Scale := Scale - After_Point; - end if; + -- Check next character + Index := Index + 1; - -- Check next character - P := P + 1; + if Index > Max then + return; + end if; - if P > Max then - -- Done if end of input field - return; + Digit := As_Digit (Str (Index)); - elsif Str (P) not in Digs then - -- If next character is not a digit, check if this is an - -- underscore. If this is not the case, then return. - if Str (P) = '_' then - Scan_Underscore (Str, P, Ptr, Max, False); + if Digit < 0 then + if Digit = Underscore and Index + 1 <= Max then + -- Underscore is only alllowed if followed by a digit + Digit := As_Digit (Str (Index + 1)); + if Digit in Valid_Digit then + Index := Index + 1; else return; end if; + else + -- Neither a valid underscore nor a digit. + return; end if; + end if; + end loop; + + end Scan_Decimal_Digits; + + -------------------------- + -- Scan_Integral_Digits -- + -------------------------- + + procedure Scan_Integral_Digits + (Str : String; + Index : in out Integer; + Max : Integer; + Value : out Long_Long_Integer; + Scale : out Integer; + Base_Violation : in out Boolean; + Base : Long_Long_Integer := 10; + Base_Specified : Boolean := False) + is + Precision_Limit_Reached : Boolean := False; + -- Set to True if addition of a digit will cause Value to be superior + -- to Precision_Limit. - end loop; - end Scanf; - - -- Start of processing for System.Scan_Real - + Digit : Char_As_Digit; + -- The current digit begin - -- We do not tolerate strings with Str'Last = Positive'Last - if Str'Last = Positive'Last then - raise Program_Error with - "string upper bound is Positive'Last, not supported"; - end if; - - -- We call the floating-point processor reset routine so that we can - -- be sure the floating-point processor is properly set for conversion - -- calls. This is notably need on Windows, where calls to the operating - -- system randomly reset the processor into 64-bit mode. - - System.Float_Control.Reset; - - Scan_Sign (Str, Ptr, Max, Minus, Start); - P := Ptr.all; - Ptr.all := Start; - - -- If digit, scan numeral before point - - if Str (P) in Digs then - Uval := 0.0; - Scanf; - - -- Initial point, allowed only if followed by digit (RM 3.5(47)) - - elsif Str (P) = '.' - and then P < Max - and then Str (P + 1) in Digs - then - Uval := 0.0; - - -- Any other initial character is an error - - else - Bad_Value (Str); - end if; - - -- Deal with based case. We reognize either the standard '#' or the - -- allowed alternative replacement ':' (see RM J.2(3)). - - if P < Max and then (Str (P) = '#' or else Str (P) = ':') then - declare - Base_Char : constant Character := Str (P); - Digit : Natural; - Fdigit : Long_Long_Float; - Uval_Tmp : Long_Long_Float; - Precision_Limit_Reached : Boolean := False; - begin - -- Set bad base if out of range, and use safe base of 16.0, - -- to guard against division by zero in the loop below. - - if Uval < 2.0 or else Uval > 16.0 then - Bad_Base := True; - Uval := 16.0; + -- Initialize Scale and Value + Value := 0; + Scale := 0; + + -- The function precondition is that the first character is a valid + -- digit. + Digit := As_Digit (Str (Index)); + + loop + -- Check if base is correct. If the base is not specified the digit + -- E or e cannot be considered as a base violation as it can be used + -- for exponentiation. + if Digit >= Base then + if Base_Specified then + Base_Violation := True; + elsif Digit = E_Digit then + return; + else + Base_Violation := True; end if; + end if; - Base := Uval; - Uval := 0.0; - P := P + 1; - - -- Special check to allow initial point (RM 3.5(49)) - - if Str (P) = '.' then - After_Point := 1; - P := P + 1; + if Precision_Limit_Reached then + -- Precision limit has been reached so just update the exponent + Scale := Scale + 1; + else + if Value > (Precision_Limit - Digit) / Base then + -- Updating Value will overflow so ignore this digit and any + -- following ones. Only update the scale + Precision_Limit_Reached := True; + Scale := Scale + 1; + else + Value := Value * Base + Digit; end if; + end if; - -- Loop to scan digits of based number. On entry to the loop we - -- must have a valid digit. If we don't, then we have an illegal - -- floating-point value, and we raise Constraint_Error, note that - -- Ptr at this stage was reset to the proper (Start) value. - - loop - if P > Max then - Bad_Value (Str); - - elsif Str (P) in Digs then - Digit := Character'Pos (Str (P)) - Character'Pos ('0'); - - elsif Str (P) in 'A' .. 'F' then - Digit := - Character'Pos (Str (P)) - (Character'Pos ('A') - 10); + -- Look for the next character + Index := Index + 1; + if Index > Max then + return; + end if; - elsif Str (P) in 'a' .. 'f' then - Digit := - Character'Pos (Str (P)) - (Character'Pos ('a') - 10); + Digit := As_Digit (Str (Index)); + if Digit not in Valid_Digit then + -- Next character is not a digit. In that case stop scanning + -- unless the next chracter is an underscore followed by a digit. + if Digit = Underscore and Index + 1 <= Max then + Digit := As_Digit (Str (Index + 1)); + if Digit in Valid_Digit then + Index := Index + 1; else - Bad_Value (Str); + return; end if; + else + return; + end if; + end if; + end loop; - if not Precision_Limit_Reached then - -- Compute potential new value - Uval_Tmp := Uval * Base + Long_Long_Float (Digit); + end Scan_Integral_Digits; - if Uval_Tmp > Precision_Limit then - Precision_Limit_Reached := True; - end if; - end if; + --------------- + -- Scan_Real -- + --------------- - if Precision_Limit_Reached then - -- If beyond precision of the mantissa then just update - -- the scale and discard remaining digits. + function Scan_Real + (Str : String; + Ptr : not null access Integer; + Max : Integer) + return Long_Long_Float - if After_Point = 0 then - Scale := Scale + 1; - end if; + is + Start : Positive; + -- Position of starting non-blank character - else - -- Now accumulate the new digit + Minus : Boolean; + -- Set to True if minus sign is present, otherwise to False - Fdigit := Long_Long_Float (Digit); + Index : Integer; + -- Local copy of string pointer - if Fdigit >= Base then - Bad_Base := True; - else - Scale := Scale - After_Point; - Uval := Uval_Tmp; - end if; - end if; + Int_Value : Long_Long_Integer := -1; + -- Mantissa as an Integer - P := P + 1; + Int_Scale : Integer := 0; + -- Exponent value - if P > Max then - Bad_Value (Str); + Base_Violation : Boolean := False; + -- If True some digits where not in the base. The float is still scan + -- till the end even if an error will be raised. - elsif Str (P) = '_' then - Scan_Underscore (Str, P, Ptr, Max, True); + Uval : Long_Long_Float := 0.0; + -- Contain the final value at the end of the function - else - -- Skip past period after digit. Note that the processing - -- here will permit either a digit after the period, or the - -- terminating base character, as allowed in (RM 3.5(48)) + After_Point : Boolean := False; + -- True if a decimal should be parsed - if Str (P) = '.' and then After_Point = 0 then - P := P + 1; - After_Point := 1; + Base : Long_Long_Integer := 10; + -- Current base (default: 10) - if P > Max then - Bad_Value (Str); - end if; - end if; + Base_Char : Character := ASCII.NUL; + -- Character used to set the base. If Nul this means that default + -- base is used. - exit when Str (P) = Base_Char; - end if; - end loop; + begin + -- We do not tolerate strings with Str'Last = Positive'Last + + if Str'Last = Positive'Last then + raise Program_Error with + "string upper bound is Positive'Last, not supported"; + end if; - -- Based number successfully scanned out (point was found) + -- We call the floating-point processor reset routine so that we can + -- be sure the floating-point processor is properly set for conversion + -- calls. This is notably need on Windows, where calls to the operating + -- system randomly reset the processor into 64-bit mode. - Ptr.all := P + 1; - end; + System.Float_Control.Reset; - -- Non-based case, check for being at decimal point now. Note that - -- in Ada 95, we do not insist on a decimal point being present + -- Scan the optional sign + Scan_Sign (Str, Ptr, Max, Minus, Start); + Index := Ptr.all; + Ptr.all := Start; + -- First character can be either a decimal digit or a dot. + if Str (Index) in '0' .. '9' then + -- If this is a digit it can indicates either the float decimal + -- part or the base to use + Scan_Integral_Digits + (Str, + Index, + Max => Max, + Value => Int_Value, + Scale => Int_Scale, + Base_Violation => Base_Violation, + Base => 10); + elsif Str (Index) = '.' and then + -- A dot is only allowed if followed by a digit. + Index < Max and then + Str (Index + 1) in '0' .. '9' + then + -- Initial point, allowed only if followed by digit (RM 3.5(47)) + After_Point := True; + Index := Index + 1; + Int_Value := 0; else - Base := 10.0; - After_Point := 1; + Bad_Value (Str); + end if; - if P <= Max and then Str (P) = '.' then - P := P + 1; + -- Check if the first number encountered is a base + if Index < Max and then + (Str (Index) = '#' or else Str (Index) = ':') + then + Base_Char := Str (Index); + Base := Int_Value; + + -- Reset Int_Value to indicate that parsing of integral value should + -- be done + Int_Value := -1; + if Base < 2 or else Base > 16 then + Base_Violation := True; + Base := 16; + end if; - -- Scan digits after point if any are present (RM 3.5(46)) + Index := Index + 1; - if P <= Max and then Str (P) in Digs then - Scanf; - end if; + if Str (Index) = '.' and then + Index < Max and then + As_Digit (Str (Index + 1)) in Valid_Digit + then + After_Point := True; + Index := Index + 1; + Int_Value := 0; end if; - - Ptr.all := P; end if; - -- At this point, we have Uval containing the digits of the value as - -- an integer, and Scale indicates the negative of the number of digits - -- after the point. Base contains the base value (an integral value in - -- the range 2.0 .. 16.0). Test for exponent, must be at least one - -- character after the E for the exponent to be valid. - - Scale := Scale + Scan_Exponent (Str, Ptr, Max, Real => True); + -- Does scanning of integral part needed + if Int_Value < 0 then + if Index > Max or else As_Digit (Str (Index)) not in Valid_Digit then + Bad_Value (Str); + end if; - -- At this point the exponent has been scanned if one is present and - -- Scale is adjusted to include the exponent value. Uval contains the - -- the integral value which is to be multiplied by Base ** Scale. + Scan_Integral_Digits + (Str, + Index, + Max => Max, + Value => Int_Value, + Scale => Int_Scale, + Base_Violation => Base_Violation, + Base => Base, + Base_Specified => Base_Char /= ASCII.NUL); + end if; - -- If base is not 10, use exponentiation for scaling + -- Do we have a dot ? + if not After_Point and then + Index <= Max and then + Str (Index) = '.' + then + -- At this stage if After_Point was not set, this means that an + -- integral part has been found. Thus the dot is valid even if not + -- followed by a digit. + if Index < Max and then As_Digit (Str (Index + 1)) in Valid_Digit then + After_Point := True; + end if; - if Base /= 10.0 then - Uval := Uval * Base ** Scale; + Index := Index + 1; + end if; - -- For base 10, use power of ten table, repeatedly if necessary + if After_Point then + -- Parse decimal part + Scan_Decimal_Digits + (Str, + Index, + Max => Max, + Value => Int_Value, + Scale => Int_Scale, + Base_Violation => Base_Violation, + Base => Base, + Base_Specified => Base_Char /= ASCII.NUL); + end if; - elsif Scale > 0 then - while Scale > Maxpow and then Uval'Valid loop - Uval := Uval * Powten (Maxpow); - Scale := Scale - Maxpow; - end loop; + -- If an explicit base was specified ensure that the delimiter is found + if Base_Char /= ASCII.NUL then + if Index > Max or else Str (Index) /= Base_Char then + Bad_Value (Str); + else + Index := Index + 1; + end if; + end if; - -- Note that we still know that Scale > 0, since the loop - -- above leaves Scale in the range 1 .. Maxpow. + -- Compute the final value + Uval := Long_Long_Float (Int_Value); - if Uval'Valid then - Uval := Uval * Powten (Scale); - end if; + -- Update pointer and scan exponent. + Ptr.all := Index; - elsif Scale < 0 then - while (-Scale) > Maxpow and then Uval'Valid loop - Uval := Uval / Powten (Maxpow); - Scale := Scale + Maxpow; - end loop; + Int_Scale := Int_Scale + Scan_Exponent (Str, + Ptr, + Max, + Real => True); - -- Note that we still know that Scale < 0, since the loop - -- above leaves Scale in the range -Maxpow .. -1. - if Uval'Valid then - Uval := Uval / Powten (-Scale); - end if; - end if; + Uval := Uval * Long_Long_Float (Base) ** Int_Scale; -- Here is where we check for a bad based number - - if Bad_Base then + if Base_Violation then Bad_Value (Str); -- If OK, then deal with initial minus sign, note that this processing -- is done even if Uval is zero, so that -0.0 is correctly interpreted. - else if Minus then return -Uval; @@ -376,6 +499,7 @@ package body System.Val_Real is return Uval; end if; end if; + end Scan_Real; ---------------- diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e0ac529..8951eb6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-09-18 Nicolas Roche + + * gnat.dg/float_value2.adb: New testcase. + 2019-09-18 Vadim Godunko * gnat.dg/expect4.adb: New testcase. diff --git a/gcc/testsuite/gnat.dg/float_value2.adb b/gcc/testsuite/gnat.dg/float_value2.adb new file mode 100644 index 0000000..d1f19f8 --- /dev/null +++ b/gcc/testsuite/gnat.dg/float_value2.adb @@ -0,0 +1,10 @@ +-- { dg-do run } + +procedure Float_Value2 is + F1 : Long_Long_Float := Long_Long_Float'Value ("1.e40"); + F2 : Long_Long_Float := Long_Long_Float'Value ("1.0e40"); +begin + if F1 /= F2 then + raise Program_Error; + end if; +end Float_Value2; \ No newline at end of file -- cgit v1.1 From d05586dce2ea2ac3bc6f645b7ad79290b327ccae Mon Sep 17 00:00:00 2001 From: Yannick Moy Date: Wed, 18 Sep 2019 08:32:28 +0000 Subject: [Ada] Skip entity name qualification in GNATprove mode GNATprove was using the qualification of names for entities with local homonyms in the same scope, requiring the use of a suffix to differentiate them. This caused problems for correctly identifying primitive equality operators. This case is now handled like the rest of entities in GNATprove, by instead updating Unique_Name to append the suffix on-the-fly where needed. There is no impact on compilation and hence no test. 2019-09-18 Yannick Moy gcc/ada/ * exp_dbug.adb (Append_Homonym_Number): Use new function Get_Homonym_Number. (Get_Homonym_Number): New function to return the homonym number. (Qualify_Entity_Name): Remove special case for GNATprove. * exp_dbug.ads (Get_Homonym_Number): Make the new function public for use in GNATprove. * frontend.adb (Frontend): Do not qualify names in GNATprove mode. * sem_util.adb (Unique_Name): Append homonym suffix where needed for entities which have local homonyms in the same scope. From-SVN: r275850 --- gcc/ada/ChangeLog | 13 +++++++++++ gcc/ada/exp_dbug.adb | 63 +++++++++++++++++++++------------------------------- gcc/ada/exp_dbug.ads | 4 ++++ gcc/ada/frontend.adb | 4 +++- gcc/ada/sem_util.adb | 55 +++++++++++++++++++++++++++++++++++++-------- 5 files changed, 91 insertions(+), 48 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index e77725c..a6012fe 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,16 @@ +2019-09-18 Yannick Moy + + * exp_dbug.adb (Append_Homonym_Number): Use new function + Get_Homonym_Number. + (Get_Homonym_Number): New function to return the homonym number. + (Qualify_Entity_Name): Remove special case for GNATprove. + * exp_dbug.ads (Get_Homonym_Number): Make the new function + public for use in GNATprove. + * frontend.adb (Frontend): Do not qualify names in GNATprove + mode. + * sem_util.adb (Unique_Name): Append homonym suffix where needed + for entities which have local homonyms in the same scope. + 2019-09-18 Nicolas Roche * libgnat/s-valrea.adb (Scan_Integral_Digits): New procedure. diff --git a/gcc/ada/exp_dbug.adb b/gcc/ada/exp_dbug.adb index 3dbe9ad..eb5e72b 100644 --- a/gcc/ada/exp_dbug.adb +++ b/gcc/ada/exp_dbug.adb @@ -219,26 +219,12 @@ package body Exp_Dbug is begin if Has_Homonym (E) then - declare - H : Entity_Id := Homonym (E); - Nr : Nat := 1; - - begin - while Present (H) loop - if Scope (H) = Scope (E) then - Nr := Nr + 1; - end if; - - H := Homonym (H); - end loop; - - if Homonym_Len > 0 then - Homonym_Len := Homonym_Len + 1; - Homonym_Numbers (Homonym_Len) := '_'; - end if; + if Homonym_Len > 0 then + Homonym_Len := Homonym_Len + 1; + Homonym_Numbers (Homonym_Len) := '_'; + end if; - Add_Nat_To_H (Nr); - end; + Add_Nat_To_H (Get_Homonym_Number (E)); end if; end Append_Homonym_Number; @@ -1068,6 +1054,26 @@ package body Exp_Dbug is end loop; end Build_Subprogram_Instance_Renamings; + ------------------------ + -- Get_Homonym_Number -- + ------------------------ + + function Get_Homonym_Number (E : Entity_Id) return Nat is + H : Entity_Id := Homonym (E); + Nr : Nat := 1; + + begin + while Present (H) loop + if Scope (H) = Scope (E) then + Nr := Nr + 1; + end if; + + H := Homonym (H); + end loop; + + return Nr; + end Get_Homonym_Number; + ------------------------------------ -- Get_Secondary_DT_External_Name -- ------------------------------------ @@ -1451,25 +1457,6 @@ package body Exp_Dbug is if Has_Qualified_Name (Ent) then return; - -- In formal verification mode, simply append a suffix for homonyms. - -- We used to qualify entity names as full expansion does, but this was - -- removed as this prevents the verification back-end from using a short - -- name for debugging and user interaction. The verification back-end - -- already takes care of qualifying names when needed. Still mark the - -- name as being qualified, as Qualify_Entity_Name may be called more - -- than once on the same entity. - - elsif GNATprove_Mode then - if Has_Homonym (Ent) then - Get_Name_String (Chars (Ent)); - Append_Homonym_Number (Ent); - Output_Homonym_Numbers_Suffix; - Set_Chars (Ent, Name_Enter); - end if; - - Set_Has_Qualified_Name (Ent); - return; - -- If the entity is a variable encoding the debug name for an object -- renaming, then the qualified name of the entity associated with the -- renamed object can now be incorporated in the debug name. diff --git a/gcc/ada/exp_dbug.ads b/gcc/ada/exp_dbug.ads index 93b9783..b9f1fd6 100644 --- a/gcc/ada/exp_dbug.ads +++ b/gcc/ada/exp_dbug.ads @@ -460,6 +460,10 @@ package Exp_Dbug is -- Subprograms for Handling Qualification -- -------------------------------------------- + function Get_Homonym_Number (E : Entity_Id) return Nat; + -- Return the homonym number for E, which is its position in the homonym + -- chain starting at 1. This is exported for use in GNATprove. + procedure Qualify_Entity_Names (N : Node_Id); -- Given a node N, that represents a block, subprogram body, or package -- body or spec, or protected or task type, sets a fully qualified name diff --git a/gcc/ada/frontend.adb b/gcc/ada/frontend.adb index 2b3f377..1cc143a 100644 --- a/gcc/ada/frontend.adb +++ b/gcc/ada/frontend.adb @@ -492,7 +492,9 @@ begin -- Qualify all entity names in inner packages, package bodies, etc - Exp_Dbug.Qualify_All_Entity_Names; + if not GNATprove_Mode then + Exp_Dbug.Qualify_All_Entity_Names; + end if; -- SCIL backend requirement. Check that SCIL nodes associated with -- dispatching calls reference subprogram calls. diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb index 99cdb8d..f66c77f 100644 --- a/gcc/ada/sem_util.adb +++ b/gcc/ada/sem_util.adb @@ -33,6 +33,7 @@ with Elists; use Elists; with Errout; use Errout; with Erroutc; use Erroutc; with Exp_Ch11; use Exp_Ch11; +with Exp_Dbug; use Exp_Dbug; with Exp_Util; use Exp_Util; with Fname; use Fname; with Freeze; use Freeze; @@ -26154,24 +26155,59 @@ package body Sem_Util is function Unique_Name (E : Entity_Id) return String is - -- Names in E_Subprogram_Body or E_Package_Body entities are not - -- reliable, as they may not include the overloading suffix. Instead, - -- when looking for the name of E or one of its enclosing scope, we get - -- the name of the corresponding Unique_Entity. + -- Local subprograms - U : constant Entity_Id := Unique_Entity (E); + function Add_Homonym_Suffix (E : Entity_Id) return String; function This_Name return String; + ------------------------ + -- Add_Homonym_Suffix -- + ------------------------ + + function Add_Homonym_Suffix (E : Entity_Id) return String is + + -- Names in E_Subprogram_Body or E_Package_Body entities are not + -- reliable, as they may not include the overloading suffix. + -- Instead, when looking for the name of E or one of its enclosing + -- scope, we get the name of the corresponding Unique_Entity. + + U : constant Entity_Id := Unique_Entity (E); + Nam : constant String := Get_Name_String (Chars (U)); + + begin + -- If E has homonyms but is not fully qualified, as done in + -- GNATprove mode, append the homonym number on the fly. Strip the + -- leading space character in the image of natural numbers. Also do + -- not print the homonym value of 1. + + if Has_Homonym (U) then + declare + N : constant Nat := Get_Homonym_Number (U); + S : constant String := N'Img; + begin + if N > 1 then + return Nam & "__" & S (2 .. S'Last); + end if; + end; + end if; + + return Nam; + end Add_Homonym_Suffix; + --------------- -- This_Name -- --------------- function This_Name return String is begin - return Get_Name_String (Chars (U)); + return Add_Homonym_Suffix (E); end This_Name; + -- Local variables + + U : constant Entity_Id := Unique_Entity (E); + -- Start of processing for Unique_Name begin @@ -26201,16 +26237,17 @@ package body Sem_Util is end if; -- For intances of generic subprograms use the name of the related - -- instace and skip the scope of its wrapper package. + -- instance and skip the scope of its wrapper package. elsif Is_Wrapper_Package (S) then pragma Assert (Scope (S) = Scope (Related_Instance (S))); -- Wrapper package and the instantiation are in the same scope declare + Related_Name : constant String := + Add_Homonym_Suffix (Related_Instance (S)); Enclosing_Name : constant String := - Unique_Name (Scope (S)) & "__" & - Get_Name_String (Chars (Related_Instance (S))); + Unique_Name (Scope (S)) & "__" & Related_Name; begin if Is_Subprogram (U) -- cgit v1.1 From 432a3b3644f52822cb61da7f529edf35b4390dd8 Mon Sep 17 00:00:00 2001 From: Piotr Trojanek Date: Wed, 18 Sep 2019 08:32:33 +0000 Subject: [Ada] Refine type of Get_Homonym_Number result Routine Get_Homonym_Number always returns a positive number. This is explained in its comment and is evident from its body. No test attached, because semantics is unaffected. 2019-09-18 Piotr Trojanek gcc/ada/ * exp_dbug.ads, exp_dbug.adb (Get_Homonym_Number): Refine type from Nat to Pos. * sem_util.adb (Add_Homonym_Suffix): Refine type of a local variable. From-SVN: r275851 --- gcc/ada/ChangeLog | 7 +++++++ gcc/ada/exp_dbug.adb | 4 ++-- gcc/ada/exp_dbug.ads | 2 +- gcc/ada/sem_util.adb | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index a6012fe..8b044d1 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,10 @@ +2019-09-18 Piotr Trojanek + + * exp_dbug.ads, exp_dbug.adb (Get_Homonym_Number): Refine type + from Nat to Pos. + * sem_util.adb (Add_Homonym_Suffix): Refine type of a local + variable. + 2019-09-18 Yannick Moy * exp_dbug.adb (Append_Homonym_Number): Use new function diff --git a/gcc/ada/exp_dbug.adb b/gcc/ada/exp_dbug.adb index eb5e72b..c2d2318 100644 --- a/gcc/ada/exp_dbug.adb +++ b/gcc/ada/exp_dbug.adb @@ -1058,9 +1058,9 @@ package body Exp_Dbug is -- Get_Homonym_Number -- ------------------------ - function Get_Homonym_Number (E : Entity_Id) return Nat is + function Get_Homonym_Number (E : Entity_Id) return Pos is H : Entity_Id := Homonym (E); - Nr : Nat := 1; + Nr : Pos := 1; begin while Present (H) loop diff --git a/gcc/ada/exp_dbug.ads b/gcc/ada/exp_dbug.ads index b9f1fd6..ac40a40 100644 --- a/gcc/ada/exp_dbug.ads +++ b/gcc/ada/exp_dbug.ads @@ -460,7 +460,7 @@ package Exp_Dbug is -- Subprograms for Handling Qualification -- -------------------------------------------- - function Get_Homonym_Number (E : Entity_Id) return Nat; + function Get_Homonym_Number (E : Entity_Id) return Pos; -- Return the homonym number for E, which is its position in the homonym -- chain starting at 1. This is exported for use in GNATprove. diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb index f66c77f..eac0c97 100644 --- a/gcc/ada/sem_util.adb +++ b/gcc/ada/sem_util.adb @@ -26183,7 +26183,7 @@ package body Sem_Util is if Has_Homonym (U) then declare - N : constant Nat := Get_Homonym_Number (U); + N : constant Pos := Get_Homonym_Number (U); S : constant String := N'Img; begin if N > 1 then -- cgit v1.1 From 50a7395372ba8a082fc0514a16a3f381ec1e49e7 Mon Sep 17 00:00:00 2001 From: Steve Baird Date: Wed, 18 Sep 2019 08:32:37 +0000 Subject: [Ada] Don't fail a front-end assertion if errors have already been detected In sem_eval.adb, we have an assertion that the type of a "null" literal is an access type. It turns out that this assertion can fail when processing an illegal program, e.g. one that contains something like "Integer'(null)". This leads to differences in the compiler's generated output for such tests depending on whether assertions are/aren't enabled; in particular, the "compilation abandoned due to previous error" message generated in Comperr.Compiler_Abort. In order to avoid these differences, we change the assertion so that it does not fail if errors have already been posted on the given node. 2019-09-18 Steve Baird gcc/ada/ * sem_eval.adb (Expr_Value): Do not fail "the type of a null literal must be an access type" assertion if errors have already been posted on the given node. From-SVN: r275852 --- gcc/ada/ChangeLog | 6 ++++++ gcc/ada/sem_eval.adb | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 8b044d1..88957a2 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,9 @@ +2019-09-18 Steve Baird + + * sem_eval.adb (Expr_Value): Do not fail "the type of a null + literal must be an access type" assertion if errors have already + been posted on the given node. + 2019-09-18 Piotr Trojanek * exp_dbug.ads, exp_dbug.adb (Get_Homonym_Number): Refine type diff --git a/gcc/ada/sem_eval.adb b/gcc/ada/sem_eval.adb index 5c41642..5f26ecd 100644 --- a/gcc/ada/sem_eval.adb +++ b/gcc/ada/sem_eval.adb @@ -4278,7 +4278,8 @@ package body Sem_Eval is -- The NULL access value elsif Kind = N_Null then - pragma Assert (Is_Access_Type (Underlying_Type (Etype (N)))); + pragma Assert (Is_Access_Type (Underlying_Type (Etype (N))) + or else Error_Posted (N)); Val := Uint_0; -- Character literal -- cgit v1.1 From f04e9787ea98a9a8d596be8ca78eb74a7f9f863c Mon Sep 17 00:00:00 2001 From: Javier Miranda Date: Wed, 18 Sep 2019 08:32:42 +0000 Subject: [Ada] Code cleanup of alignment representation clauses in dispatch tables This patch does not modify the functionality of the compiler; it avoids generating non-required alignment representation clauses for dispatch tables. 2019-09-18 Javier Miranda gcc/ada/ * exp_disp.adb (Make_DT, Make_Secondary_DT): Remove generation of alignment representation clause for the following tables: Predef_Prims, Iface_DT, TSD, ITable, DT. From-SVN: r275853 --- gcc/ada/ChangeLog | 6 ++++ gcc/ada/exp_disp.adb | 99 +--------------------------------------------------- 2 files changed, 7 insertions(+), 98 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 88957a2..dee3610 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,9 @@ +2019-09-18 Javier Miranda + + * exp_disp.adb (Make_DT, Make_Secondary_DT): Remove generation + of alignment representation clause for the following tables: + Predef_Prims, Iface_DT, TSD, ITable, DT. + 2019-09-18 Steve Baird * sem_eval.adb (Expr_Value): Do not fail "the type of a null diff --git a/gcc/ada/exp_disp.adb b/gcc/ada/exp_disp.adb index 640d205..84caa92 100644 --- a/gcc/ada/exp_disp.adb +++ b/gcc/ada/exp_disp.adb @@ -4041,7 +4041,6 @@ package body Exp_Disp is -- predef-prim-op-thunk-2'address, -- ... -- predef-prim-op-thunk-n'address); - -- for Predef_Prims'Alignment use Address'Alignment -- Create the thunks associated with the predefined primitives and -- save their entity to fill the aggregate. @@ -4125,16 +4124,6 @@ package body Exp_Disp is Object_Definition => New_Occurrence_Of (Defining_Identifier (Decl), Loc), Expression => New_Node)); - - Append_To (Result, - Make_Attribute_Definition_Clause (Loc, - Name => New_Occurrence_Of (Predef_Prims, Loc), - Chars => Name_Alignment, - Expression => - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (RTE (RE_Integer_Address), Loc), - Attribute_Name => Name_Alignment))); end; -- Generate @@ -4143,6 +4132,7 @@ package body Exp_Disp is -- (OSD_Table => (1 => , -- ... -- N => )); + -- for OSD'Alignment use Address'Alignment; -- Iface_DT : Dispatch_Table (Nb_Prims) := -- ([ Signature => ], @@ -4154,7 +4144,6 @@ package body Exp_Disp is -- prim-op-2'address, -- ... -- prim-op-n'address)); - -- for Iface_DT'Alignment use Address'Alignment; -- Stage 3: Initialize the discriminant and the record components @@ -4454,17 +4443,6 @@ package body Exp_Disp is Make_Aggregate (Loc, Expressions => DT_Aggr_List))); - Append_To (Result, - Make_Attribute_Definition_Clause (Loc, - Name => New_Occurrence_Of (Iface_DT, Loc), - Chars => Name_Alignment, - - Expression => - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (RTE (RE_Integer_Address), Loc), - Attribute_Name => Name_Alignment))); - if Exporting_Table then Export_DT (Typ, Iface_DT, Suffix_Index); @@ -4946,7 +4924,6 @@ package body Exp_Disp is -- Generate: -- DT : No_Dispatch_Table_Wrapper; - -- for DT'Alignment use Address'Alignment; -- DT_Ptr : Tag := !Tag (DT.NDT_Prims_Ptr'Address); if not Has_DT (Typ) then @@ -4960,16 +4937,6 @@ package body Exp_Disp is (RTE (RE_No_Dispatch_Table_Wrapper), Loc))); Append_To (Result, - Make_Attribute_Definition_Clause (Loc, - Name => New_Occurrence_Of (DT, Loc), - Chars => Name_Alignment, - Expression => - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (RTE (RE_Integer_Address), Loc), - Attribute_Name => Name_Alignment))); - - Append_To (Result, Make_Object_Declaration (Loc, Defining_Identifier => DT_Ptr, Object_Definition => New_Occurrence_Of (RTE (RE_Tag), Loc), @@ -5008,7 +4975,6 @@ package body Exp_Disp is -- Generate: -- DT : Dispatch_Table_Wrapper (Nb_Prim); - -- for DT'Alignment use Address'Alignment; -- DT_Ptr : Tag := !Tag (DT.Prims_Ptr'Address); else @@ -5037,16 +5003,6 @@ package body Exp_Disp is Constraints => DT_Constr_List)))); Append_To (Result, - Make_Attribute_Definition_Clause (Loc, - Name => New_Occurrence_Of (DT, Loc), - Chars => Name_Alignment, - Expression => - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (RTE (RE_Integer_Address), Loc), - Attribute_Name => Name_Alignment))); - - Append_To (Result, Make_Object_Declaration (Loc, Defining_Identifier => DT_Ptr, Object_Definition => New_Occurrence_Of (RTE (RE_Tag), Loc), @@ -5161,7 +5117,6 @@ package body Exp_Disp is -- Tags_Table => (0 => null, -- 1 => Parent'Tag -- ...); - -- for TSD'Alignment use Address'Alignment TSD_Aggr_List := New_List; @@ -5699,16 +5654,6 @@ package body Exp_Disp is Make_Integer_Literal (Loc, Num_Ifaces), Make_Aggregate (Loc, TSD_Ifaces_List))))); - Append_To (Result, - Make_Attribute_Definition_Clause (Loc, - Name => New_Occurrence_Of (ITable, Loc), - Chars => Name_Alignment, - Expression => - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (RTE (RE_Integer_Address), Loc), - Attribute_Name => Name_Alignment))); - Iface_Table_Node := Make_Attribute_Reference (Loc, Prefix => New_Occurrence_Of (ITable, Loc), @@ -5859,16 +5804,6 @@ package body Exp_Disp is Set_Is_True_Constant (TSD, Building_Static_DT (Typ)); - Append_To (Result, - Make_Attribute_Definition_Clause (Loc, - Name => New_Occurrence_Of (TSD, Loc), - Chars => Name_Alignment, - Expression => - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (RTE (RE_Integer_Address), Loc), - Attribute_Name => Name_Alignment))); - -- Initialize or declare the dispatch table object if not Has_DT (Typ) then @@ -5906,7 +5841,6 @@ package body Exp_Disp is -- DT : aliased constant No_Dispatch_Table := -- (NDT_TSD => TSD'Address; -- NDT_Prims_Ptr => 0); - -- for DT'Alignment use Address'Alignment; else Append_To (Result, @@ -5918,16 +5852,6 @@ package body Exp_Disp is New_Occurrence_Of (RTE (RE_No_Dispatch_Table_Wrapper), Loc), Expression => Make_Aggregate (Loc, DT_Aggr_List))); - Append_To (Result, - Make_Attribute_Definition_Clause (Loc, - Name => New_Occurrence_Of (DT, Loc), - Chars => Name_Alignment, - Expression => - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (RTE (RE_Integer_Address), Loc), - Attribute_Name => Name_Alignment))); - Export_DT (Typ, DT); end if; @@ -5940,7 +5864,6 @@ package body Exp_Disp is -- predef-prim-op-2'address, -- ... -- predef-prim-op-n'address); - -- for Predef_Prims'Alignment use Address'Alignment -- DT : Dispatch_Table (Nb_Prims) := -- (Signature => , @@ -6025,16 +5948,6 @@ package body Exp_Disp is -- Remember aggregates initializing dispatch tables Append_Elmt (New_Node, DT_Aggr); - - Append_To (Result, - Make_Attribute_Definition_Clause (Loc, - Name => New_Occurrence_Of (Predef_Prims, Loc), - Chars => Name_Alignment, - Expression => - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (RTE (RE_Integer_Address), Loc), - Attribute_Name => Name_Alignment))); end; -- Stage 1: Initialize the discriminant and the record components @@ -6221,16 +6134,6 @@ package body Exp_Disp is Constraints => DT_Constr_List)), Expression => Make_Aggregate (Loc, DT_Aggr_List))); - Append_To (Result, - Make_Attribute_Definition_Clause (Loc, - Name => New_Occurrence_Of (DT, Loc), - Chars => Name_Alignment, - Expression => - Make_Attribute_Reference (Loc, - Prefix => - New_Occurrence_Of (RTE (RE_Integer_Address), Loc), - Attribute_Name => Name_Alignment))); - Export_DT (Typ, DT); end if; end if; -- cgit v1.1 From a6d677c65b999fd44446592cde9282b65772095a Mon Sep 17 00:00:00 2001 From: Vasiliy Fofanov Date: Wed, 18 Sep 2019 08:32:46 +0000 Subject: [Ada] Fix minor formatting issue 2019-09-18 Vasiliy Fofanov gcc/ada/ * doc/gnat_rm/implementation_defined_pragmas.rst: Fix minor formatting issue. From-SVN: r275854 --- gcc/ada/ChangeLog | 5 +++++ gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index dee3610..752a9fd 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,8 @@ +2019-09-18 Vasiliy Fofanov + + * doc/gnat_rm/implementation_defined_pragmas.rst: Fix minor + formatting issue. + 2019-09-18 Javier Miranda * exp_disp.adb (Make_DT, Make_Secondary_DT): Remove generation diff --git a/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst b/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst index 8ce22f1..126aaf8 100644 --- a/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst +++ b/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst @@ -6179,7 +6179,7 @@ usually supplied automatically by the project manager. A pragma Source_File_Name cannot appear after a :ref:`Pragma_Source_File_Name_Project`. For more details on the use of the ``Source_File_Name`` pragma, see the -sections on ``Using Other File Names`` and `Alternative File Naming Schemes' +sections on `Using Other File Names` and `Alternative File Naming Schemes` in the :title:`GNAT User's Guide`. .. _Pragma_Source_File_Name_Project: -- cgit v1.1 From 0af16535246ef8a9a814da6a3ae7a5bcae89dc30 Mon Sep 17 00:00:00 2001 From: Bob Duff Date: Wed, 18 Sep 2019 08:32:51 +0000 Subject: [Ada] Improve efficiency of copying bit-packed slices This patch substantially improves the efficiency of copying large slices of bit-packed arrays, by copying 32 bits at a time instead of 1 at a time. 2019-09-18 Bob Duff gcc/ada/ * exp_ch5.adb (Expand_Assign_Array_Loop_Or_Bitfield): The call to Copy_Bitfield is now enabled. (Expand_Assign_Array_Bitfield): Multiply 'Length times 'Component_Size "by hand" instead of using 'Size. From-SVN: r275855 --- gcc/ada/ChangeLog | 7 +++++++ gcc/ada/exp_ch5.adb | 22 ++++++++++++++-------- 2 files changed, 21 insertions(+), 8 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 752a9fd..561f6a8 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,10 @@ +2019-09-18 Bob Duff + + * exp_ch5.adb (Expand_Assign_Array_Loop_Or_Bitfield): The call + to Copy_Bitfield is now enabled. + (Expand_Assign_Array_Bitfield): Multiply 'Length times + 'Component_Size "by hand" instead of using 'Size. + 2019-09-18 Vasiliy Fofanov * doc/gnat_rm/implementation_defined_pragmas.rst: Fix minor diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb index 76e97fc..f5c1f21 100644 --- a/gcc/ada/exp_ch5.adb +++ b/gcc/ada/exp_ch5.adb @@ -1411,12 +1411,21 @@ package body Exp_Ch5 is -- Compute the Size of the bitfield -- Note that the length check has already been done, so we can use the - -- size of either L or R. + -- size of either L or R; they are equal. We can't use 'Size here, + -- because sometimes bit fields get copied into a temp, and the 'Size + -- ends up being the size of the temp (e.g. an 8-bit temp containing + -- a 4-bit bit field). Size : constant Node_Id := - Make_Attribute_Reference (Loc, - Prefix => Duplicate_Subexpr (Name (N), True), - Attribute_Name => Name_Size); + Make_Op_Multiply (Loc, + Make_Attribute_Reference (Loc, + Prefix => + Duplicate_Subexpr (Name (N), True), + Attribute_Name => Name_Length), + Make_Attribute_Reference (Loc, + Prefix => + Duplicate_Subexpr (Name (N), True), + Attribute_Name => Name_Component_Size)); begin return Make_Procedure_Call_Statement (Loc, @@ -1466,10 +1475,7 @@ package body Exp_Ch5 is -- optimization in that case as well. We could complicate this code by -- actually looking for such volatile and independent components. - -- Note that Expand_Assign_Array_Bitfield is disabled for now. - - if False and then -- ??? - RTE_Available (RE_Copy_Bitfield) + if RTE_Available (RE_Copy_Bitfield) and then Is_Bit_Packed_Array (L_Type) and then Is_Bit_Packed_Array (R_Type) and then not Reverse_Storage_Order (L_Type) -- cgit v1.1 From 6bc08721d027d10a2d9ea98c753a8bf0b4493e91 Mon Sep 17 00:00:00 2001 From: Javier Miranda Date: Wed, 18 Sep 2019 08:32:55 +0000 Subject: [Ada] Fix portability issues in access to subprograms This patch improves the portability of the code generated by the compiler for access to subprograms. Written by Richard Kenner. 2019-09-18 Javier Miranda gcc/ada/ * exp_ch4.adb (Expand_N_Op_Eq): The frontend assumes that we can do a bit-for-bit comparison of two access to protected subprogram pointers. However, there are two reasons why we may not be able to do that: (1) there may be padding bits for alignment before the access to subprogram, and (2) the access to subprogram itself may not be compared bit-for- bit because the activation record part is undefined: two pointers are equal iff the subprogram addresses are equal. This patch fixes it by forcing a field-by-field comparison. * bindgen.adb (Gen_Adainit): The type No_Param_Proc is defined in the library as having Favor_Top_Level, but when we create an object of that type in the binder file we don't have that pragma, so the types are different. This patch fixes this issue. * libgnarl/s-interr.adb, libgnarl/s-interr__hwint.adb, libgnarl/s-interr__sigaction.adb, libgnarl/s-interr__vxworks.adb (Is_Registered): This routine erroneously assumes that the access to protected subprogram is two addresses. We need to create the same record that the compiler makes to ensure that any padding is the same. Then we have to look at just the first word of the access to subprogram. This patch fixes this issue. From-SVN: r275856 --- gcc/ada/ChangeLog | 23 +++++++++++++++++++ gcc/ada/bindgen.adb | 1 + gcc/ada/exp_ch4.adb | 39 +++++++++++++++++++++++++++++++- gcc/ada/libgnarl/s-interr.adb | 6 +++-- gcc/ada/libgnarl/s-interr__hwint.adb | 7 ++++-- gcc/ada/libgnarl/s-interr__sigaction.adb | 6 +++-- gcc/ada/libgnarl/s-interr__vxworks.adb | 7 ++++-- 7 files changed, 80 insertions(+), 9 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 561f6a8..07638f1 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,26 @@ +2019-09-18 Javier Miranda + + * exp_ch4.adb (Expand_N_Op_Eq): The frontend assumes that we can + do a bit-for-bit comparison of two access to protected + subprogram pointers. However, there are two reasons why we may + not be able to do that: (1) there may be padding bits for + alignment before the access to subprogram, and (2) the access to + subprogram itself may not be compared bit-for- bit because the + activation record part is undefined: two pointers are equal iff + the subprogram addresses are equal. This patch fixes it by + forcing a field-by-field comparison. + * bindgen.adb (Gen_Adainit): The type No_Param_Proc is defined + in the library as having Favor_Top_Level, but when we create an + object of that type in the binder file we don't have that + pragma, so the types are different. This patch fixes this issue. + * libgnarl/s-interr.adb, libgnarl/s-interr__hwint.adb, + libgnarl/s-interr__sigaction.adb, libgnarl/s-interr__vxworks.adb + (Is_Registered): This routine erroneously assumes that the + access to protected subprogram is two addresses. We need to + create the same record that the compiler makes to ensure that + any padding is the same. Then we have to look at just the first + word of the access to subprogram. This patch fixes this issue. + 2019-09-18 Bob Duff * exp_ch5.adb (Expand_Assign_Array_Loop_Or_Bitfield): The call diff --git a/gcc/ada/bindgen.adb b/gcc/ada/bindgen.adb index 153043c..e60cb7a 100644 --- a/gcc/ada/bindgen.adb +++ b/gcc/ada/bindgen.adb @@ -524,6 +524,7 @@ package body Bindgen is and then not Configurable_Run_Time_On_Target then WBI (" type No_Param_Proc is access procedure;"); + WBI (" pragma Favor_Top_Level (No_Param_Proc);"); WBI (""); end if; diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb index c288d6a..0c96d8c 100644 --- a/gcc/ada/exp_ch4.adb +++ b/gcc/ada/exp_ch4.adb @@ -8221,6 +8221,32 @@ package body Exp_Ch4 is Insert_Actions (N, Bodies, Suppress => All_Checks); Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks); end if; + + -- If unnesting, handle elementary types whose Equivalent_Types are + -- records because there may be padding or undefined fields. + + elsif Unnest_Subprogram_Mode + and then Ekind_In (Typl, E_Class_Wide_Type, + E_Class_Wide_Subtype, + E_Access_Subprogram_Type, + E_Access_Protected_Subprogram_Type, + E_Anonymous_Access_Protected_Subprogram_Type, + E_Access_Subprogram_Type, + E_Exception_Type) + and then Present (Equivalent_Type (Typl)) + and then Is_Record_Type (Equivalent_Type (Typl)) + then + Typl := Equivalent_Type (Typl); + Remove_Side_Effects (Lhs); + Remove_Side_Effects (Rhs); + Rewrite (N, + Expand_Record_Equality (N, Typl, + Unchecked_Convert_To (Typl, Lhs), + Unchecked_Convert_To (Typl, Rhs), + Bodies)); + + Insert_Actions (N, Bodies, Suppress => All_Checks); + Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks); end if; -- Test if result is known at compile time @@ -9497,10 +9523,21 @@ package body Exp_Ch4 is Typ : constant Entity_Id := Etype (Left_Opnd (N)); begin - -- Case of elementary type with standard operator + -- Case of elementary type with standard operator. But if + -- unnesting, handle elementary types whose Equivalent_Types are + -- records because there may be padding or undefined fields. if Is_Elementary_Type (Typ) and then Sloc (Entity (N)) = Standard_Location + and then not (Ekind_In (Typ, E_Class_Wide_Type, + E_Class_Wide_Subtype, + E_Access_Subprogram_Type, + E_Access_Protected_Subprogram_Type, + E_Anonymous_Access_Protected_Subprogram_Type, + E_Access_Subprogram_Type, + E_Exception_Type) + and then Present (Equivalent_Type (Typ)) + and then Is_Record_Type (Equivalent_Type (Typ))) then Binary_Op_Validity_Checks (N); diff --git a/gcc/ada/libgnarl/s-interr.adb b/gcc/ada/libgnarl/s-interr.adb index 7106c57..bb5defd 100644 --- a/gcc/ada/libgnarl/s-interr.adb +++ b/gcc/ada/libgnarl/s-interr.adb @@ -545,9 +545,11 @@ package body System.Interrupts is function Is_Registered (Handler : Parameterless_Handler) return Boolean is + type Acc_Proc is access procedure; + type Fat_Ptr is record Object_Addr : System.Address; - Handler_Addr : System.Address; + Handler_Addr : Acc_Proc; end record; function To_Fat_Ptr is new Ada.Unchecked_Conversion @@ -565,7 +567,7 @@ package body System.Interrupts is Ptr := Registered_Handler_Head; while Ptr /= null loop - if Ptr.H = Fat.Handler_Addr then + if Ptr.H = Fat.Handler_Addr.all'Address then return True; end if; diff --git a/gcc/ada/libgnarl/s-interr__hwint.adb b/gcc/ada/libgnarl/s-interr__hwint.adb index 50e2ec2..ff7fe05 100644 --- a/gcc/ada/libgnarl/s-interr__hwint.adb +++ b/gcc/ada/libgnarl/s-interr__hwint.adb @@ -561,9 +561,12 @@ package body System.Interrupts is ------------------- function Is_Registered (Handler : Parameterless_Handler) return Boolean is + + type Acc_Proc is access procedure; + type Fat_Ptr is record Object_Addr : System.Address; - Handler_Addr : System.Address; + Handler_Addr : Acc_Proc; end record; function To_Fat_Ptr is new Ada.Unchecked_Conversion @@ -581,7 +584,7 @@ package body System.Interrupts is Ptr := Registered_Handler_Head; while Ptr /= null loop - if Ptr.H = Fat.Handler_Addr then + if Ptr.H = Fat.Handler_Addr.all'Address then return True; end if; diff --git a/gcc/ada/libgnarl/s-interr__sigaction.adb b/gcc/ada/libgnarl/s-interr__sigaction.adb index d9ffe0c..d8fb7ba 100644 --- a/gcc/ada/libgnarl/s-interr__sigaction.adb +++ b/gcc/ada/libgnarl/s-interr__sigaction.adb @@ -487,9 +487,11 @@ package body System.Interrupts is function Is_Registered (Handler : Parameterless_Handler) return Boolean is Ptr : R_Link := Registered_Handlers; + type Acc_Proc is access procedure; + type Fat_Ptr is record Object_Addr : System.Address; - Handler_Addr : System.Address; + Handler_Addr : Acc_Proc; end record; function To_Fat_Ptr is new Ada.Unchecked_Conversion @@ -505,7 +507,7 @@ package body System.Interrupts is Fat := To_Fat_Ptr (Handler); while Ptr /= null loop - if Ptr.H = Fat.Handler_Addr then + if Ptr.H = Fat.Handler_Addr.all'Address then return True; end if; diff --git a/gcc/ada/libgnarl/s-interr__vxworks.adb b/gcc/ada/libgnarl/s-interr__vxworks.adb index b2c4eee..16d22a6 100644 --- a/gcc/ada/libgnarl/s-interr__vxworks.adb +++ b/gcc/ada/libgnarl/s-interr__vxworks.adb @@ -578,9 +578,12 @@ package body System.Interrupts is ------------------- function Is_Registered (Handler : Parameterless_Handler) return Boolean is + + type Acc_Proc is access procedure; + type Fat_Ptr is record Object_Addr : System.Address; - Handler_Addr : System.Address; + Handler_Addr : Acc_Proc; end record; function To_Fat_Ptr is new Ada.Unchecked_Conversion @@ -598,7 +601,7 @@ package body System.Interrupts is Ptr := Registered_Handler_Head; while Ptr /= null loop - if Ptr.H = Fat.Handler_Addr then + if Ptr.H = Fat.Handler_Addr.all'Address then return True; end if; -- cgit v1.1 From c8324fe7b12851c16c867f16ce248c95d2dbae7d Mon Sep 17 00:00:00 2001 From: Steve Baird Date: Wed, 18 Sep 2019 08:33:02 +0000 Subject: [Ada] Implement AI12-0086's rules for discriminants in aggregates In Ada2012, a discriminant value that governs an active variant part in an aggregate had to be static. AI12-0086 relaxes this restriction - if the subtype of the discriminant value is a static subtype all of whose values select the same variant, then that is good enough. 2019-09-18 Steve Baird gcc/ada/ * sem_util.ads (Interval_Lists): A new visible package. This package is visible because it is also intended for eventual use in Sem_Eval.Subtypes_Statically_Compatible when that function is someday upgraded to handle static predicates correctly. This new package doesn't really need to be visible for now, but it still seems like a good idea. * sem_util.adb (Gather_Components): Implement AI12-0086 via the following strategy. The existing code knows how to take a static discriminant value and identify the corresponding variant; in the newly-permitted case of a non-static value of a static subtype, we arbitrarily select a value of the subtype and find the corresponding variant using the existing code. Subsequently, we check that every other value of the discriminant's subtype corresponds to the same variant; this is done using the newly introduced Interval_Lists package. (Interval_Lists): Provide a body for the new package. gcc/testsuite/ * gnat.dg/ai12_0086_example.adb: New testcase. From-SVN: r275857 --- gcc/ada/ChangeLog | 19 ++ gcc/ada/sem_util.adb | 509 ++++++++++++++++++++++++++-- gcc/ada/sem_util.ads | 36 ++ gcc/testsuite/ChangeLog | 4 + gcc/testsuite/gnat.dg/ai12_0086_example.adb | 24 ++ 5 files changed, 571 insertions(+), 21 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/ai12_0086_example.adb (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 07638f1..452243a 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,22 @@ +2019-09-18 Steve Baird + + * sem_util.ads (Interval_Lists): A new visible package. This + package is visible because it is also intended for eventual use + in Sem_Eval.Subtypes_Statically_Compatible when that function is + someday upgraded to handle static predicates correctly. This + new package doesn't really need to be visible for now, but it + still seems like a good idea. + * sem_util.adb (Gather_Components): Implement AI12-0086 via the + following strategy. The existing code knows how to take a static + discriminant value and identify the corresponding variant; in + the newly-permitted case of a non-static value of a static + subtype, we arbitrarily select a value of the subtype and find + the corresponding variant using the existing code. Subsequently, + we check that every other value of the discriminant's subtype + corresponds to the same variant; this is done using the newly + introduced Interval_Lists package. + (Interval_Lists): Provide a body for the new package. + 2019-09-18 Javier Miranda * exp_ch4.adb (Expand_N_Op_Eq): The frontend assumes that we can diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb index eac0c97..13555a5 100644 --- a/gcc/ada/sem_util.adb +++ b/gcc/ada/sem_util.adb @@ -68,6 +68,7 @@ with Tbuild; use Tbuild; with Ttypes; use Ttypes; with Uname; use Uname; +with GNAT.Heap_Sort_G; with GNAT.HTable; use GNAT.HTable; package body Sem_Util is @@ -8885,11 +8886,17 @@ package body Sem_Util is Variant : Node_Id; Discrete_Choice : Node_Id; Comp_Item : Node_Id; + Discrim : Entity_Id; + Discrim_Name : Node_Id; - Discrim : Entity_Id; - Discrim_Name : Node_Id; - Discrim_Value : Node_Id; + type Discriminant_Value_Status is + (Static_Expr, Static_Subtype, Bad); + subtype Good_Discrim_Value_Status is Discriminant_Value_Status + range Static_Expr .. Static_Subtype; -- range excludes Bad + Discrim_Value : Node_Id; + Discrim_Value_Subtype : Node_Id; + Discrim_Value_Status : Discriminant_Value_Status := Bad; begin Report_Errors := False; @@ -9022,26 +9029,73 @@ package body Sem_Util is end loop Find_Constraint; Discrim_Value := Expression (Assoc); + if Is_OK_Static_Expression (Discrim_Value) then + Discrim_Value_Status := Static_Expr; + else + if Ada_Version >= Ada_2020 then + if Original_Node (Discrim_Value) /= Discrim_Value + and then Nkind (Discrim_Value) = N_Type_Conversion + and then Etype (Original_Node (Discrim_Value)) + = Etype (Expression (Discrim_Value)) + then + Discrim_Value_Subtype := Etype (Original_Node (Discrim_Value)); + -- An unhelpful (for this code) type conversion may be + -- introduced in some cases; deal with it. + else + Discrim_Value_Subtype := Etype (Discrim_Value); + end if; - if not Is_OK_Static_Expression (Discrim_Value) then + if Is_OK_Static_Subtype (Discrim_Value_Subtype) and then + not Is_Null_Range (Type_Low_Bound (Discrim_Value_Subtype), + Type_High_Bound (Discrim_Value_Subtype)) + then + -- Is_Null_Range test doesn't account for predicates, as in + -- subtype Null_By_Predicate is Natural + -- with Static_Predicate => Null_By_Predicate < 0; + -- so test for that null case separately. + + if (not Has_Static_Predicate (Discrim_Value_Subtype)) + or else Present (First (Static_Discrete_Predicate + (Discrim_Value_Subtype))) + then + Discrim_Value_Status := Static_Subtype; + end if; + end if; + end if; - -- If the variant part is governed by a discriminant of the type - -- this is an error. If the variant part and the discriminant are - -- inherited from an ancestor this is legal (AI05-120) unless the - -- components are being gathered for an aggregate, in which case - -- the caller must check Report_Errors. + if Discrim_Value_Status = Bad then - if Scope (Original_Record_Component - ((Entity (First (Choices (Assoc)))))) = Typ - then - Error_Msg_FE - ("value for discriminant & must be static!", - Discrim_Value, Discrim); - Why_Not_Static (Discrim_Value); - end if; + -- If the variant part is governed by a discriminant of the type + -- this is an error. If the variant part and the discriminant are + -- inherited from an ancestor this is legal (AI05-220) unless the + -- components are being gathered for an aggregate, in which case + -- the caller must check Report_Errors. + -- + -- In Ada2020 the above rules are relaxed. A non-static governing + -- discriminant is ok as long as it has a static subtype and + -- every value of that subtype (and there must be at least one) + -- selects the same variant. - Report_Errors := True; - return; + if Scope (Original_Record_Component + ((Entity (First (Choices (Assoc)))))) = Typ + then + if Ada_Version >= Ada_2020 then + Error_Msg_FE + ("value for discriminant & must be static or " & + "discriminant's nominal subtype must be static " & + "and non-null!", + Discrim_Value, Discrim); + else + Error_Msg_FE + ("value for discriminant & must be static!", + Discrim_Value, Discrim); + end if; + Why_Not_Static (Discrim_Value); + end if; + + Report_Errors := True; + return; + end if; end if; Search_For_Discriminant_Value : declare @@ -9050,9 +9104,36 @@ package body Sem_Util is UI_High : Uint; UI_Low : Uint; - UI_Discrim_Value : constant Uint := Expr_Value (Discrim_Value); + UI_Discrim_Value : Uint; begin + case Good_Discrim_Value_Status'(Discrim_Value_Status) is + when Static_Expr => + UI_Discrim_Value := Expr_Value (Discrim_Value); + when Static_Subtype => + -- Arbitrarily pick one value of the subtype and look + -- for the variant associated with that value; we will + -- check later that the same variant is associated with + -- all of the other values of the subtype. + if Has_Static_Predicate (Discrim_Value_Subtype) then + declare + Range_Or_Expr : constant Node_Id := + First (Static_Discrete_Predicate + (Discrim_Value_Subtype)); + begin + if Nkind (Range_Or_Expr) = N_Range then + UI_Discrim_Value := + Expr_Value (Low_Bound (Range_Or_Expr)); + else + UI_Discrim_Value := Expr_Value (Range_Or_Expr); + end if; + end; + else + UI_Discrim_Value + := Expr_Value (Type_Low_Bound (Discrim_Value_Subtype)); + end if; + end case; + Find_Discrete_Value : while Present (Variant) loop -- If a choice is a subtype with a static predicate, it must @@ -9085,7 +9166,7 @@ package body Sem_Util is -- The case statement must include a variant that corresponds to the -- value of the discriminant, unless the discriminant type has a -- static predicate. In that case the absence of an others_choice that - -- would cover this value becomes a run-time error (3.8,1 (21.1/2)). + -- would cover this value becomes a run-time error (3.8.1 (21.1/2)). if No (Variant) and then not Has_Static_Predicate (Etype (Discrim_Name)) @@ -9101,6 +9182,31 @@ package body Sem_Util is -- the same record type. if Present (Variant) then + if Discrim_Value_Status = Static_Subtype then + declare + Discrim_Value_Subtype_Intervals + : constant Interval_Lists.Discrete_Interval_List + := Interval_Lists.Type_Intervals (Discrim_Value_Subtype); + + Variant_Intervals + : constant Interval_Lists.Discrete_Interval_List + := Interval_Lists.Choice_List_Intervals + (Discrete_Choices => Discrete_Choices (Variant)); + begin + if not Interval_Lists.Is_Subset + (Subset => Discrim_Value_Subtype_Intervals, + Of_Set => Variant_Intervals) + then + Error_Msg_NE + ("no single variant is associated with all values of " & + "the subtype of discriminant value &", + Discrim_Value, Discrim); + Report_Errors := True; + return; + end if; + end; + end if; + Gather_Components (Typ, Component_List (Variant), Governed_By, Into, Report_Errors); end if; @@ -27117,6 +27223,367 @@ package body Sem_Util is end if; end Yields_Universal_Type; + package body Interval_Lists is + + function In_Interval + (Value : Uint; Interval : Discrete_Interval) return Boolean; + -- Does the given value lie within the given interval? + + ----------------- + -- In_Interval -- + ----------------- + function In_Interval + (Value : Uint; Interval : Discrete_Interval) return Boolean is + begin + return Value >= Interval.Low and then Value <= Interval.High; + end In_Interval; + + procedure Check_Consistency (Intervals : Discrete_Interval_List); + -- Check that list is sorted, lacks null intervals, and has gaps + -- between intervals. + + ------------------------ + -- Check_Consistency -- + ------------------------ + procedure Check_Consistency (Intervals : Discrete_Interval_List) is + begin + if Serious_Errors_Detected > 0 then + return; + end if; + + -- low bound is 1 and high bound equals length + pragma Assert (Intervals'First = 1 and Intervals'Last >= 0); + for Idx in Intervals'Range loop + -- each interval is non-null + pragma Assert (Intervals (Idx).Low <= Intervals (Idx).High); + if Idx /= Intervals'First then + -- intervals are sorted with non-empty gaps between them + pragma Assert + (Intervals (Idx - 1).High < (Intervals (Idx).Low - 1)); + null; + end if; + end loop; + end Check_Consistency; + + function Chosen_Interval (Choice : Node_Id) return Discrete_Interval; + -- Given an element of a Discrete_Choices list, a + -- Static_Discrete_Predicate list, or an Others_Discrete_Choices + -- list (but not an N_Others_Choice node) return the corresponding + -- interval. If an element that does not represent a single + -- contiguous interval due to a static predicate (or which + -- represents a single contiguous interval whose bounds depend on + -- a static predicate) is encountered, then that is an error on the + -- part of whoever built the list in question. + + --------------------- + -- Chosen_Interval -- + --------------------- + function Chosen_Interval (Choice : Node_Id) return Discrete_Interval is + begin + case Nkind (Choice) is + when N_Range => + return (Low => Expr_Value (Low_Bound (Choice)), + High => Expr_Value (High_Bound (Choice))); + + when N_Subtype_Indication => + declare + Range_Exp : constant Node_Id + := Range_Expression (Constraint (Choice)); + begin + return (Low => Expr_Value (Low_Bound (Range_Exp)), + High => Expr_Value (High_Bound (Range_Exp))); + end; + + when N_Others_Choice => + raise Program_Error; + + when others => + if Is_Entity_Name (Choice) and then Is_Type (Entity (Choice)) + then + return + (Low => Expr_Value (Type_Low_Bound (Entity (Choice))), + High => Expr_Value (Type_High_Bound (Entity (Choice)))); + else + -- an expression + return (Low | High => Expr_Value (Choice)); + end if; + end case; + end Chosen_Interval; + + -------------------- + -- Type_Intervals -- + -------------------- + function Type_Intervals + (Typ : Entity_Id) return Discrete_Interval_List + is + begin + if Has_Static_Predicate (Typ) then + declare + -- No sorting or merging needed + SDP_List : constant List_Id := Static_Discrete_Predicate (Typ); + Range_Or_Expr : Node_Id := First (SDP_List); + Result : + Discrete_Interval_List (1 .. List_Length (SDP_List)); + begin + for Idx in Result'Range loop + Result (Idx) := Chosen_Interval (Range_Or_Expr); + Range_Or_Expr := Next (Range_Or_Expr); + end loop; + pragma Assert (not Present (Range_Or_Expr)); + Check_Consistency (Result); + return Result; + end; + else + declare + Low : constant Uint := Expr_Value (Type_Low_Bound (Typ)); + High : constant Uint := Expr_Value (Type_High_Bound (Typ)); + begin + if Low > High then + declare + Null_Array : Discrete_Interval_List (1 .. 0); + begin + return Null_Array; + end; + else + return (1 => (Low => Low, High => High)); + end if; + end; + end if; + end Type_Intervals; + + procedure Normalize_Interval_List + (List : in out Discrete_Interval_List; Last : out Nat); + -- Perform sorting and merging as required by Check_Consistency. + + ----------------------------- + -- Normalize_Interval_List -- + ----------------------------- + procedure Normalize_Interval_List + (List : in out Discrete_Interval_List; Last : out Nat) is + + procedure Move_Interval (From, To : Natural); + -- Copy interval from one location to another + + function Lt_Interval (Idx1, Idx2 : Natural) return Boolean; + -- Compare two list elements + + Temp_0 : Discrete_Interval := (others => Uint_0); + -- cope with Heap_Sort_G idiosyncrasies. + + function Read_Interval (From : Natural) return Discrete_Interval; + -- Normal array indexing unless From = 0 + + ------------------- + -- Read_Interval -- + ------------------- + function Read_Interval (From : Natural) return Discrete_Interval is + begin + if From = 0 then + return Temp_0; + else + return List (Pos (From)); + end if; + end Read_Interval; + + ------------------- + -- Move_Interval -- + ------------------- + procedure Move_Interval (From, To : Natural) is + Rhs : constant Discrete_Interval := Read_Interval (From); + begin + if To = 0 then + Temp_0 := Rhs; + else + List (Pos (To)) := Rhs; + end if; + end Move_Interval; + + ----------------- + -- Lt_Interval -- + ----------------- + function Lt_Interval (Idx1, Idx2 : Natural) return Boolean is + Elem1 : constant Discrete_Interval := Read_Interval (Idx1); + Elem2 : constant Discrete_Interval := Read_Interval (Idx2); + Null_1 : constant Boolean := Elem1.Low > Elem1.High; + Null_2 : constant Boolean := Elem2.Low > Elem2.High; + begin + if Null_1 /= Null_2 then + -- So that sorting moves null intervals to high end + return Null_2; + elsif Elem1.Low /= Elem2.Low then + return Elem1.Low < Elem2.Low; + else + return Elem1.High < Elem2.High; + end if; + end Lt_Interval; + + package Interval_Sorting is + new Gnat.Heap_Sort_G (Move_Interval, Lt_Interval); + + function Is_Null (Idx : Pos) return Boolean; + -- True iff List (Idx) defines a null range + + function Is_Null (Idx : Pos) return Boolean is + begin + return List (Idx).Low > List (Idx).High; + end Is_Null; + + procedure Merge_Intervals (Null_Interval_Count : out Nat); + -- Merge contiguous ranges by replacing one with merged range + -- and the other with a null value. Return a count of the + -- null intervals, both preexisting and those introduced by + -- merging. + + --------------------- + -- Merge_Intervals -- + --------------------- + procedure Merge_Intervals (Null_Interval_Count : out Nat) is + Not_Null : Pos range List'Range; + -- Index of the most recently examined non-null interval + + Null_Interval : constant Discrete_Interval + := (Low => Uint_1, High => Uint_0); -- any null range ok here + begin + if List'Length = 0 or else Is_Null (List'First) then + Null_Interval_Count := List'Length; + -- no non-null elements, so no merge candidates + return; + end if; + + Null_Interval_Count := 0; + Not_Null := List'First; + for Idx in List'First + 1 .. List'Last loop + if Is_Null (Idx) then + -- all remaining elements are null + Null_Interval_Count := + Null_Interval_Count + List (Idx .. List'Last)'Length; + return; + elsif List (Idx).Low = List (Not_Null).High + 1 then + -- Merge the two intervals into one; discard the other + List (Not_Null).High := List (Idx).High; + List (Idx) := Null_Interval; + Null_Interval_Count := Null_Interval_Count + 1; + else + pragma Assert (List (Idx).Low > List (Not_Null).High); + Not_Null := Idx; + end if; + end loop; + end Merge_Intervals; + begin + Interval_Sorting.Sort (Natural (List'Last)); + declare + Null_Interval_Count : Nat; + begin + Merge_Intervals (Null_Interval_Count); + Last := List'Last - Null_Interval_Count; + if Null_Interval_Count /= 0 then + -- Move null intervals introduced during merging to high end + Interval_Sorting.Sort (Natural (List'Last)); + end if; + end; + end Normalize_Interval_List; + + --------------------------- + -- Choice_List_Intervals -- + --------------------------- + function Choice_List_Intervals + (Discrete_Choices : List_Id) return Discrete_Interval_List + is + function Unmerged_Choice_Count return Nat; + -- The number of intervals before adjacent intervals are merged. + + --------------------------- + -- Unmerged_Choice_Count -- + --------------------------- + function Unmerged_Choice_Count return Nat is + Choice : Node_Id := First (Discrete_Choices); + Count : Nat := 0; + begin + while Present (Choice) loop + -- Non-contiguous choices involving static predicates + -- have already been normalized away. + + if Nkind (Choice) = N_Others_Choice then + Count := + Count + List_Length (Others_Discrete_Choices (Choice)); + else + Count := Count + 1; -- an ordinary expression or range + end if; + + Choice := Next (Choice); + end loop; + return Count; + end Unmerged_Choice_Count; + + Choice : Node_Id := First (Discrete_Choices); + Result : Discrete_Interval_List (1 .. Unmerged_Choice_Count); + Count : Nat := 0; + begin + while Present (Choice) loop + if Nkind (Choice) = N_Others_Choice then + declare + Others_Choice : Node_Id + := First (Others_Discrete_Choices (Choice)); + begin + while Present (Others_Choice) loop + Count := Count + 1; + Result (Count) := Chosen_Interval (Others_Choice); + Others_Choice := Next (Others_Choice); + end loop; + end; + else + Count := Count + 1; + Result (Count) := Chosen_Interval (Choice); + end if; + Choice := Next (Choice); + end loop; + pragma Assert (Count = Result'Last); + Normalize_Interval_List (Result, Count); + Check_Consistency (Result (1 .. Count)); + return Result (1 .. Count); + end Choice_List_Intervals; + + --------------- + -- Is_Subset -- + --------------- + function Is_Subset + (Subset, Of_Set : Discrete_Interval_List) return Boolean + is + -- Returns True iff for each interval of Subset we can find + -- a single interval of Of_Set which contains the Subset interval. + begin + if Of_Set'Length = 0 then + return Subset'Length = 0; + end if; + + declare + Set_Index : Pos range Of_Set'Range := Of_Set'First; + begin + for Ss_Idx in Subset'Range loop + while not In_Interval + (Value => Subset (Ss_Idx).Low, + Interval => Of_Set (Set_Index)) + loop + if Set_Index = Of_Set'Last then + return False; + end if; + Set_Index := Set_Index + 1; + end loop; + + if not In_Interval + (Value => Subset (Ss_Idx).High, + Interval => Of_Set (Set_Index)) + then + return False; + end if; + end loop; + end; + + return True; + end Is_Subset; + + end Interval_Lists; + begin Erroutc.Subprogram_Name_Ptr := Subprogram_Name'Access; end Sem_Util; diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads index 2d1bcf0..c77f441 100644 --- a/gcc/ada/sem_util.ads +++ b/gcc/ada/sem_util.ads @@ -2965,4 +2965,40 @@ package Sem_Util is function Yields_Universal_Type (N : Node_Id) return Boolean; -- Determine whether unanalyzed node N yields a universal type + package Interval_Lists is + type Discrete_Interval is + record + Low, High : Uint; + end record; + + type Discrete_Interval_List is + array (Pos range <>) of Discrete_Interval; + -- A sorted (in ascending order) list of non-empty pairwise-disjoint + -- intervals, always with a gap of at least one value between + -- successive intervals (i.e., mergeable intervals are merged). + -- Low bound is one; high bound is nonnegative. + + function Type_Intervals (Typ : Entity_Id) return Discrete_Interval_List; + -- Given a static discrete type or subtype, returns the (unique) + -- interval list representing the values of the type/subtype. + -- If no static predicates are involved, the length of the result + -- will be at most one. + + function Choice_List_Intervals (Discrete_Choices : List_Id) + return Discrete_Interval_List; + -- Given a discrete choice list, returns the (unique) interval + -- list representing the chosen values.. + + function Is_Subset (Subset, Of_Set : Discrete_Interval_List) + return Boolean; + -- Returns True iff every value belonging to some interval of + -- Subset also belongs to some interval of Of_Set. + + -- TBD: When we get around to implementing "is statically compatible" + -- correctly for real types with static predicates, we may need + -- an analogous Real_Interval_List type. Most of the language + -- rules that reference "is statically compatible" pertain to + -- discriminants and therefore do require support for real types; + -- the exception is 12.5.1(8). + end Interval_Lists; end Sem_Util; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8951eb6..fd0efb1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-09-18 Steve Baird + + * gnat.dg/ai12_0086_example.adb: New testcase. + 2019-09-18 Nicolas Roche * gnat.dg/float_value2.adb: New testcase. diff --git a/gcc/testsuite/gnat.dg/ai12_0086_example.adb b/gcc/testsuite/gnat.dg/ai12_0086_example.adb new file mode 100644 index 0000000..4ea6f6a --- /dev/null +++ b/gcc/testsuite/gnat.dg/ai12_0086_example.adb @@ -0,0 +1,24 @@ +-- { dg-do compile } +-- { dg-options "-gnatX" } + +procedure AI12_0086_Example is + type Enum is (Aa, Bb, Cc, Dd, Ee, Ff, Gg, Hh, Ii, Jj, Kk, Ll, MM, + Nn, Oo, Pp, Qq, Rr, Ss, Tt, Uu, Vv, Ww, Xx, Yy, Zz); + subtype S is Enum range Dd .. Hh; + + type Rec (D : Enum) is record + case D is + when S => Foo, Bar : Integer; + when others => null; + end case; + end record; + + function Make (D : S) return Rec is + begin + return (D => D, Foo => 123, Bar => 456); -- legal + end; +begin + if Make (Ff).Bar /= 456 then + raise Program_Error; + end if; +end AI12_0086_Example; \ No newline at end of file -- cgit v1.1 From 43b264110f5581af0cc93308f9433fe8053f01cc Mon Sep 17 00:00:00 2001 From: Justin Squirek Date: Wed, 18 Sep 2019 08:33:07 +0000 Subject: [Ada] Spurious run time error on anonymous access formals This patch fixes an issue whereby subprograms with anonymous access formals may trigger spurious runtime accessibility errors when such formals are used as actuals in calls to nested subprograms. Running these commands: gnatmake -q pass.adb gnatmake -q fail.adb gnatmake -q test_main.adb gnatmake -q indirect_call_test.adb pass fail test_main indirect_call_test On the following sources: -- pass.adb procedure Pass is function A (Param : access Integer) return Boolean is type Typ is access all Integer; function A_Inner (Param : access Integer) return Typ is begin return Typ (Param); -- OK end; begin return A_Inner (Param) = Typ (Param); end; function B (Param : access Integer) return Boolean; function B (Param : access Integer) return Boolean is type Typ is access all Integer; function B_Inner (Param : access Integer) return Typ is begin return Typ (Param); -- OK end; begin return B_Inner (Param) = Typ (Param); end; procedure C (Param : access Integer) is type Typ is access all Integer; Var : Typ; procedure C_Inner (Param : access Integer) is begin Var := Typ (Param); -- OK end; begin C_Inner (Param); end; procedure D (Param : access Integer); procedure D (Param : access Integer) is type Typ is access all Integer; Var : Typ; procedure D_Inner (Param : access Integer) is begin Var := Typ (Param); -- OK end; begin D_Inner (Param); end; protected type E is function G (Param : access Integer) return Boolean; procedure I (Param : access Integer); end; protected body E is function F (Param : access Integer) return Boolean is type Typ is access all Integer; function F_Inner (Param : access Integer) return Typ is begin return Typ (Param); -- OK end; begin return F_Inner (Param) = Typ (Param); end; function G (Param : access Integer) return Boolean is type Typ is access all Integer; function G_Inner (Param : access Integer) return Typ is begin return Typ (Param); -- OK end; B : Boolean := F (Param); -- OK begin return G_Inner (Param) = Typ (Param); end; procedure H (Param : access Integer) is type Typ is access all Integer; Var : Typ; procedure H_Inner (Param : access Integer) is begin Var := Typ (Param); -- OK end; begin H_Inner (Param); end; procedure I (Param : access Integer) is type Typ is access all Integer; Var : Typ; procedure I_Inner (Param : access Integer) is begin Var := Typ (Param); -- OK end; begin H (Param); -- OK I_Inner (Param); end; end; task type J is end; task body J is function K (Param : access Integer) return Boolean is type Typ is access all Integer; function K_Inner (Param : access Integer) return Typ is begin return Typ (Param); -- OK end; begin return K_Inner (Param) = Typ (Param); end; function L (Param : access Integer) return Boolean; function L (Param : access Integer) return Boolean is type Typ is access all Integer; function L_Inner (Param : access Integer) return Typ is begin return Typ (Param); -- OK end; begin return L_Inner (Param) = Typ (Param); end; procedure M (Param : access Integer) is type Typ is access all Integer; Var : Typ; procedure M_Inner (Param : access Integer) is begin Var := Typ (Param); -- OK end; begin M_Inner (Param); end; procedure N (Param : access Integer); procedure N (Param : access Integer) is type Typ is access all Integer; Var : Typ; procedure N_Inner (Param : access Integer) is begin Var := Typ (Param); -- OK end; begin N_Inner (Param); end; Var : aliased Integer := 666; begin if K (Var'Access) then null; end if; -- OK if L (Var'Access) then null; end if; -- OK M (Var'Access); -- OK N (Var'Access); -- OK end; begin begin begin declare Var : aliased Integer := 666; T : J; Prot : E; begin if A (Var'Access) then null; end if; -- OK if B (Var'Access) then null; end if; -- OK C (Var'Access); -- OK D (Var'Access); -- OK if Prot.G (Var'Access) then null; end if; -- OK Prot.I (Var'Access); -- OK end; end; end; end; -- fail.adb procedure Fail is Failures : Integer := 0; type Base_Typ is access all Integer; function A (Param : access Integer) return Boolean is subtype Typ is Base_Typ; function A_Inner (Param : access Integer) return Typ is begin return Typ (Param); -- ERROR end; begin return A_Inner (Param) = Typ (Param); exception when others => Failures := Failures + 1; return False; end; function B (Param : access Integer) return Boolean; function B (Param : access Integer) return Boolean is subtype Typ is Base_Typ; function B_Inner (Param : access Integer) return Typ is begin return Typ (Param); -- ERROR end; begin return B_Inner (Param) = Typ (Param); exception when others => Failures := Failures + 1; return False; end; procedure C (Param : access Integer) is subtype Typ is Base_Typ; Var : Typ; procedure C_Inner (Param : access Integer) is begin Var := Typ (Param); -- ERROR end; begin C_Inner (Param); exception when others => Failures := Failures + 1; end; procedure D (Param : access Integer); procedure D (Param : access Integer) is subtype Typ is Base_Typ; Var : Typ; procedure D_Inner (Param : access Integer) is begin Var := Typ (Param); -- ERROR end; begin D_Inner (Param); exception when others => Failures := Failures + 1; end; protected type E is function G (Param : access Integer) return Boolean; procedure I (Param : access Integer); end; protected body E is function F (Param : access Integer) return Boolean is subtype Typ is Base_Typ; function F_Inner (Param : access Integer) return Typ is begin return Typ (Param); -- ERROR end; begin return F_Inner (Param) = Typ (Param); exception when others => Failures := Failures + 1; return False; end; function G (Param : access Integer) return Boolean is subtype Typ is Base_Typ; function G_Inner (Param : access Integer) return Typ is begin return Typ (Param); -- ERROR end; B : Boolean := F (Param); -- ERROR begin return G_Inner (Param) = Typ (Param); exception when others => Failures := Failures + 1; return False; end; procedure H (Param : access Integer) is subtype Typ is Base_Typ; Var : Typ; procedure H_Inner (Param : access Integer) is begin Var := Typ (Param); -- ERROR end; begin H_Inner (Param); exception when others => Failures := Failures + 1; end; procedure I (Param : access Integer) is subtype Typ is Base_Typ; Var : Typ; procedure I_Inner (Param : access Integer) is begin Var := Typ (Param); -- ERROR end; begin H (Param); -- ERROR I_Inner (Param); exception when others => Failures := Failures + 1; end; end; task type J is end; task body J is function K (Param : access Integer) return Boolean is subtype Typ is Base_Typ; function K_Inner (Param : access Integer) return Typ is begin return Typ (Param); -- ERROR end; begin return K_Inner (Param) = Typ (Param); exception when others => Failures := Failures + 1; return False; end; function L (Param : access Integer) return Boolean; function L (Param : access Integer) return Boolean is subtype Typ is Base_Typ; function L_Inner (Param : access Integer) return Typ is begin return Typ (Param); -- ERROR end; begin return L_Inner (Param) = Typ (Param); exception when others => Failures := Failures + 1; return False; end; procedure M (Param : access Integer) is subtype Typ is Base_Typ; Var : Typ; procedure M_Inner (Param : access Integer) is begin Var := Typ (Param); -- ERROR end; begin M_Inner (Param); exception when others => Failures := Failures + 1; end; procedure N (Param : access Integer); procedure N (Param : access Integer) is subtype Typ is Base_Typ; Var : Typ; procedure N_Inner (Param : access Integer) is begin Var := Typ (Param); -- ERROR end; begin N_Inner (Param); exception when others => Failures := Failures + 1; end; Var : aliased Integer := 666; begin if K (Var'Access) then null; end if; -- ERROR if L (Var'Access) then null; end if; -- ERROR M (Var'Access); -- ERROR N (Var'Access); -- ERROR end; begin begin begin declare Var : aliased Integer := 666; T : J; Prot : E; begin if A (Var'Access) then null; end if; -- ERROR if B (Var'Access) then null; end if; -- ERROR C (Var'Access); -- ERROR D (Var'Access); -- ERROR if Prot.G (Var'Access) then null; end if; -- ERROR Prot.I (Var'Access); -- ERROR if Failures /= 12 then raise Program_Error; end if; end; end; end; end; -- indirect_call_test.adb with Text_IO; procedure Indirect_Call_Test is Tracing_Enabled : constant Boolean := False; procedure Trace (S : String) is begin if Tracing_Enabled then Text_IO.Put_Line (S); end if; end; package Pkg is type Root is abstract tagged null record; function F (X : Root; Param : access Integer) return Boolean is abstract; end Pkg; function F_Wrapper (X : Pkg.Root; Param : access Integer) return Boolean is (Pkg.F (Pkg.Root'Class (X), Param)); -- dispatching call function A (Param : access Integer) return Boolean is type Typ is access all Integer; package Nested is type Ext is new Pkg.Root with null record; overriding function F (X : Ext; Param : access Integer) return Boolean; end Nested; function A_Inner (Param : access Integer) return Typ is begin return Typ (Param); -- OK end A_Inner; package body Nested is function F (X : Ext; Param : access Integer) return Boolean is begin return A_Inner (Param) = null; end; end; Ext_Obj : Nested.Ext; begin Trace ("In subtest A"); return F_Wrapper (Pkg.Root (Ext_Obj), Param); exception when Program_Error => Trace ("Failed"); return True; end A; function B (Param : access Integer) return Boolean is type Typ is access all Integer; function B_Inner (Param : access Integer) return Typ is begin return Typ (Param); -- OK end B_Inner; type Ref is access function (Param : access Integer) return Typ; Ptr : Ref := B_Inner'Access; function Ptr_Caller return Typ is (Ptr.all (Param)); -- access-to-subp value begin Trace ("In subtest B"); return Ptr_Caller = null; exception when Program_Error => Trace ("*** failed"); return True; end B; begin begin begin declare Var : aliased Integer := 666; begin if A (Var'Access) then null; end if; Trace ("Subtest A done"); if B (Var'Access) then null; end if; Trace ("Subtest B done"); end; end; end; end Indirect_Call_Test; Should produce the following output: Failure Failure Failure Failure Failure Failure Failure Failure Failure Failure Failure Failure Failure Failure Failure Failure Failure Failure Failure Failure Failure Failure Failure Failure 2019-09-18 Justin Squirek gcc/ada/ * einfo.adb, einfo.ads (Minimum_Accessibility): Added new field. (Set_Minimum_Accessibility): Added to set new field. (Minimum_Accessibility): Added to fetch new field. * exp_ch6.adb (Expand_Subprogram_Call): Modify calls to fetch accessibility levels to the new subprogram Get_Accessibility which handles cases where minimum accessibility might be needed. * sem_ch6.adb (Analyze_Subprogram_Body_Helper): Add section to generate a Minimum_Accessibility object within relevant subprograms. * sem_util.adb, sem_util.ads (Dynamic_Accessibility_Level): Additional documentation added and modify section to use new function Get_Accessibility. (Get_Accessibility): Added to centralize processing of accessibility levels. From-SVN: r275858 --- gcc/ada/ChangeLog | 17 ++++++++ gcc/ada/einfo.adb | 16 +++++++ gcc/ada/einfo.ads | 13 ++++++ gcc/ada/exp_ch6.adb | 34 +++++++-------- gcc/ada/sem_ch6.adb | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++ gcc/ada/sem_util.adb | 33 ++++++++++++-- gcc/ada/sem_util.ads | 4 ++ 7 files changed, 216 insertions(+), 21 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 452243a..384f982 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,20 @@ +2019-09-18 Justin Squirek + + * einfo.adb, einfo.ads (Minimum_Accessibility): Added new field. + (Set_Minimum_Accessibility): Added to set new field. + (Minimum_Accessibility): Added to fetch new field. + * exp_ch6.adb (Expand_Subprogram_Call): Modify calls to fetch + accessibility levels to the new subprogram Get_Accessibility + which handles cases where minimum accessibility might be needed. + * sem_ch6.adb (Analyze_Subprogram_Body_Helper): Add section to + generate a Minimum_Accessibility object within relevant + subprograms. + * sem_util.adb, sem_util.ads (Dynamic_Accessibility_Level): + Additional documentation added and modify section to use new + function Get_Accessibility. + (Get_Accessibility): Added to centralize processing of + accessibility levels. + 2019-09-18 Steve Baird * sem_util.ads (Interval_Lists): A new visible package. This diff --git a/gcc/ada/einfo.adb b/gcc/ada/einfo.adb index ebef3a0..dcbeac5 100644 --- a/gcc/ada/einfo.adb +++ b/gcc/ada/einfo.adb @@ -215,6 +215,7 @@ package body Einfo is -- Stored_Constraint Elist23 -- Incomplete_Actuals Elist24 + -- Minimum_Accessibility Node24 -- Related_Expression Node24 -- Subps_Index Uint24 @@ -2847,6 +2848,12 @@ package body Einfo is return UI_To_Int (Uint8 (Id)); end Mechanism; + function Minimum_Accessibility (Id : E) return E is + begin + pragma Assert (Ekind (Id) in Formal_Kind); + return Node24 (Id); + end Minimum_Accessibility; + function Modulus (Id : E) return Uint is begin pragma Assert (Is_Modular_Integer_Type (Id)); @@ -6076,6 +6083,12 @@ package body Einfo is Set_Uint8 (Id, UI_From_Int (V)); end Set_Mechanism; + procedure Set_Minimum_Accessibility (Id : E; V : E) is + begin + pragma Assert (Ekind (Id) in Formal_Kind); + Set_Node24 (Id, V); + end Set_Minimum_Accessibility; + procedure Set_Modulus (Id : E; V : U) is begin pragma Assert (Ekind (Id) = E_Modular_Integer_Type); @@ -10913,6 +10926,9 @@ package body Einfo is => Write_Str ("Related_Expression"); + when Formal_Kind => + Write_Str ("Minimum_Accessibility"); + when E_Function | E_Operator | E_Procedure diff --git a/gcc/ada/einfo.ads b/gcc/ada/einfo.ads index e93a837..3e968a2 100644 --- a/gcc/ada/einfo.ads +++ b/gcc/ada/einfo.ads @@ -3516,6 +3516,14 @@ package Einfo is -- is also set (to the default value of zero = Default_Mechanism) in a -- subprogram body entity but not used in this context. +-- Minimum_Accessibility (Node24) +-- Defined in formal parameters in the non-generic case. Normally Empty, +-- but if expansion is active, and a parameter exists for which a +-- dynamic accessibility check is required, then an object is generated +-- within such a subprogram representing the accessibility level of the +-- subprogram or the formal's Extra_Accessibility - whichever one is +-- lesser. The Minimum_Accessibility field then points to this object. + -- Modulus (Uint17) [base type only] -- Defined in modular types. Contains the modulus. For the binary case, -- this will be a power of 2, but if Non_Binary_Modulus is set, then it @@ -6273,6 +6281,7 @@ package Einfo is -- Default_Expr_Function (Node21) -- Protected_Formal (Node22) -- Extra_Constrained (Node23) + -- Minimum_Accessibility (Node24) -- Last_Assignment (Node26) (OUT, IN-OUT only) -- Activation_Record_Component (Node31) -- Has_Initial_Value (Flag219) @@ -7398,6 +7407,7 @@ package Einfo is function Materialize_Entity (Id : E) return B; function May_Inherit_Delayed_Rep_Aspects (Id : E) return B; function Mechanism (Id : E) return M; + function Minimum_Accessibility (Id : E) return E; function Modulus (Id : E) return U; function Must_Be_On_Byte_Boundary (Id : E) return B; function Must_Have_Preelab_Init (Id : E) return B; @@ -8103,6 +8113,7 @@ package Einfo is procedure Set_Materialize_Entity (Id : E; V : B := True); procedure Set_May_Inherit_Delayed_Rep_Aspects (Id : E; V : B := True); procedure Set_Mechanism (Id : E; V : M); + procedure Set_Minimum_Accessibility (Id : E; V : E); procedure Set_Modulus (Id : E; V : U); procedure Set_Must_Be_On_Byte_Boundary (Id : E; V : B := True); procedure Set_Must_Have_Preelab_Init (Id : E; V : B := True); @@ -8973,6 +8984,7 @@ package Einfo is pragma Inline (Materialize_Entity); pragma Inline (May_Inherit_Delayed_Rep_Aspects); pragma Inline (Mechanism); + pragma Inline (Minimum_Accessibility); pragma Inline (Modulus); pragma Inline (Must_Be_On_Byte_Boundary); pragma Inline (Must_Have_Preelab_Init); @@ -9466,6 +9478,7 @@ package Einfo is pragma Inline (Set_Materialize_Entity); pragma Inline (Set_May_Inherit_Delayed_Rep_Aspects); pragma Inline (Set_Mechanism); + pragma Inline (Set_Minimum_Accessibility); pragma Inline (Set_Modulus); pragma Inline (Set_Must_Be_On_Byte_Boundary); pragma Inline (Set_Must_Have_Preelab_Init); diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb index 3277b46..78a1496 100644 --- a/gcc/ada/exp_ch6.adb +++ b/gcc/ada/exp_ch6.adb @@ -3221,7 +3221,7 @@ package body Exp_Ch6 is -- Create possible extra actual for accessibility level - if Present (Extra_Accessibility (Formal)) then + if Present (Get_Accessibility (Formal)) then -- Ada 2005 (AI-252): If the actual was rewritten as an Access -- attribute, then the original actual may be an aliased object @@ -3297,8 +3297,8 @@ package body Exp_Ch6 is Add_Extra_Actual (Expr => - New_Occurrence_Of (Extra_Accessibility (Parm_Ent), Loc), - EF => Extra_Accessibility (Formal)); + New_Occurrence_Of (Get_Accessibility (Parm_Ent), Loc), + EF => Get_Accessibility (Formal)); end; elsif Is_Entity_Name (Prev_Orig) then @@ -3327,12 +3327,12 @@ package body Exp_Ch6 is begin pragma Assert (Present (Parm_Ent)); - if Present (Extra_Accessibility (Parm_Ent)) then + if Present (Get_Accessibility (Parm_Ent)) then Add_Extra_Actual (Expr => New_Occurrence_Of - (Extra_Accessibility (Parm_Ent), Loc), - EF => Extra_Accessibility (Formal)); + (Get_Accessibility (Parm_Ent), Loc), + EF => Get_Accessibility (Formal)); -- If the actual access parameter does not have an -- associated extra formal providing its scope level, @@ -3344,7 +3344,7 @@ package body Exp_Ch6 is (Expr => Make_Integer_Literal (Loc, Intval => Scope_Depth (Standard_Standard)), - EF => Extra_Accessibility (Formal)); + EF => Get_Accessibility (Formal)); end if; end; @@ -3354,7 +3354,7 @@ package body Exp_Ch6 is else Add_Extra_Actual (Expr => Dynamic_Accessibility_Level (Prev_Orig), - EF => Extra_Accessibility (Formal)); + EF => Get_Accessibility (Formal)); end if; -- If the actual is an access discriminant, then pass the level @@ -3370,7 +3370,7 @@ package body Exp_Ch6 is (Expr => Make_Integer_Literal (Loc, Intval => Object_Access_Level (Prefix (Prev_Orig))), - EF => Extra_Accessibility (Formal)); + EF => Get_Accessibility (Formal)); -- All other cases @@ -3440,19 +3440,19 @@ package body Exp_Ch6 is Make_Integer_Literal (Loc, Intval => Type_Access_Level (Pref_Entity)), - EF => Extra_Accessibility (Formal)); + EF => Get_Accessibility (Formal)); elsif Nkind (Prev_Orig) = N_Explicit_Dereference and then Present (Pref_Entity) and then Is_Formal (Pref_Entity) and then Present - (Extra_Accessibility (Pref_Entity)) + (Get_Accessibility (Pref_Entity)) then Add_Extra_Actual (Expr => New_Occurrence_Of - (Extra_Accessibility (Pref_Entity), Loc), - EF => Extra_Accessibility (Formal)); + (Get_Accessibility (Pref_Entity), Loc), + EF => Get_Accessibility (Formal)); else Add_Extra_Actual @@ -3460,7 +3460,7 @@ package body Exp_Ch6 is Make_Integer_Literal (Loc, Intval => Object_Access_Level (Prev_Orig)), - EF => Extra_Accessibility (Formal)); + EF => Get_Accessibility (Formal)); end if; -- Treat the unchecked attributes as library-level @@ -3472,7 +3472,7 @@ package body Exp_Ch6 is (Expr => Make_Integer_Literal (Loc, Intval => Scope_Depth (Standard_Standard)), - EF => Extra_Accessibility (Formal)); + EF => Get_Accessibility (Formal)); -- No other cases of attributes returning access -- values that can be passed to access parameters. @@ -3494,7 +3494,7 @@ package body Exp_Ch6 is (Expr => Make_Integer_Literal (Loc, Intval => Scope_Depth (Current_Scope) + 1), - EF => Extra_Accessibility (Formal)); + EF => Get_Accessibility (Formal)); -- For most other cases we simply pass the level of the -- actual's access type. The type is retrieved from @@ -3505,7 +3505,7 @@ package body Exp_Ch6 is when others => Add_Extra_Actual (Expr => Dynamic_Accessibility_Level (Prev), - EF => Extra_Accessibility (Formal)); + EF => Get_Accessibility (Formal)); end case; end if; end if; diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb index ddb12ec..eb6768d 100644 --- a/gcc/ada/sem_ch6.adb +++ b/gcc/ada/sem_ch6.adb @@ -3376,6 +3376,9 @@ package body Sem_Ch6 is -- Local variables + Body_Nod : Node_Id := Empty; + Minimum_Acc_Objs : List_Id := No_List; + Saved_GM : constant Ghost_Mode_Type := Ghost_Mode; Saved_IGR : constant Node_Id := Ignored_Ghost_Region; Saved_EA : constant Boolean := Expander_Active; @@ -4254,6 +4257,110 @@ package body Sem_Ch6 is end; end if; + -- Generate minimum accessibility local objects to correspond with + -- any extra formal added for anonymous access types. This new local + -- object can then be used instead of the formal in case it is used + -- in an actual to a call to a nested subprogram. + + -- This method is used to suppliment our "small integer model" for + -- accessibility check generation (for more information see + -- Dynamic_Accessibility_Level). + + -- Because we allow accesibility values greater than our expected value + -- passing along the same extra accessibility formal as an actual + -- to a nested subprogram becomes a problem because high values mean + -- different things to the callee even though they are the same to the + -- caller. So, as described in the first section, we create a local + -- object representing the minimum of the accessibility level value that + -- is passed in and the accessibility level of the callee's parameter + -- and locals and use it in the case of a call to a nested subprogram. + -- This generated object is refered to as a "minimum accessiblity + -- level." + + if Present (Spec_Id) or else Present (Body_Id) then + Body_Nod := Unit_Declaration_Node (Body_Id); + + declare + Form : Entity_Id; + begin + -- Grab the appropriate formal depending on whether there exists + -- an actual spec for the subprogram or whether we are dealing + -- with a protected subprogram. + + if Present (Spec_Id) then + if Present (Protected_Body_Subprogram (Spec_Id)) then + Form := First_Formal (Protected_Body_Subprogram (Spec_Id)); + else + Form := First_Formal (Spec_Id); + end if; + else + Form := First_Formal (Body_Id); + end if; + + -- Loop through formals if the subprogram is capable of accepting + -- a generated local object. If it is not then it is also not + -- capable of having local subprograms meaning it would not need + -- a minimum accessibility level object anyway. + + if Present (Body_Nod) + and then Has_Declarations (Body_Nod) + and then Nkind (Body_Nod) /= N_Package_Specification + then + while Present (Form) loop + + if Present (Extra_Accessibility (Form)) + and then No (Minimum_Accessibility (Form)) + then + -- Generate the minimum accessibility level object + + -- A60b : integer := integer'min(2, paramL); + + declare + Loc : constant Source_Ptr := Sloc (Body_Nod); + Obj_Node : constant Node_Id := + Make_Object_Declaration (Loc, + Defining_Identifier => + Make_Temporary + (Loc, 'A', Extra_Accessibility (Form)), + Object_Definition => New_Occurrence_Of + (Standard_Integer, Loc), + Expression => + Make_Attribute_Reference (Loc, + Prefix => New_Occurrence_Of + (Standard_Integer, Loc), + Attribute_Name => Name_Min, + Expressions => New_List ( + Make_Integer_Literal (Loc, + Object_Access_Level (Form)), + New_Occurrence_Of + (Extra_Accessibility (Form), Loc)))); + begin + -- Add the new local object to the Minimum_Acc_Obj to + -- be later prepended to the subprogram's list of + -- declarations after we are sure all expansion is + -- done. + + if Present (Minimum_Acc_Objs) then + Prepend (Obj_Node, Minimum_Acc_Objs); + else + Minimum_Acc_Objs := New_List (Obj_Node); + end if; + + -- Register the object and analyze it + + Set_Minimum_Accessibility + (Form, Defining_Identifier (Obj_Node)); + + Analyze (Obj_Node); + end; + end if; + + Next_Formal (Form); + end loop; + end if; + end; + end if; + -- Now we can go on to analyze the body HSS := Handled_Statement_Sequence (N); @@ -4358,6 +4465,19 @@ package body Sem_Ch6 is Inspect_Deferred_Constant_Completion (Declarations (N)); Analyze (HSS); + -- Add the generated minimum accessibility objects to the subprogram + -- body's list of declarations after analysis of the statements and + -- contracts. + + while Is_Non_Empty_List (Minimum_Acc_Objs) loop + if Present (Declarations (Body_Nod)) then + Prepend (Remove_Head (Minimum_Acc_Objs), Declarations (Body_Nod)); + else + Set_Declarations + (Body_Nod, New_List (Remove_Head (Minimum_Acc_Objs))); + end if; + end loop; + -- Deal with end of scope processing for the body Process_End_Label (HSS, 't', Current_Scope); diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb index 13555a5..1bcda5f 100644 --- a/gcc/ada/sem_util.adb +++ b/gcc/ada/sem_util.adb @@ -6531,10 +6531,11 @@ package body Sem_Util is return Dynamic_Accessibility_Level (Renamed_Object (E)); end if; - if Is_Formal (E) or else Ekind_In (E, E_Variable, E_Constant) then - if Present (Extra_Accessibility (E)) then - return New_Occurrence_Of (Extra_Accessibility (E), Loc); - end if; + if (Is_Formal (E) + or else Ekind_In (E, E_Variable, E_Constant)) + and then Present (Get_Accessibility (E)) + then + return New_Occurrence_Of (Get_Accessibility (E), Loc); end if; end if; @@ -9212,6 +9213,30 @@ package body Sem_Util is end if; end Gather_Components; + ----------------------- + -- Get_Accessibility -- + ----------------------- + + function Get_Accessibility (E : Entity_Id) return Node_Id is + begin + -- When minimum accessibility is set for E then we utilize it - except + -- in a few edge cases like the expansion of select statements where + -- generated subprogram may attempt to unnecessarily use a minimum + -- accessibility object declared outside of scope. + + -- To avoid these situations where expansion may get complex we verify + -- that the minimum accessibility object is within scope. + + if Ekind (E) in Formal_Kind + and then Present (Minimum_Accessibility (E)) + and then In_Open_Scopes (Scope (Minimum_Accessibility (E))) + then + return Minimum_Accessibility (E); + end if; + + return Extra_Accessibility (E); + end Get_Accessibility; + ------------------------ -- Get_Actual_Subtype -- ------------------------ diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads index c77f441..b41b875 100644 --- a/gcc/ada/sem_util.ads +++ b/gcc/ada/sem_util.ads @@ -983,6 +983,10 @@ package Sem_Util is -- discriminants. Otherwise all components of the parent must be included -- in the subtype for semantic analysis. + function Get_Accessibility (E : Entity_Id) return Node_Id; + -- Obtain the accessibility level for a given entity formal taking into + -- account both extra and minimum accessibility. + function Get_Actual_Subtype (N : Node_Id) return Entity_Id; -- Given a node for an expression, obtain the actual subtype of the -- expression. In the case of a parameter where the formal is an -- cgit v1.1 From 6951cbc9e7646bca1c99c973815e6838a6e1fe25 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Wed, 18 Sep 2019 08:33:12 +0000 Subject: [Ada] Fix sharing of expression in array aggregate with others choice This change fixes a long-standing issue in the compiler that is generally silent but may lead to wrong code generation in specific circumstances. When an others choice in an array aggregate spans multiple ranges, the compiler may generate multiple (groups of) assignments for the ranges. The problem is that it internally reuses the original expression for all the ranges, which is problematic if this expression gets rewritten during the processing of one of the ranges and typically causes a new temporary to be shared between different ranges. The solution is to duplicate the original expression for each range. 2019-09-18 Eric Botcazou gcc/ada/ * exp_aggr.adb (Build_Array_Aggr_Code): In STEP 1 (c), duplicate the expression and reset the Loop_Actions for each loop generated for an others choice. gcc/testsuite/ * gnat.dg/aggr28.adb: New testcase. From-SVN: r275859 --- gcc/ada/ChangeLog | 6 ++++++ gcc/ada/exp_aggr.adb | 18 ++++++++++++++---- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gnat.dg/aggr28.adb | 29 +++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/aggr28.adb (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 384f982..5c17f81 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,9 @@ +2019-09-18 Eric Botcazou + + * exp_aggr.adb (Build_Array_Aggr_Code): In STEP 1 (c), duplicate + the expression and reset the Loop_Actions for each loop + generated for an others choice. + 2019-09-18 Justin Squirek * einfo.adb, einfo.ads (Minimum_Accessibility): Added new field. diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb index 7f11b41..5b2e0a5 100644 --- a/gcc/ada/exp_aggr.adb +++ b/gcc/ada/exp_aggr.adb @@ -2075,7 +2075,6 @@ package body Exp_Aggr is Choice := First (Choice_List (Assoc)); while Present (Choice) loop if Nkind (Choice) = N_Others_Choice then - Set_Loop_Actions (Assoc, New_List); Others_Assoc := Assoc; exit; end if; @@ -2122,7 +2121,8 @@ package body Exp_Aggr is if Present (Others_Assoc) then declare - First : Boolean := True; + First : Boolean := True; + Dup_Expr : Node_Id; begin for J in 0 .. Nb_Choices loop @@ -2160,9 +2160,19 @@ package body Exp_Aggr is or else not Empty_Range (Low, High) then First := False; + + -- Duplicate the expression in case we will be generating + -- several loops. As a result the expression is no longer + -- shared between the loops and is reevaluated for each + -- such loop. + + Expr := Get_Assoc_Expr (Others_Assoc); + Dup_Expr := New_Copy_Tree (Expr); + Set_Parent (Dup_Expr, Parent (Expr)); + + Set_Loop_Actions (Others_Assoc, New_List); Append_List - (Gen_Loop (Low, High, - Get_Assoc_Expr (Others_Assoc)), To => New_Code); + (Gen_Loop (Low, High, Dup_Expr), To => New_Code); end if; end loop; end; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fd0efb1..32297d1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-09-18 Eric Botcazou + + * gnat.dg/aggr28.adb: New testcase. + 2019-09-18 Steve Baird * gnat.dg/ai12_0086_example.adb: New testcase. diff --git a/gcc/testsuite/gnat.dg/aggr28.adb b/gcc/testsuite/gnat.dg/aggr28.adb new file mode 100644 index 0000000..3375b71 --- /dev/null +++ b/gcc/testsuite/gnat.dg/aggr28.adb @@ -0,0 +1,29 @@ +-- { dg-do run } + +procedure Aggr28 is + + Count : Natural := 0; + + function Get (S: String) return String is + begin + Count := Count + 1; + return S; + end; + + Max_Error_Length : constant := 8; + subtype Error_Type is String (1 .. Max_Error_Length); + + type Rec is record + Text : Error_Type; + end record; + + type Arr is array (1 .. 16) of Rec; + + Table : constant Arr := + (3 => (Text => Get ("INVALID ")), others => (Text => Get ("OTHERS "))); + +begin + if Count /= Table'Length then + raise Program_Error; + end if; +end; \ No newline at end of file -- cgit v1.1 From 1b2f53bb9ad9c903a126bbe5d6c5672550a54c13 Mon Sep 17 00:00:00 2001 From: Justin Squirek Date: Wed, 18 Sep 2019 08:33:17 +0000 Subject: [Ada] Missing accessibility check on discrim assignment This patch fixes an issue whereby assignments from anonymous access descriminants which are part of stand alone objects of anonymous access did not have runtime checks generated based on the accessibility level of the object according to ARM 3.10.2 (12.5/3). 2019-09-18 Justin Squirek gcc/ada/ * exp_ch4.adb (Expand_N_Type_Conversion): Add calculation of an alternative operand for the purposes of generating accessibility checks. gcc/testsuite/ * gnat.dg/access8.adb, gnat.dg/access8_pkg.adb, gnat.dg/access8_pkg.ads: New testcase. From-SVN: r275860 --- gcc/ada/ChangeLog | 6 +++++ gcc/ada/exp_ch4.adb | 18 +++++++++++--- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gnat.dg/access8.adb | 46 +++++++++++++++++++++++++++++++++++ gcc/testsuite/gnat.dg/access8_pkg.adb | 30 +++++++++++++++++++++++ gcc/testsuite/gnat.dg/access8_pkg.ads | 19 +++++++++++++++ 6 files changed, 120 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/access8.adb create mode 100644 gcc/testsuite/gnat.dg/access8_pkg.adb create mode 100644 gcc/testsuite/gnat.dg/access8_pkg.ads (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 5c17f81..cbb1e16 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,9 @@ +2019-09-18 Justin Squirek + + * exp_ch4.adb (Expand_N_Type_Conversion): Add calculation of an + alternative operand for the purposes of generating accessibility + checks. + 2019-09-18 Eric Botcazou * exp_aggr.adb (Build_Array_Aggr_Code): In STEP 1 (c), duplicate diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb index 0c96d8c..a20469c 100644 --- a/gcc/ada/exp_ch4.adb +++ b/gcc/ada/exp_ch4.adb @@ -11001,6 +11001,7 @@ package body Exp_Ch4 is procedure Expand_N_Type_Conversion (N : Node_Id) is Loc : constant Source_Ptr := Sloc (N); Operand : constant Node_Id := Expression (N); + Operand_Acc : Node_Id := Operand; Target_Type : Entity_Id := Etype (N); Operand_Type : Entity_Id := Etype (Operand); @@ -11718,6 +11719,15 @@ package body Exp_Ch4 is -- Case of converting to an access type if Is_Access_Type (Target_Type) then + -- In terms of accessibility rules, an anonymous access discriminant + -- is not considered separate from its parent object. + + if Nkind (Operand) = N_Selected_Component + and then Ekind (Entity (Selector_Name (Operand))) = E_Discriminant + and then Ekind (Operand_Type) = E_Anonymous_Access_Type + then + Operand_Acc := Original_Node (Prefix (Operand)); + end if; -- If this type conversion was internally generated by the front end -- to displace the pointer to the object to reference an interface @@ -11741,9 +11751,9 @@ package body Exp_Ch4 is -- other checks may still need to be applied below (such as tagged -- type checks). - elsif Is_Entity_Name (Operand) - and then Has_Extra_Accessibility (Entity (Operand)) - and then Ekind (Etype (Operand)) = E_Anonymous_Access_Type + elsif Is_Entity_Name (Operand_Acc) + and then Has_Extra_Accessibility (Entity (Operand_Acc)) + and then Ekind (Etype (Operand_Acc)) = E_Anonymous_Access_Type and then (Nkind (Original_Node (N)) /= N_Attribute_Reference or else Attribute_Name (Original_Node (N)) = Name_Access) then @@ -11758,7 +11768,7 @@ package body Exp_Ch4 is else Apply_Accessibility_Check - (Operand, Target_Type, Insert_Node => Operand); + (Operand_Acc, Target_Type, Insert_Node => Operand); end if; -- If the level of the operand type is statically deeper than the diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 32297d1..bf67722 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-18 Justin Squirek + + * gnat.dg/access8.adb, gnat.dg/access8_pkg.adb, + gnat.dg/access8_pkg.ads: New testcase. + 2019-09-18 Eric Botcazou * gnat.dg/aggr28.adb: New testcase. diff --git a/gcc/testsuite/gnat.dg/access8.adb b/gcc/testsuite/gnat.dg/access8.adb new file mode 100644 index 0000000..d7eec2a --- /dev/null +++ b/gcc/testsuite/gnat.dg/access8.adb @@ -0,0 +1,46 @@ +-- { dg-do run } +-- { dg-options "-gnatws" } + +with Access8_Pkg; +procedure Access8 is + Errors : Natural := 0; + outer_object_accessibility_check + : access Access8_Pkg.object; + outer_discriminant_accessibility_check + : access Access8_Pkg.discriminant; + Mistake + : access Access8_Pkg.discriminant; + outer_discriminant_copy_discriminant_check + : access Access8_Pkg.discriminant; +begin + declare + obj + : aliased Access8_Pkg.object := Access8_Pkg.get; + inner_object + : access Access8_Pkg.object := obj'Access; + inner_discriminant + : access Access8_Pkg.discriminant := obj.d; + begin + begin + outer_object_accessibility_check + := inner_object; -- ERROR + exception + when others => Errors := Errors + 1; + end; + begin + Mistake + := inner_object.d; -- ERROR + exception + when others => Errors := Errors + 1; + end; + begin + outer_discriminant_copy_discriminant_check + := inner_discriminant; -- ERROR + exception + when others => Errors := Errors + 1; + end; + if Errors /= 3 then + raise Program_Error; + end if; + end; +end; diff --git a/gcc/testsuite/gnat.dg/access8_pkg.adb b/gcc/testsuite/gnat.dg/access8_pkg.adb new file mode 100644 index 0000000..9d7c933 --- /dev/null +++ b/gcc/testsuite/gnat.dg/access8_pkg.adb @@ -0,0 +1,30 @@ +-- { dg-options "-gnatws" } + +with Ada.Finalization; + +package body Access8_Pkg is + + overriding procedure Initialize (O : in out Object) is + begin + null; + end; + + overriding procedure Finalize (O : in out Object) is + begin + null; + end; + + function Get return Object is + begin + return O : Object := Object' + (Ada.Finalization.Limited_Controlled + with D => new discriminant); + end; + + function Get_Access return access Object is + begin + return new Object' + (Ada.Finalization.Limited_Controlled + with D => new Discriminant); + end; +end; diff --git a/gcc/testsuite/gnat.dg/access8_pkg.ads b/gcc/testsuite/gnat.dg/access8_pkg.ads new file mode 100644 index 0000000..19c632d --- /dev/null +++ b/gcc/testsuite/gnat.dg/access8_pkg.ads @@ -0,0 +1,19 @@ +with Ada.Finalization; + +package Access8_Pkg is + + type Discriminant is record + Component : Integer := 6; + end record; + + type Object (D : access Discriminant) + is tagged limited private; + + function Get return Object; + function Get_Access return access Object; +private + type Object (D : access Discriminant) + is new Ada.Finalization.Limited_Controlled with null record; + overriding procedure Initialize (O : in out Object); + overriding procedure Finalize (O : in out Object); +end; -- cgit v1.1 From 483af72e4bf2499fdbbf6b6e061318eaa9ba2b2d Mon Sep 17 00:00:00 2001 From: Justin Squirek Date: Wed, 18 Sep 2019 08:33:23 +0000 Subject: [Ada] Spurious ineffective use_clause warning This patch fixes an issue whereby expansion of post conditions may lead to spurious ineffective use_clause warnings when a use type clause is present in a package specification and a use package clause exists in the package body on the package containing said type. 2019-09-18 Justin Squirek gcc/ada/ * sem_ch8.adb (Use_One_Type): Add guard to prevent warning on a reundant use package clause where there is no previous use_clause in the chain. gcc/testsuite/ * gnat.dg/warn30.adb, gnat.dg/warn30.ads: New testcase. From-SVN: r275861 --- gcc/ada/ChangeLog | 6 ++++++ gcc/ada/sem_ch8.adb | 17 ++++++++++++----- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gnat.dg/warn30.adb | 10 ++++++++++ gcc/testsuite/gnat.dg/warn30.ads | 6 ++++++ 5 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/warn30.adb create mode 100644 gcc/testsuite/gnat.dg/warn30.ads (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index cbb1e16..6823972 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,5 +1,11 @@ 2019-09-18 Justin Squirek + * sem_ch8.adb (Use_One_Type): Add guard to prevent warning on a + reundant use package clause where there is no previous + use_clause in the chain. + +2019-09-18 Justin Squirek + * exp_ch4.adb (Expand_N_Type_Conversion): Add calculation of an alternative operand for the purposes of generating accessibility checks. diff --git a/gcc/ada/sem_ch8.adb b/gcc/ada/sem_ch8.adb index a7918da..5d03f835 100644 --- a/gcc/ada/sem_ch8.adb +++ b/gcc/ada/sem_ch8.adb @@ -10337,11 +10337,18 @@ package body Sem_Ch8 is -- The package where T is declared is already used elsif In_Use (Scope (T)) then - Error_Msg_Sloc := - Sloc (Find_Most_Prev (Current_Use_Clause (Scope (T)))); - Error_Msg_NE -- CODEFIX - ("& is already use-visible through package use clause #??", - Id, T); + -- Due to expansion of contracts we could be attempting to issue + -- a spurious warning - so verify there is a previous use clause. + + if Current_Use_Clause (Scope (T)) /= + Find_Most_Prev (Current_Use_Clause (Scope (T))) + then + Error_Msg_Sloc := + Sloc (Find_Most_Prev (Current_Use_Clause (Scope (T)))); + Error_Msg_NE -- CODEFIX + ("& is already use-visible through package use clause #??", + Id, T); + end if; -- The current scope is the package where T is declared diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bf67722..e9966b2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2019-09-18 Justin Squirek + * gnat.dg/warn30.adb, gnat.dg/warn30.ads: New testcase. + +2019-09-18 Justin Squirek + * gnat.dg/access8.adb, gnat.dg/access8_pkg.adb, gnat.dg/access8_pkg.ads: New testcase. diff --git a/gcc/testsuite/gnat.dg/warn30.adb b/gcc/testsuite/gnat.dg/warn30.adb new file mode 100644 index 0000000..841c70e --- /dev/null +++ b/gcc/testsuite/gnat.dg/warn30.adb @@ -0,0 +1,10 @@ +-- { dg-do compile } +-- { dg-options "-gnatwa" } +with Interfaces; use Interfaces; + +package body Warn30 is + procedure Incr (X : in out Interfaces.Integer_64) is + begin + X := X + 1; + end Incr; +end Warn30; \ No newline at end of file diff --git a/gcc/testsuite/gnat.dg/warn30.ads b/gcc/testsuite/gnat.dg/warn30.ads new file mode 100644 index 0000000..3b60816 --- /dev/null +++ b/gcc/testsuite/gnat.dg/warn30.ads @@ -0,0 +1,6 @@ +with Interfaces; use type Interfaces.Integer_64; + +package Warn30 is + procedure Incr (X : in out Interfaces.Integer_64) with + Post => X = X'Old + 1; +end Warn30; -- cgit v1.1 From b8411279b0674cd76850b0fa8266e8db21724e0e Mon Sep 17 00:00:00 2001 From: Ed Schonberg Date: Wed, 18 Sep 2019 08:33:27 +0000 Subject: [Ada] Crash on aggregate with dscriminant in if-expression as default This patch fixes a crash on a an aggregate for a discriminated type, when a component of the aggregate is also a discriminated type constrained by a discriminant of the enclosing object, and the default value for the component is a conditional expression that includes references to that outer discriminant. 2019-09-18 Ed Schonberg gcc/ada/ * exp_aggr.adb (Expand_Record_Aggregate, Rewrite_Discriminant): After rewriting a reference to an outer discriminant as a selected component of the enclosing object, analyze the selected component to ensure that the entity of the selector name is properly set. This is necessary when the aggregate appears within an expression that may have been analyzed already. gcc/testsuite/ * gnat.dg/discr58.adb: New testcase. From-SVN: r275862 --- gcc/ada/ChangeLog | 9 +++++++++ gcc/ada/exp_aggr.adb | 7 +++++++ gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gnat.dg/discr58.adb | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+) create mode 100644 gcc/testsuite/gnat.dg/discr58.adb (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 6823972..92782aa 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,12 @@ +2019-09-18 Ed Schonberg + + * exp_aggr.adb (Expand_Record_Aggregate, Rewrite_Discriminant): + After rewriting a reference to an outer discriminant as a + selected component of the enclosing object, analyze the selected + component to ensure that the entity of the selector name is + properly set. This is necessary when the aggregate appears + within an expression that may have been analyzed already. + 2019-09-18 Justin Squirek * sem_ch8.adb (Use_One_Type): Add guard to prevent warning on a diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb index 5b2e0a5..63f9d1a 100644 --- a/gcc/ada/exp_aggr.adb +++ b/gcc/ada/exp_aggr.adb @@ -3103,6 +3103,13 @@ package body Exp_Aggr is Make_Selected_Component (Loc, Prefix => New_Copy_Tree (Lhs), Selector_Name => Make_Identifier (Loc, Chars (Expr)))); + + -- The generated code will be reanalyzed, but if the reference + -- to the discriminant appears within an already analyzed + -- expression (e.g. a conditional) we must set its proper entity + -- now. Context is an initialization procedure. + + Analyze (Expr); end if; return OK; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e9966b2..cc18969 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-09-18 Ed Schonberg + + * gnat.dg/discr58.adb: New testcase. + 2019-09-18 Justin Squirek * gnat.dg/warn30.adb, gnat.dg/warn30.ads: New testcase. diff --git a/gcc/testsuite/gnat.dg/discr58.adb b/gcc/testsuite/gnat.dg/discr58.adb new file mode 100644 index 0000000..bb6f5bf --- /dev/null +++ b/gcc/testsuite/gnat.dg/discr58.adb @@ -0,0 +1,33 @@ +-- { dg-do compile } + +with Ada.Text_IO; use Ada.Text_IO; + +procedure Discr58 is + + type Field(Flag : Boolean := True) is record + case Flag is + when True => Param1 : Boolean := False; + when False => Param2 : Boolean := True; + end case; + end record; + + type Header(Flag : Boolean := True) is record + Param3 : Integer := 0; + Params : Field(Flag) := (if Flag = True then + (Flag => True, others => <>) + else + (Flag => False, others => <>)); + end record; + + type Message(Flag : Boolean) is record + + -- This assignment crashes GNAT + The_Header : Header(Flag) := Header'(Flag => True, others => <>); + end record; + + It : Message (True); +begin + Put_Line("Hello World"); + Put_Line (Boolean'Image (It.The_Header.Flag)); + Put_Line (Boolean'Image (It.The_Header.Params.Flag)); +end Discr58; \ No newline at end of file -- cgit v1.1 From 0cff31f0f67a88fd1bf76bab430eaa0adac94ffa Mon Sep 17 00:00:00 2001 From: Ed Schonberg Date: Wed, 18 Sep 2019 08:33:32 +0000 Subject: [Ada] Use static discriminant value for discriminated task record This patch allows the construction of a static subtype for the generated constrained Secondary_Stack component of a task for which a stack size is specified, when compiling for a restricted run-time that forbids dynamic allocation. Needed for LLVM. 2019-09-18 Ed Schonberg gcc/ada/ * sem_ch3.adb (Constrain_Component_Type): For a discriminated type, handle the case of a constraint given by a conversion of a discriminant of the enclosing type. Necessary when compiling a discriminated task for a restricted run-time, when the generated Secondary_Stack component may be set by means of an aspect on the task type. From-SVN: r275863 --- gcc/ada/ChangeLog | 9 +++++++++ gcc/ada/sem_ch3.adb | 21 ++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 92782aa..d9b552a 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,5 +1,14 @@ 2019-09-18 Ed Schonberg + * sem_ch3.adb (Constrain_Component_Type): For a discriminated + type, handle the case of a constraint given by a conversion of a + discriminant of the enclosing type. Necessary when compiling a + discriminated task for a restricted run-time, when the generated + Secondary_Stack component may be set by means of an aspect on + the task type. + +2019-09-18 Ed Schonberg + * exp_aggr.adb (Expand_Record_Aggregate, Rewrite_Discriminant): After rewriting a reference to an outer discriminant as a selected component of the enclosing object, analyze the selected diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb index 864b08e..35be35a 100644 --- a/gcc/ada/sem_ch3.adb +++ b/gcc/ada/sem_ch3.adb @@ -13258,7 +13258,9 @@ package body Sem_Ch3 is function Build_Constrained_Discriminated_Type (Old_Type : Entity_Id) return Entity_Id; - -- Ditto for record components + -- Ditto for record components. Handle the case where the constraint + -- is a conversion of the discriminant value, introduced during + -- expansion. function Build_Constrained_Access_Type (Old_Type : Entity_Id) return Entity_Id; @@ -13443,6 +13445,17 @@ package body Sem_Ch3 is if Is_Discriminant (Expr) then Need_To_Create_Itype := True; + + -- After expansion of discriminated task types, the value + -- of the discriminant may be converted to a run-time type + -- for restricted run-times. Propagate the value of the + -- discriminant ss well, so that e.g. the secondary stack + -- component has a static constraint. Necessry for LLVM. + + elsif Nkind (Expr) = N_Type_Conversion + and then Is_Discriminant (Expression (Expr)) + then + Need_To_Create_Itype := True; end if; Next_Elmt (Old_Constraint); @@ -13457,6 +13470,12 @@ package body Sem_Ch3 is if Is_Discriminant (Expr) then Expr := Get_Discr_Value (Expr); + + elsif Nkind (Expr) = N_Type_Conversion + and then Is_Discriminant (Expression (Expr)) + then + Expr := New_Copy_Tree (Expr); + Set_Expression (Expr, Get_Discr_Value (Expression (Expr))); end if; Append (New_Copy_Tree (Expr), To => Constr_List); -- cgit v1.1 From 1784b1eb1f22a802cf7e2f3529fa83a40bce1b20 Mon Sep 17 00:00:00 2001 From: Ed Schonberg Date: Wed, 18 Sep 2019 08:33:40 +0000 Subject: [Ada] Crash on universal case expression in fixed-point division This patch fixes a compiler abort on a case expression whose alternatives are universal_real constants, when the case expression is an operand in a multiplication or division whose other operand is of a fixed-point type. 2019-09-18 Ed Schonberg gcc/ada/ * sem_res.adb (Set_Mixed_Node_Expression): If a conditional expression has universal_real alternaitves and the context is Universal_Fixed, as when it is an operand in a fixed-point multiplication or division, resolve the expression with a visible fixed-point type, which must be unique. gcc/testsuite/ * gnat.dg/fixedpnt8.adb: New testcase. From-SVN: r275864 --- gcc/ada/ChangeLog | 8 ++++++++ gcc/ada/sem_res.adb | 12 ++++++++++-- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gnat.dg/fixedpnt8.adb | 28 ++++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/fixedpnt8.adb (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index d9b552a..2a5ca04 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,5 +1,13 @@ 2019-09-18 Ed Schonberg + * sem_res.adb (Set_Mixed_Node_Expression): If a conditional + expression has universal_real alternaitves and the context is + Universal_Fixed, as when it is an operand in a fixed-point + multiplication or division, resolve the expression with a + visible fixed-point type, which must be unique. + +2019-09-18 Ed Schonberg + * sem_ch3.adb (Constrain_Component_Type): For a discriminated type, handle the case of a constraint given by a conversion of a discriminant of the enclosing type. Necessary when compiling a diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb index 7a52b90..38de57d 100644 --- a/gcc/ada/sem_res.adb +++ b/gcc/ada/sem_res.adb @@ -5674,13 +5674,21 @@ package body Sem_Res is -- A universal real conditional expression can appear in a fixed-type -- context and must be resolved with that context to facilitate the - -- code generation in the back end. + -- code generation in the back end. However, If the context is + -- Universal_fixed (i.e. as an operand of a multiplication/division + -- involving a fixed-point operand) the conditional expression must + -- resolve to a unique visible fixed_point type, normally Duration. elsif Nkind_In (N, N_Case_Expression, N_If_Expression) and then Etype (N) = Universal_Real and then Is_Fixed_Point_Type (B_Typ) then - Resolve (N, B_Typ); + if B_Typ = Universal_Fixed then + Resolve (N, Unique_Fixed_Point_Type (N)); + + else + Resolve (N, B_Typ); + end if; else Resolve (N); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cc18969..7cfdc4c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2019-09-18 Ed Schonberg + * gnat.dg/fixedpnt8.adb: New testcase. + +2019-09-18 Ed Schonberg + * gnat.dg/discr58.adb: New testcase. 2019-09-18 Justin Squirek diff --git a/gcc/testsuite/gnat.dg/fixedpnt8.adb b/gcc/testsuite/gnat.dg/fixedpnt8.adb new file mode 100644 index 0000000..1fc5cef --- /dev/null +++ b/gcc/testsuite/gnat.dg/fixedpnt8.adb @@ -0,0 +1,28 @@ +-- { dg-do compile } + +procedure Fixedpnt8 is + + Ct_A : constant := 0.000_000_100; + Ct_B : constant := 0.000_000_025; + + Ct_C : constant := 1_000; + + type Number_Type is range 0 .. Ct_C; + + subtype Index_Type is Number_Type range 1 .. Number_Type'Last; + + type Kind_Enumerated_Type is + (A1, + A2); + + Kind : Kind_Enumerated_Type := A1; + + V : Duration := 10.0; + + Last : constant Index_Type := + Index_Type (V / (case Kind is -- { dg-warning "universal_fixed expression interpreted as type \"Standard.Duration\"" } + when A1 => Ct_B, + when A2 => Ct_A)); +begin + null; +end Fixedpnt8; \ No newline at end of file -- cgit v1.1 From 5c13a04e0dcb6e6c07708dc6796968ee89b4560b Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Wed, 18 Sep 2019 08:33:44 +0000 Subject: [Ada] Fix spurious alignment warning on simple address clause This eliminates a spurious alignment warning given by the compiler on an address clause when the No_Exception_Propagation restriction is in effect and the -gnatw.x switch is used. In this configuration the address clauses whose expression is itself of the form X'Address would not be sufficiently analyzed and, therefore, the compiler might give false positive warnings. 2019-09-18 Eric Botcazou gcc/ada/ * checks.ads (Alignment_Warnings_Record): Add P component. * checks.adb (Apply_Address_Clause_Check): Be prepared to kill the warning also if the clause is of the form X'Address. (Validate_Alignment_Check_Warning): Kill the warning if the clause is of the form X'Address and the alignment of X is compatible. gcc/testsuite/ * gnat.dg/warn31.adb, gnat.dg/warn31.ads: New testcase. From-SVN: r275865 --- gcc/ada/ChangeLog | 9 +++++++++ gcc/ada/checks.adb | 23 +++++++++++++++++++++-- gcc/ada/checks.ads | 7 +++++-- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gnat.dg/warn31.adb | 5 +++++ gcc/testsuite/gnat.dg/warn31.ads | 20 ++++++++++++++++++++ 6 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/warn31.adb create mode 100644 gcc/testsuite/gnat.dg/warn31.ads (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 2a5ca04..240bc08 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,12 @@ +2019-09-18 Eric Botcazou + + * checks.ads (Alignment_Warnings_Record): Add P component. + * checks.adb (Apply_Address_Clause_Check): Be prepared to kill + the warning also if the clause is of the form X'Address. + (Validate_Alignment_Check_Warning): Kill the warning if the + clause is of the form X'Address and the alignment of X is + compatible. + 2019-09-18 Ed Schonberg * sem_res.adb (Set_Mixed_Node_Expression): If a conditional diff --git a/gcc/ada/checks.adb b/gcc/ada/checks.adb index caee9ad..9ca1cf0 100644 --- a/gcc/ada/checks.adb +++ b/gcc/ada/checks.adb @@ -808,7 +808,21 @@ package body Checks is if Compile_Time_Known_Value (Expr) then Alignment_Warnings.Append - ((E => E, A => Expr_Value (Expr), W => Warning_Msg)); + ((E => E, + A => Expr_Value (Expr), + P => Empty, + W => Warning_Msg)); + + -- Likewise if the expression is of the form X'Address + + elsif Nkind (Expr) = N_Attribute_Reference + and then Attribute_Name (Expr) = Name_Address + then + Alignment_Warnings.Append + ((E => E, + A => No_Uint, + P => Prefix (Expr), + W => Warning_Msg)); -- Add explanation of the warning generated by the check @@ -10925,7 +10939,12 @@ package body Checks is renames Alignment_Warnings.Table (J); begin if Known_Alignment (AWR.E) - and then AWR.A mod Alignment (AWR.E) = 0 + and then ((AWR.A /= No_Uint + and then AWR.A mod Alignment (AWR.E) = 0) + or else (Present (AWR.P) + and then Has_Compatible_Alignment + (AWR.E, AWR.P, True) = + Known_Compatible)) then Delete_Warning_And_Continuations (AWR.W); end if; diff --git a/gcc/ada/checks.ads b/gcc/ada/checks.ads index 9bf2908..a1538a3 100644 --- a/gcc/ada/checks.ads +++ b/gcc/ada/checks.ads @@ -90,7 +90,7 @@ package Checks is -- When we have address clauses, there is an issue of whether the address -- specified is appropriate to the alignment. In the general case where the -- address is dynamic, we generate a check and a possible warning (this - -- warning occurs for example if we have a restricted run time with the + -- warning occurs for example if we have a restricted runtime with the -- restriction No_Exception_Propagation). We also issue this warning in -- the case where the address is static, but we don't know the alignment -- at the time we process the address clause. In such a case, we issue the @@ -98,7 +98,7 @@ package Checks is -- annotated the actual alignment chosen) that the warning was not needed. -- To deal with deleting these potentially annoying warnings, we save the - -- warning information in a table, and then delete the waranings in the + -- warning information in a table, and then delete the warnings in the -- post compilation validation stage if we can tell that the check would -- never fail (in general the back end will also optimize away the check -- in such cases). @@ -113,6 +113,9 @@ package Checks is -- Compile time known value of address clause for which the alignment -- is to be checked once we know the alignment. + P : Node_Id; + -- Prefix of address clause when it is of the form X'Address + W : Error_Msg_Id; -- Id of warning message we might delete end record; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7cfdc4c..dc84ed9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-09-18 Eric Botcazou + + * gnat.dg/warn31.adb, gnat.dg/warn31.ads: New testcase. + 2019-09-18 Ed Schonberg * gnat.dg/fixedpnt8.adb: New testcase. diff --git a/gcc/testsuite/gnat.dg/warn31.adb b/gcc/testsuite/gnat.dg/warn31.adb new file mode 100644 index 0000000..136c84f --- /dev/null +++ b/gcc/testsuite/gnat.dg/warn31.adb @@ -0,0 +1,5 @@ +-- { dg-do compile } +-- { dg-options "-gnatw.x -gnatd.a" } +package body Warn31 is + procedure Dummy is null; +end Warn31; diff --git a/gcc/testsuite/gnat.dg/warn31.ads b/gcc/testsuite/gnat.dg/warn31.ads new file mode 100644 index 0000000..5311079 --- /dev/null +++ b/gcc/testsuite/gnat.dg/warn31.ads @@ -0,0 +1,20 @@ +pragma Restrictions (No_Exception_Propagation); + +package Warn31 is + + type U16 is mod 2 ** 16; + type U32 is mod 2 ** 32; + + type Pair is record + X, Y : U16; + end record; + for Pair'Alignment use U32'Alignment; + + Blob : array (1 .. 2) of Pair; + + Sum : array (1 .. 2) of U32; + for Sum'Address use Blob'Address; + + procedure Dummy; + +end Warn31; \ No newline at end of file -- cgit v1.1 From 58ab1e7607d7e464ba1e4fa3d4986da934903b5c Mon Sep 17 00:00:00 2001 From: Bob Duff Date: Wed, 18 Sep 2019 08:33:49 +0000 Subject: [Ada] Avoid gnatbind regression caused by Copy_Bitfield The recent Copy_Bitfield change caused gnatbind to change elaboration order, causing different error messages. 2019-09-18 Bob Duff gcc/ada/ * exp_ch5.adb (Expand_Assign_Array_Loop_Or_Bitfield): Move call to RTE_Available later, so it doesn't disturb the elab order. The RE_Copy_Bitfield entity is defined in package System.Bitfields which has a dependency on package System.Bitfield_Utils, which has it its spec: pragma Elaborate_Body; The query on RTE_Available forces loading and analyzing System.Bitfields and all its withed units. From-SVN: r275866 --- gcc/ada/ChangeLog | 11 +++++++++++ gcc/ada/exp_ch5.adb | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 240bc08..c42498e 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,14 @@ +2019-09-18 Bob Duff + + * exp_ch5.adb (Expand_Assign_Array_Loop_Or_Bitfield): Move call + to RTE_Available later, so it doesn't disturb the elab order. + The RE_Copy_Bitfield entity is defined in package + System.Bitfields which has a dependency on package + System.Bitfield_Utils, which has it its spec: + pragma Elaborate_Body; + The query on RTE_Available forces loading and analyzing + System.Bitfields and all its withed units. + 2019-09-18 Eric Botcazou * checks.ads (Alignment_Warnings_Record): Add P component. diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb index f5c1f21..4bbe86a 100644 --- a/gcc/ada/exp_ch5.adb +++ b/gcc/ada/exp_ch5.adb @@ -1475,8 +1475,7 @@ package body Exp_Ch5 is -- optimization in that case as well. We could complicate this code by -- actually looking for such volatile and independent components. - if RTE_Available (RE_Copy_Bitfield) - and then Is_Bit_Packed_Array (L_Type) + if Is_Bit_Packed_Array (L_Type) and then Is_Bit_Packed_Array (R_Type) and then not Reverse_Storage_Order (L_Type) and then not Reverse_Storage_Order (R_Type) @@ -1489,6 +1488,7 @@ package body Exp_Ch5 is and then not Has_Independent_Components (R_Type) and then not L_Prefix_Comp and then not R_Prefix_Comp + and then RTE_Available (RE_Copy_Bitfield) then return Expand_Assign_Array_Bitfield (N, Larray, Rarray, L_Type, R_Type, Rev); -- cgit v1.1 From a95b474a088187218bd4e73c1c34566e3c3fc83d Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Wed, 18 Sep 2019 11:03:14 +0200 Subject: Come up with debug counter for store-merging. 2019-09-18 Martin Liska * dbgcnt.def (store_merging): New counter. * gimple-ssa-store-merging.c (imm_store_chain_info::output_merged_stores): Use it in store merging. From-SVN: r275867 --- gcc/ChangeLog | 6 ++++++ gcc/dbgcnt.def | 1 + gcc/gimple-ssa-store-merging.c | 4 +++- 3 files changed, 10 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5a4fc2c..5407096 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-09-18 Martin Liska + + * dbgcnt.def (store_merging): New counter. + * gimple-ssa-store-merging.c (imm_store_chain_info::output_merged_stores): + Use it in store merging. + 2019-09-17 Richard Sandiford * config/aarch64/aarch64.c (aarch64_sched_variable_issue): New diff --git a/gcc/dbgcnt.def b/gcc/dbgcnt.def index 230072f..ef981aa 100644 --- a/gcc/dbgcnt.def +++ b/gcc/dbgcnt.def @@ -196,3 +196,4 @@ DEBUG_COUNTER (vect_loop) DEBUG_COUNTER (vect_slp) DEBUG_COUNTER (dom_unreachable_edges) DEBUG_COUNTER (match) +DEBUG_COUNTER (store_merging) diff --git a/gcc/gimple-ssa-store-merging.c b/gcc/gimple-ssa-store-merging.c index 0bf64b3..5abaa7d 100644 --- a/gcc/gimple-ssa-store-merging.c +++ b/gcc/gimple-ssa-store-merging.c @@ -166,6 +166,7 @@ #include "rtl.h" #include "expr.h" /* For get_bit_range. */ #include "optabs-tree.h" +#include "dbgcnt.h" #include "selftest.h" /* The maximum size (in bits) of the stores this pass should generate. */ @@ -4195,7 +4196,8 @@ imm_store_chain_info::output_merged_stores () bool ret = false; FOR_EACH_VEC_ELT (m_merged_store_groups, i, merged_store) { - if (output_merged_store (merged_store)) + if (dbg_cnt (store_merging) + && output_merged_store (merged_store)) { unsigned int j; store_immediate_info *store; -- cgit v1.1 From ef20d2215067b1bfa8b3f9549ca0baed636a94a0 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 18 Sep 2019 09:43:10 +0000 Subject: Two more POLY_INT cases for dwarf2out.c loc_list_for_tree_1 and add_const_value_attribute currently ICE on POLY_INTs. loc_list_for_tree_1 can do something sensible but add_const_value_attribute has to punt, since the constant there needs to be a link-time rather than load-time or run-time constant. This is tested by later SVE patches. 2019-09-18 Richard Sandiford gcc/ * dwarf2out.c (loc_list_from_tree_1): Handle POLY_INT_CST. (add_const_value_attribute): Handle CONST_POLY_INT. From-SVN: r275868 --- gcc/ChangeLog | 5 +++++ gcc/dwarf2out.c | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5407096..7f8425b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-09-18 Richard Sandiford + + * dwarf2out.c (loc_list_from_tree_1): Handle POLY_INT_CST. + (add_const_value_attribute): Handle CONST_POLY_INT. + 2019-09-18 Martin Liska * dbgcnt.def (store_merging): New counter. diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 5698c82..cec25fa 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -18568,6 +18568,24 @@ loc_list_from_tree_1 (tree loc, int want_address, } break; + case POLY_INT_CST: + { + if (want_address) + { + expansion_failed (loc, NULL_RTX, + "constant address with a runtime component"); + return 0; + } + poly_int64 value; + if (!poly_int_tree_p (loc, &value)) + { + expansion_failed (loc, NULL_RTX, "constant too big"); + return 0; + } + ret = int_loc_descriptor (value); + } + break; + case CONSTRUCTOR: case REAL_CST: case STRING_CST: @@ -19684,6 +19702,7 @@ add_const_value_attribute (dw_die_ref die, rtx rtl) case MINUS: case SIGN_EXTEND: case ZERO_EXTEND: + case CONST_POLY_INT: return false; case MEM: -- cgit v1.1 From defc6f266c1dd625cc64ad1ecfbd1eacbcd66e4f Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 18 Sep 2019 09:43:29 +0000 Subject: Handle variable-length vectors in compute_record_mode This patch makes compute_record_mode handle SVE vectors in the same way as it would handle fixed-length vectors. There should be no change in behaviour for other targets. This is needed for the SVE equivalent of arm_neon.h types like int8x8x2_t (i.e. a pair of int8x8_ts). 2019-09-18 Richard Sandiford gcc/ * stor-layout.c (compute_record_mode): Operate on poly_uint64 sizes instead of uhwi sizes. From-SVN: r275869 --- gcc/ChangeLog | 5 +++++ gcc/stor-layout.c | 12 ++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7f8425b..3afdb09 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2019-09-18 Richard Sandiford + * stor-layout.c (compute_record_mode): Operate on poly_uint64 + sizes instead of uhwi sizes. + +2019-09-18 Richard Sandiford + * dwarf2out.c (loc_list_from_tree_1): Handle POLY_INT_CST. (add_const_value_attribute): Handle CONST_POLY_INT. diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 0e59cfb..9aada97 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -1811,7 +1811,8 @@ compute_record_mode (tree type) line. */ SET_TYPE_MODE (type, BLKmode); - if (! tree_fits_uhwi_p (TYPE_SIZE (type))) + poly_uint64 type_size; + if (!poly_int_tree_p (TYPE_SIZE (type), &type_size)) return; /* A record which has any BLKmode members must itself be @@ -1822,20 +1823,21 @@ compute_record_mode (tree type) if (TREE_CODE (field) != FIELD_DECL) continue; + poly_uint64 field_size; if (TREE_CODE (TREE_TYPE (field)) == ERROR_MARK || (TYPE_MODE (TREE_TYPE (field)) == BLKmode && ! TYPE_NO_FORCE_BLK (TREE_TYPE (field)) && !(TYPE_SIZE (TREE_TYPE (field)) != 0 && integer_zerop (TYPE_SIZE (TREE_TYPE (field))))) - || ! tree_fits_uhwi_p (bit_position (field)) + || !tree_fits_poly_uint64_p (bit_position (field)) || DECL_SIZE (field) == 0 - || ! tree_fits_uhwi_p (DECL_SIZE (field))) + || !poly_int_tree_p (DECL_SIZE (field), &field_size)) return; /* If this field is the whole struct, remember its mode so that, say, we can put a double in a class into a DF register instead of forcing it to live in the stack. */ - if (simple_cst_equal (TYPE_SIZE (type), DECL_SIZE (field)) + if (known_eq (field_size, type_size) /* Partial int types (e.g. __int20) may have TYPE_SIZE equal to wider types (e.g. int32), despite precision being less. Ensure that the TYPE_MODE of the struct does not get set to the partial @@ -1855,7 +1857,6 @@ compute_record_mode (tree type) For UNION_TYPE, if the widest field is MODE_INT then use that mode. If the widest field is MODE_PARTIAL_INT, and the union will be passed by reference, then use that mode. */ - poly_uint64 type_size; if ((TREE_CODE (type) == RECORD_TYPE || (TREE_CODE (type) == UNION_TYPE && (GET_MODE_CLASS (mode) == MODE_INT @@ -1864,7 +1865,6 @@ compute_record_mode (tree type) (pack_cumulative_args (0), function_arg_info (type, mode, /*named=*/false))))))) && mode != VOIDmode - && poly_int_tree_p (TYPE_SIZE (type), &type_size) && known_eq (GET_MODE_BITSIZE (mode), type_size)) ; else -- cgit v1.1 From 22b6299199da4efd3944cdaabca1d095d19ff901 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 18 Sep 2019 09:43:42 +0000 Subject: Don't treat variable-length vectors as VLAs during gimplification Source-level SVE vectors should be gimplified in the same way as normal fixed-length vectors rather than as VLAs. This is tested by later SVE patches. 2019-09-18 Richard Sandiford gcc/ * gimplify.c (gimplify_decl_expr): Use poly_int_tree_p instead of checking specifically for INTEGER_CST. From-SVN: r275870 --- gcc/ChangeLog | 5 +++++ gcc/gimplify.c | 7 ++++--- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3afdb09..2842a7f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2019-09-18 Richard Sandiford + * gimplify.c (gimplify_decl_expr): Use poly_int_tree_p instead + of checking specifically for INTEGER_CST. + +2019-09-18 Richard Sandiford + * stor-layout.c (compute_record_mode): Operate on poly_uint64 sizes instead of uhwi sizes. diff --git a/gcc/gimplify.c b/gcc/gimplify.c index daa0b71..623cdbf 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -1754,11 +1754,12 @@ gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p) tree init = DECL_INITIAL (decl); bool is_vla = false; - if (TREE_CODE (DECL_SIZE_UNIT (decl)) != INTEGER_CST + poly_uint64 size; + if (!poly_int_tree_p (DECL_SIZE_UNIT (decl), &size) || (!TREE_STATIC (decl) && flag_stack_check == GENERIC_STACK_CHECK - && compare_tree_int (DECL_SIZE_UNIT (decl), - STACK_CHECK_MAX_VAR_SIZE) > 0)) + && maybe_gt (size, + (unsigned HOST_WIDE_INT) STACK_CHECK_MAX_VAR_SIZE))) { gimplify_vla_decl (decl, seq_p); is_vla = true; -- cgit v1.1 From 01b57ebf58b8cc0d16db827d1d9aa5f10da23cce Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 18 Sep 2019 09:44:06 +0000 Subject: Make get_value_for_expr check for INTEGER_CSTs CONSTANT lattice values are symbolic constants rather than compile-time constants, so among other things can be POLY_INT_CSTs. This patch fixes a case in which we assumed all CONSTANTs were either ADDR_EXPRs or INTEGER_CSTs. This is tested by later SVE patches. 2019-09-18 Richard Sandiford gcc/ * tree-ssa-ccp.c (get_value_for_expr): Check whether CONSTANTs are INTEGER_CSTs. From-SVN: r275871 --- gcc/ChangeLog | 5 +++++ gcc/tree-ssa-ccp.c | 14 +++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2842a7f..5785081 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2019-09-18 Richard Sandiford + * tree-ssa-ccp.c (get_value_for_expr): Check whether CONSTANTs + are INTEGER_CSTs. + +2019-09-18 Richard Sandiford + * gimplify.c (gimplify_decl_expr): Use poly_int_tree_p instead of checking specifically for INTEGER_CST. diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index 5af3810..311918b 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -615,9 +615,17 @@ get_value_for_expr (tree expr, bool for_bits_p) val.mask = -1; } if (for_bits_p - && val.lattice_val == CONSTANT - && TREE_CODE (val.value) == ADDR_EXPR) - val = get_value_from_alignment (val.value); + && val.lattice_val == CONSTANT) + { + if (TREE_CODE (val.value) == ADDR_EXPR) + val = get_value_from_alignment (val.value); + else if (TREE_CODE (val.value) != INTEGER_CST) + { + val.lattice_val = VARYING; + val.value = NULL_TREE; + val.mask = -1; + } + } /* Fall back to a copy value. */ if (!for_bits_p && val.lattice_val == VARYING -- cgit v1.1 From a3d09469041ab66ee1e12c2f3e4de33c4bf96732 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 18 Sep 2019 11:28:20 +0000 Subject: re PR lto/91763 (go.go-torture/execute/printnil.go FAILs) 2019-09-18 Richard Biener PR lto/91763 * lto-streamer-in.c (input_eh_regions): Move EH init to lto_materialize_function. * tree-streamer-in.c (lto_input_ts_function_decl_tree_pointers): Likewise. lto/ * lto.c (lto_materialize_function): Initialize EH by looking at the function personality and flag_exceptions setting. From-SVN: r275872 --- gcc/ChangeLog | 8 ++++++++ gcc/lto-streamer-in.c | 5 ----- gcc/lto/ChangeLog | 6 ++++++ gcc/lto/lto.c | 6 ++++++ gcc/tree-streamer-in.c | 6 ------ 5 files changed, 20 insertions(+), 11 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5785081..1907307 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2019-09-18 Richard Biener + + PR lto/91763 + * lto-streamer-in.c (input_eh_regions): Move EH init to + lto_materialize_function. + * tree-streamer-in.c (lto_input_ts_function_decl_tree_pointers): + Likewise. + 2019-09-18 Richard Sandiford * tree-ssa-ccp.c (get_value_for_expr): Check whether CONSTANTs diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c index 3158edd..32b5d5f 100644 --- a/gcc/lto-streamer-in.c +++ b/gcc/lto-streamer-in.c @@ -615,11 +615,6 @@ input_eh_regions (class lto_input_block *ib, class data_in *data_in, lto_tag_check_range (tag, LTO_eh_table, LTO_eh_table); - /* If the file contains EH regions, then it was compiled with - -fexceptions. In that case, initialize the backend EH - machinery. */ - lto_init_eh (); - gcc_assert (fn->eh); root_region = streamer_read_hwi (ib); diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index 4e68fbf..a73cbc4 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,9 @@ +2019-09-18 Richard Biener + + PR lto/91763 + * lto.c (lto_materialize_function): Initialize EH by looking + at the function personality and flag_exceptions setting. + 2019-08-23 Jakub Jelinek PR middle-end/91283 diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index 814f03a..af3590c 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -107,6 +107,12 @@ lto_materialize_function (struct cgraph_node *node) return; if (DECL_FUNCTION_PERSONALITY (decl) && !first_personality_decl) first_personality_decl = DECL_FUNCTION_PERSONALITY (decl); + /* If the file contains a function with a language specific EH + personality set or with EH enabled initialize the backend EH + machinery. */ + if (DECL_FUNCTION_PERSONALITY (decl) + || opt_for_fn (decl, flag_exceptions)) + lto_init_eh (); } /* Let the middle end know about the function. */ diff --git a/gcc/tree-streamer-in.c b/gcc/tree-streamer-in.c index dcd511e..5152d10 100644 --- a/gcc/tree-streamer-in.c +++ b/gcc/tree-streamer-in.c @@ -802,12 +802,6 @@ lto_input_ts_function_decl_tree_pointers (class lto_input_block *ib, } } #endif - - /* If the file contains a function with an EH personality set, - then it was compiled with -fexceptions. In that case, initialize - the backend EH machinery. */ - if (DECL_FUNCTION_PERSONALITY (expr)) - lto_init_eh (); } -- cgit v1.1 From 743a16d57a4f9f65bbc663100d5e16c564f283ec Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 18 Sep 2019 11:37:02 +0000 Subject: Make assemble_real generate canonical CONST_INTs assemble_real used GEN_INT to create integers directly from the longs returned by real_to_target. assemble_integer then went on to interpret the const_ints as though they had the mode corresponding to the accompanying size parameter: imode = mode_for_size (size * BITS_PER_UNIT, mclass, 0).require (); for (i = 0; i < size; i += subsize) { rtx partial = simplify_subreg (omode, x, imode, i); But in the assemble_real case, X might not be canonical for IMODE. If the interface to assemble_integer is supposed to allow outputting (say) the low 4 bytes of a DImode integer, then the simplify_subreg above is wrong. But if the number of bytes passed to assemble_integer is supposed to be the number of bytes that the integer actually contains, assemble_real is wrong. This patch takes the latter interpretation and makes assemble_real generate const_ints that are canonical for the number of bytes passed. The flip_storage_order handling assumes that each long is a full SImode, which e.g. excludes BITS_PER_UNIT != 8 and float formats whose memory size is not a multiple of 32 bits (which includes HFmode at least). The patch therefore leaves that code alone. If interpreting each integer as SImode is correct, the const_ints that it generates are also correct. 2019-09-18 Richard Sandiford gcc/ * varasm.c (assemble_real): Generate canonical const_ints. From-SVN: r275873 --- gcc/ChangeLog | 4 ++++ gcc/varasm.c | 14 ++++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1907307..a6869cf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2019-09-18 Richard Sandiford + + * varasm.c (assemble_real): Generate canonical const_ints. + 2019-09-18 Richard Biener PR lto/91763 diff --git a/gcc/varasm.c b/gcc/varasm.c index a7c2252..57365ad 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -2873,25 +2873,27 @@ assemble_real (REAL_VALUE_TYPE d, scalar_float_mode mode, unsigned int align, real_to_target (data, &d, mode); /* Put out the first word with the specified alignment. */ + unsigned int chunk_nunits = MIN (nunits, units_per); if (reverse) elt = flip_storage_order (SImode, gen_int_mode (data[nelts - 1], SImode)); else - elt = GEN_INT (data[0]); - assemble_integer (elt, MIN (nunits, units_per), align, 1); - nunits -= units_per; + elt = GEN_INT (sext_hwi (data[0], chunk_nunits * BITS_PER_UNIT)); + assemble_integer (elt, chunk_nunits, align, 1); + nunits -= chunk_nunits; /* Subsequent words need only 32-bit alignment. */ align = min_align (align, 32); for (int i = 1; i < nelts; i++) { + chunk_nunits = MIN (nunits, units_per); if (reverse) elt = flip_storage_order (SImode, gen_int_mode (data[nelts - 1 - i], SImode)); else - elt = GEN_INT (data[i]); - assemble_integer (elt, MIN (nunits, units_per), align, 1); - nunits -= units_per; + elt = GEN_INT (sext_hwi (data[i], chunk_nunits * BITS_PER_UNIT)); + assemble_integer (elt, chunk_nunits, align, 1); + nunits -= chunk_nunits; } } -- cgit v1.1 From 5fdd6038147e4ba30c8c01332dae8ab0d717bc14 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 18 Sep 2019 12:43:08 +0000 Subject: tree-vectorizer.h (get_initial_def_for_reduction): Remove. 2019-09-18 Richard Biener * tree-vectorizer.h (get_initial_def_for_reduction): Remove. * tree-vect-loop.c (get_initial_def_for_reduction): Make static. (vect_create_epilog_for_reduction): Remove dead code. From-SVN: r275874 --- gcc/ChangeLog | 7 +++++++ gcc/tree-vect-loop.c | 4 +--- gcc/tree-vectorizer.h | 1 - 3 files changed, 8 insertions(+), 4 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a6869cf..c4b27bf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2019-09-18 Richard Biener + + * tree-vectorizer.h (get_initial_def_for_reduction): Remove. + * tree-vect-loop.c (get_initial_def_for_reduction): Make + static. + (vect_create_epilog_for_reduction): Remove dead code. + 2019-09-18 Richard Sandiford * varasm.c (assemble_real): Generate canonical const_ints. diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index d8546ff..a455a6d 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -4203,7 +4203,7 @@ vect_model_induction_cost (stmt_vec_info stmt_info, int ncopies, A cost model should help decide between these two schemes. */ -tree +static tree get_initial_def_for_reduction (stmt_vec_info stmt_vinfo, tree init_val, tree *adjustment_def) { @@ -4585,7 +4585,6 @@ vect_create_epilog_for_reduction (vec vect_defs, (in case of SLP, do it for all the phis). */ /* Get the loop-entry arguments. */ - enum vect_def_type initial_def_dt = vect_unknown_def_type; if (slp_node) { unsigned vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); @@ -4623,7 +4622,6 @@ vect_create_epilog_for_reduction (vec vect_defs, { /* Do not use an adjustment def as that case is not supported correctly if ncopies is not one. */ - vect_is_simple_use (initial_def, loop_vinfo, &initial_def_dt); vec_initial_def = vect_get_vec_def_for_operand (initial_def, stmt_info); } diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 05ad1c6..40ff8b7 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -1645,7 +1645,6 @@ extern bool vectorizable_reduction (stmt_vec_info, gimple_stmt_iterator *, extern bool vectorizable_induction (stmt_vec_info, gimple_stmt_iterator *, stmt_vec_info *, slp_tree, stmt_vector_for_cost *); -extern tree get_initial_def_for_reduction (stmt_vec_info, tree, tree *); extern bool vect_worthwhile_without_simd_p (vec_info *, tree_code); extern int vect_get_known_peeling_cost (loop_vec_info, int, int *, stmt_vector_for_cost *, -- cgit v1.1