diff options
-rw-r--r-- | MAINTAINERS | 5 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64-sve.md | 64 | ||||
-rw-r--r-- | gcc/config/arm/arm.cc | 5 | ||||
-rw-r--r-- | gcc/config/arm/arm.md | 13 | ||||
-rw-r--r-- | gcc/config/arm/thumb1.md | 9 | ||||
-rw-r--r-- | gcc/config/arm/thumb2.md | 21 | ||||
-rw-r--r-- | gcc/doc/tm.texi | 10 | ||||
-rw-r--r-- | gcc/doc/tm.texi.in | 10 | ||||
-rw-r--r-- | gcc/testsuite/g++.target/aarch64/sve/pr121449.C | 44 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/arm/cmse/cmse-18.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/arm/cmse/cmse-19.c | 14 | ||||
-rw-r--r-- | gcc/tree-vect-loop.cc | 172 | ||||
-rw-r--r-- | gcc/tree-vect-stmts.cc | 15 | ||||
-rw-r--r-- | libgcc/Makefile.in | 1 | ||||
-rw-r--r-- | libgcc/config/aarch64/t-aarch64 | 2 | ||||
-rwxr-xr-x | libgcc/configure | 19 | ||||
-rw-r--r-- | libgcc/configure.ac | 14 | ||||
-rw-r--r-- | libgcobol/libgcobol.cc | 70 | ||||
-rw-r--r-- | libgcobol/stringbin.cc | 147 | ||||
-rw-r--r-- | libgcobol/stringbin.h | 5 |
20 files changed, 362 insertions, 285 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index bc607cb..dd31eed 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -276,7 +276,7 @@ check in changes outside of the parts of the compiler they maintain. Reviewers aarch64 port Alex Coplan <alex.coplan@arm.com> -aarch64 port Andrew Pinski <pinskia@gmail.com> +aarch64 port Andrew Pinski <andrew.pinski@oss.qualcomm.com> arm port (MVE) Christophe Lyon <christophe.lyon@arm.com> callgraph Martin Jambor <mjambor@suse.cz> C front end Marek Polacek <polacek@redhat.com> @@ -734,7 +734,7 @@ Sebastian Peryt speryt <sebastian.peryt@intel.com> Johannes Pfau jpfau <johannespfau@gmail.com> Gerald Pfeifer gerald <gerald@pfeifer.com> Kaushik Phatak kaushikp <kaushik.phatak@kpitcummins.com> -Andrew Pinski pinskia <pinskia@gmail.com> +Andrew Pinski pinskia <andrew.pinski@qualcomm.com> Nicolas Pitre nico <nico@cam.org> Michael Ploujnikov plouj <michael.ploujnikov@oracle.com> Paul Pluzhnikov ppluzhnikov <ppluzhnikov@google.com> @@ -959,6 +959,7 @@ Immad Mir <mir@sourceware.org> Gaius Mulley <gaiusmod2@gmail.com> Szabolcs Nagy <nsz@gcc.gnu.org> Andrew Pinski <quic_apinski@quicinc.com> +Andrew Pinski <andrew.pinski@oss.qualcomm.com> Siddhesh Poyarekar <siddhesh@gotplt.org> Ramana Radhakrishnan <ramanara@nvidia.com> Navid Rahimi <navidr@gcc.gnu.org> diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md index 88d323a..51e2d7d 100644 --- a/gcc/config/aarch64/aarch64-sve.md +++ b/gcc/config/aarch64/aarch64-sve.md @@ -1542,18 +1542,18 @@ UNSPEC_LD1_GATHER))] "TARGET_SVE && TARGET_NON_STREAMING" {@ [cons: =0, 1, 2, 3, 4, 5 ] - [&w, Z, w, Ui1, Ui1, Upl] ld1<Vesize>\t%0.s, %5/z, [%2.s] - [?w, Z, 0, Ui1, Ui1, Upl] ^ - [&w, vgw, w, Ui1, Ui1, Upl] ld1<Vesize>\t%0.s, %5/z, [%2.s, #%1] - [?w, vgw, 0, Ui1, Ui1, Upl] ^ - [&w, rk, w, Z, Ui1, Upl] ld1<Vesize>\t%0.s, %5/z, [%1, %2.s, sxtw] - [?w, rk, 0, Z, Ui1, Upl] ^ - [&w, rk, w, Ui1, Ui1, Upl] ld1<Vesize>\t%0.s, %5/z, [%1, %2.s, uxtw] - [?w, rk, 0, Ui1, Ui1, Upl] ^ - [&w, rk, w, Z, i, Upl] ld1<Vesize>\t%0.s, %5/z, [%1, %2.s, sxtw %p4] - [?w, rk, 0, Z, i, Upl] ^ - [&w, rk, w, Ui1, i, Upl] ld1<Vesize>\t%0.s, %5/z, [%1, %2.s, uxtw %p4] - [?w, rk, 0, Ui1, i, Upl] ^ + [&w, Z, w, Ui1, Ui1, Upl] ld1<Vesize>\t%0.s, %5/z, [%2.s] + [?w, Z, 0, Ui1, Ui1, Upl] ^ + [&w, vg<Vesize>, w, Ui1, Ui1, Upl] ld1<Vesize>\t%0.s, %5/z, [%2.s, #%1] + [?w, vg<Vesize>, 0, Ui1, Ui1, Upl] ^ + [&w, rk, w, Z, Ui1, Upl] ld1<Vesize>\t%0.s, %5/z, [%1, %2.s, sxtw] + [?w, rk, 0, Z, Ui1, Upl] ^ + [&w, rk, w, Ui1, Ui1, Upl] ld1<Vesize>\t%0.s, %5/z, [%1, %2.s, uxtw] + [?w, rk, 0, Ui1, Ui1, Upl] ^ + [&w, rk, w, Z, i, Upl] ld1<Vesize>\t%0.s, %5/z, [%1, %2.s, sxtw %p4] + [?w, rk, 0, Z, i, Upl] ^ + [&w, rk, w, Ui1, i, Upl] ld1<Vesize>\t%0.s, %5/z, [%1, %2.s, uxtw %p4] + [?w, rk, 0, Ui1, i, Upl] ^ } ) @@ -1572,14 +1572,14 @@ UNSPEC_LD1_GATHER))] "TARGET_SVE && TARGET_NON_STREAMING" {@ [cons: =0, 1, 2, 3, 4, 5] - [&w, Z, w, i, Ui1, Upl] ld1<Vesize>\t%0.d, %5/z, [%2.d] - [?w, Z, 0, i, Ui1, Upl] ^ - [&w, vgd, w, i, Ui1, Upl] ld1<Vesize>\t%0.d, %5/z, [%2.d, #%1] - [?w, vgd, 0, i, Ui1, Upl] ^ - [&w, rk, w, i, Ui1, Upl] ld1<Vesize>\t%0.d, %5/z, [%1, %2.d] - [?w, rk, 0, i, Ui1, Upl] ^ - [&w, rk, w, i, i, Upl] ld1<Vesize>\t%0.d, %5/z, [%1, %2.d, lsl %p4] - [?w, rk, 0, i, i, Upl] ^ + [&w, Z, w, i, Ui1, Upl] ld1<Vesize>\t%0.d, %5/z, [%2.d] + [?w, Z, 0, i, Ui1, Upl] ^ + [&w, vg<Vesize>, w, i, Ui1, Upl] ld1<Vesize>\t%0.d, %5/z, [%2.d, #%1] + [?w, vg<Vesize>, 0, i, Ui1, Upl] ^ + [&w, rk, w, i, Ui1, Upl] ld1<Vesize>\t%0.d, %5/z, [%1, %2.d] + [?w, rk, 0, i, Ui1, Upl] ^ + [&w, rk, w, i, i, Upl] ld1<Vesize>\t%0.d, %5/z, [%1, %2.d, lsl %p4] + [?w, rk, 0, i, i, Upl] ^ } ) @@ -2488,13 +2488,13 @@ (match_operand:SVE_4 4 "register_operand")] UNSPEC_ST1_SCATTER))] "TARGET_SVE && TARGET_NON_STREAMING" - {@ [ cons: 0 , 1 , 2 , 3 , 4 , 5 ] - [ Z , w , Ui1 , Ui1 , w , Upl ] st1<Vesize>\t%4.s, %5, [%1.s] - [ vgw , w , Ui1 , Ui1 , w , Upl ] st1<Vesize>\t%4.s, %5, [%1.s, #%0] - [ rk , w , Z , Ui1 , w , Upl ] st1<Vesize>\t%4.s, %5, [%0, %1.s, sxtw] - [ rk , w , Ui1 , Ui1 , w , Upl ] st1<Vesize>\t%4.s, %5, [%0, %1.s, uxtw] - [ rk , w , Z , i , w , Upl ] st1<Vesize>\t%4.s, %5, [%0, %1.s, sxtw %p3] - [ rk , w , Ui1 , i , w , Upl ] st1<Vesize>\t%4.s, %5, [%0, %1.s, uxtw %p3] + {@ [ cons: 0 , 1 , 2 , 3 , 4 , 5 ] + [ Z , w , Ui1 , Ui1 , w , Upl ] st1<Vesize>\t%4.s, %5, [%1.s] + [ vg<Vesize> , w , Ui1 , Ui1 , w , Upl ] st1<Vesize>\t%4.s, %5, [%1.s, #%0] + [ rk , w , Z , Ui1 , w , Upl ] st1<Vesize>\t%4.s, %5, [%0, %1.s, sxtw] + [ rk , w , Ui1 , Ui1 , w , Upl ] st1<Vesize>\t%4.s, %5, [%0, %1.s, uxtw] + [ rk , w , Z , i , w , Upl ] st1<Vesize>\t%4.s, %5, [%0, %1.s, sxtw %p3] + [ rk , w , Ui1 , i , w , Upl ] st1<Vesize>\t%4.s, %5, [%0, %1.s, uxtw %p3] } ) @@ -2511,11 +2511,11 @@ (match_operand:SVE_2 4 "register_operand")] UNSPEC_ST1_SCATTER))] "TARGET_SVE && TARGET_NON_STREAMING" - {@ [ cons: 0 , 1 , 3 , 4 , 5 ] - [ Z , w , Ui1 , w , Upl ] st1<Vesize>\t%4.d, %5, [%1.d] - [ vgd , w , Ui1 , w , Upl ] st1<Vesize>\t%4.d, %5, [%1.d, #%0] - [ rk , w , Ui1 , w , Upl ] st1<Vesize>\t%4.d, %5, [%0, %1.d] - [ rk , w , i , w , Upl ] st1<Vesize>\t%4.d, %5, [%0, %1.d, lsl %p3] + {@ [ cons: 0 , 1 , 3 , 4 , 5 ] + [ Z , w , Ui1 , w , Upl ] st1<Vesize>\t%4.d, %5, [%1.d] + [ vg<Vesize> , w , Ui1 , w , Upl ] st1<Vesize>\t%4.d, %5, [%1.d, #%0] + [ rk , w , Ui1 , w , Upl ] st1<Vesize>\t%4.d, %5, [%0, %1.d] + [ rk , w , i , w , Upl ] st1<Vesize>\t%4.d, %5, [%0, %1.d, lsl %p3] } ) diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc index 29b45ae..8b951f3 100644 --- a/gcc/config/arm/arm.cc +++ b/gcc/config/arm/arm.cc @@ -18983,7 +18983,8 @@ cmse_nonsecure_call_inline_register_clear (void) call = SET_SRC (call); /* Check if it is a cmse_nonsecure_call. */ - unspec = XEXP (call, 0); + unspec = XVECEXP (pat, 0, 2); + if (GET_CODE (unspec) != UNSPEC || XINT (unspec, 1) != UNSPEC_NONSECURE_MEM) continue; @@ -19010,7 +19011,7 @@ cmse_nonsecure_call_inline_register_clear (void) /* Make sure the register used to hold the function address is not cleared. */ - address = RTVEC_ELT (XVEC (unspec, 0), 0); + address = XEXP (call, 0); gcc_assert (MEM_P (address)); gcc_assert (REG_P (XEXP (address, 0))); address_regnum = REGNO (XEXP (address, 0)); diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 5e5e112..537a3e2 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -8623,7 +8623,7 @@ if (detect_cmse_nonsecure_call (addr)) { pat = gen_nonsecure_call_internal (operands[0], operands[1], - operands[2]); + operands[2], const0_rtx); emit_call_insn (pat); } else @@ -8665,10 +8665,10 @@ (clobber (reg:SI LR_REGNUM))])]) (define_expand "nonsecure_call_internal" - [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand")] - UNSPEC_NONSECURE_MEM) + [(parallel [(call (match_operand 0 "memory_operand") (match_operand 1 "general_operand")) (use (match_operand 2 "" "")) + (unspec:SI [(match_operand 3)] UNSPEC_NONSECURE_MEM) (clobber (reg:SI LR_REGNUM))])] "use_cmse" { @@ -8745,7 +8745,8 @@ if (detect_cmse_nonsecure_call (addr)) { pat = gen_nonsecure_call_value_internal (operands[0], operands[1], - operands[2], operands[3]); + operands[2], operands[3], + const0_rtx); emit_call_insn (pat); } else @@ -8779,10 +8780,10 @@ (define_expand "nonsecure_call_value_internal" [(parallel [(set (match_operand 0 "" "") - (call (unspec:SI [(match_operand 1 "memory_operand")] - UNSPEC_NONSECURE_MEM) + (call (match_operand 1 "memory_operand") (match_operand 2 "general_operand"))) (use (match_operand 3 "" "")) + (unspec:SI [(match_operand 4)] UNSPEC_NONSECURE_MEM) (clobber (reg:SI LR_REGNUM))])] "use_cmse" " diff --git a/gcc/config/arm/thumb1.md b/gcc/config/arm/thumb1.md index f9e89e9..4da0086 100644 --- a/gcc/config/arm/thumb1.md +++ b/gcc/config/arm/thumb1.md @@ -1874,10 +1874,10 @@ ) (define_insn "*nonsecure_call_reg_thumb1_v5" - [(call (unspec:SI [(mem:SI (reg:SI R4_REGNUM))] - UNSPEC_NONSECURE_MEM) + [(call (mem:SI (reg:SI R4_REGNUM)) (match_operand 0 "" "")) (use (match_operand 1 "" "")) + (unspec:SI [(match_operand 2)]UNSPEC_NONSECURE_MEM) (clobber (reg:SI LR_REGNUM))] "TARGET_THUMB1 && use_cmse && !SIBLING_CALL_P (insn)" "bl\\t__gnu_cmse_nonsecure_call" @@ -1919,11 +1919,10 @@ (define_insn "*nonsecure_call_value_reg_thumb1_v5" [(set (match_operand 0 "" "") - (call (unspec:SI - [(mem:SI (reg:SI R4_REGNUM))] - UNSPEC_NONSECURE_MEM) + (call (mem:SI (reg:SI R4_REGNUM)) (match_operand 1 "" ""))) (use (match_operand 2 "" "")) + (unspec:SI [(match_operand 3)] UNSPEC_NONSECURE_MEM) (clobber (reg:SI LR_REGNUM))] "TARGET_THUMB1 && use_cmse" "bl\\t__gnu_cmse_nonsecure_call" diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md index 019f9d4..2c2026b 100644 --- a/gcc/config/arm/thumb2.md +++ b/gcc/config/arm/thumb2.md @@ -537,10 +537,10 @@ ) (define_insn "*nonsecure_call_reg_thumb2_fpcxt" - [(call (unspec:SI [(mem:SI (match_operand:SI 0 "s_register_operand" "l*r"))] - UNSPEC_NONSECURE_MEM) + [(call (mem:SI (match_operand:SI 0 "s_register_operand" "l*r")) (match_operand 1 "" "")) (use (match_operand 2 "" "")) + (unspec:SI [(match_operand 3)] UNSPEC_NONSECURE_MEM) (clobber (reg:SI LR_REGNUM))] "TARGET_THUMB2 && use_cmse && TARGET_HAVE_FPCXT_CMSE" "blxns\\t%0" @@ -549,10 +549,10 @@ ) (define_insn "*nonsecure_call_reg_thumb2" - [(call (unspec:SI [(mem:SI (reg:SI R4_REGNUM))] - UNSPEC_NONSECURE_MEM) + [(call (mem:SI (reg:SI R4_REGNUM)) (match_operand 0 "" "")) (use (match_operand 1 "" "")) + (unspec:SI [(match_operand 2)] UNSPEC_NONSECURE_MEM) (clobber (reg:SI LR_REGNUM))] "TARGET_THUMB2 && use_cmse && !TARGET_HAVE_FPCXT_CMSE" "bl\\t__gnu_cmse_nonsecure_call" @@ -573,11 +573,10 @@ (define_insn "*nonsecure_call_value_reg_thumb2_fpcxt" [(set (match_operand 0 "" "") - (call - (unspec:SI [(mem:SI (match_operand:SI 1 "register_operand" "l*r"))] - UNSPEC_NONSECURE_MEM) - (match_operand 2 "" ""))) + (call (mem:SI (match_operand:SI 1 "register_operand" "l*r")) + (match_operand 2 "" ""))) (use (match_operand 3 "" "")) + (unspec:SI [(match_operand 4)] UNSPEC_NONSECURE_MEM) (clobber (reg:SI LR_REGNUM))] "TARGET_THUMB2 && use_cmse && TARGET_HAVE_FPCXT_CMSE" "blxns\\t%1" @@ -587,10 +586,10 @@ (define_insn "*nonsecure_call_value_reg_thumb2" [(set (match_operand 0 "" "") - (call - (unspec:SI [(mem:SI (reg:SI R4_REGNUM))] UNSPEC_NONSECURE_MEM) - (match_operand 1 "" ""))) + (call (mem:SI (reg:SI R4_REGNUM)) + (match_operand 1 "" ""))) (use (match_operand 2 "" "")) + (unspec:SI [(match_operand 3)] UNSPEC_NONSECURE_MEM) (clobber (reg:SI LR_REGNUM))] "TARGET_THUMB2 && use_cmse && !TARGET_HAVE_FPCXT_CMSE" "bl\\t__gnu_cmse_nonsecure_call" diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 4d4e676..4c338c3 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -37,6 +37,8 @@ through the macros defined in the @file{.h} file. * Trampolines:: Code set up at run time to enter a nested function. * Library Calls:: Controlling how library routines are implicitly called. * Addressing Modes:: Defining addressing modes valid for memory operands. +* Vectorization:: Controlling how the vectorizer operates. +* OpenMP and OpenACC:: Defining how OpenMP and OpenACC features should work. * Anchored Addresses:: Defining how @option{-fsection-anchors} should work. * Condition Code:: Defining how insns update the condition code. * Costs:: Defining relative costs of different operations. @@ -6282,6 +6284,10 @@ reciprocal of the machine-specific builtin function @var{fndecl}, or @code{NULL_TREE} if such a function is not available. @end deftypefn +@node Vectorization +@section Vectorization +@cindex Vectorization + @deftypefn {Target Hook} tree TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD (void) This hook should return the DECL of a function @var{f} that given an address @var{addr} as an argument returns a mask @var{m} that can be @@ -6522,6 +6528,10 @@ number of scalar elements in each scalar loop iteration that are to be combined into the vector. @end deftypefn +@node OpenMP and OpenACC +@section OpenMP and OpenACC +@cindex OpenMP and OpenACC + @deftypefn {Target Hook} int TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN (struct cgraph_node *@var{}, struct cgraph_simd_clone *@var{}, @var{tree}, @var{int}, @var{bool}) This hook should set @var{vecsize_mangle}, @var{vecsize_int}, @var{vecsize_float} fields in @var{simd_clone} structure pointed by @var{clone_info} argument and also diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 1a51ad5..12b8ed6 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -37,6 +37,8 @@ through the macros defined in the @file{.h} file. * Trampolines:: Code set up at run time to enter a nested function. * Library Calls:: Controlling how library routines are implicitly called. * Addressing Modes:: Defining addressing modes valid for memory operands. +* Vectorization:: Controlling how the vectorizer operates. +* OpenMP and OpenACC:: Defining how OpenMP and OpenACC features should work. * Anchored Addresses:: Defining how @option{-fsection-anchors} should work. * Condition Code:: Defining how insns update the condition code. * Costs:: Defining relative costs of different operations. @@ -4273,6 +4275,10 @@ address; but often a machine-dependent strategy can generate better code. @hook TARGET_BUILTIN_RECIPROCAL +@node Vectorization +@section Vectorization +@cindex Vectorization + @hook TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD @hook TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST @@ -4313,6 +4319,10 @@ address; but often a machine-dependent strategy can generate better code. @hook TARGET_VECTORIZE_PREFER_GATHER_SCATTER +@node OpenMP and OpenACC +@section OpenMP and OpenACC +@cindex OpenMP and OpenACC + @hook TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN @hook TARGET_SIMD_CLONE_ADJUST diff --git a/gcc/testsuite/g++.target/aarch64/sve/pr121449.C b/gcc/testsuite/g++.target/aarch64/sve/pr121449.C new file mode 100644 index 0000000..b2e1376 --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/sve/pr121449.C @@ -0,0 +1,44 @@ +/* PR target/121449 */ +/* { dg-do assemble { target aarch64_asm_sve_ok } } */ +/* { dg-options "-O3 -save-temps" } */ + +struct example; + +struct array { + unsigned length(); + example *operator[](unsigned i) { + example **data = reinterpret_cast<example **>(this); + return data[i]; + } +}; + +struct example { + int a[16]; + bool is_even; + int version; + int count() { return is_even ? 2 : 1; } + void fun1(int, long); + void fun2(unsigned, unsigned); + void process(array &, array &); +}; + +bool found; + +void example::process(array &a, array &b) { + for (unsigned i = 1; a.length(); i++) { + long total = 0; + for (unsigned k = 0; k <= i; k++) { + total += a[k]->count(); + } + for (unsigned j = 0; j < i; j++) { + int major = b[j]->version; + if (found) + major += i; + fun1(i + 1, total); + fun2(j, major); + } + } +} + +/* { dg-final { scan-assembler-not {\tld1b\t(z[0-9]+)\.d, p[0-7]/z, \[(z[0-9]+)\.d, #64\]} } } */ + diff --git a/gcc/testsuite/gcc.target/arm/cmse/cmse-18.c b/gcc/testsuite/gcc.target/arm/cmse/cmse-18.c index db7d975..eb8a358 100644 --- a/gcc/testsuite/gcc.target/arm/cmse/cmse-18.c +++ b/gcc/testsuite/gcc.target/arm/cmse/cmse-18.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ -/* { dg-options "-mcmse -fdump-rtl-final-slim" } */ +/* Make sure FPCXT is not enabled. */ +/* { dg-options "-mcmse -fdump-rtl-final -march=armv8-m.main+fp" } */ typedef void (*f)(int) __attribute__((cmse_nonsecure_call)); @@ -8,5 +9,5 @@ void bar(f func, int a) func(a); } -/* { dg-final { scan-rtl-dump "call unspec\\\[\\\[r4:SI\\\]\\\]" "final" { target { ! arm_v8_1m_mve_ok } } } } */ -/* { dg-final { scan-rtl-dump "call unspec\\\[\\\[r\[0-7\]:SI\\\]\\\]" "final" { target { arm_v8_1m_mve_ok } } } } */ +/* { dg-final { scan-rtl-dump "call \\\(mem:SI \\\(reg:SI 4 r4" "final" } } */ +/* { dg-final { scan-rtl-dump "UNSPEC_NONSECURE_MEM" "final" } } */ diff --git a/gcc/testsuite/gcc.target/arm/cmse/cmse-19.c b/gcc/testsuite/gcc.target/arm/cmse/cmse-19.c new file mode 100644 index 0000000..ae075c3 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/cmse/cmse-19.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* This is a duplicate of cmse-18.c, targetting arm_v8_1m_mve, to make sure + FPCXT is enabled. */ +/* { dg-options "-mcmse -fdump-rtl-final -march=armv8.1-m.main+mve" } */ + +typedef void (*f)(int) __attribute__((cmse_nonsecure_call)); + +void bar(f func, int a) +{ + func(a); +} + +/* { dg-final { scan-rtl-dump "call \\\(mem:SI \\\(reg/f:SI \[0-7] r\[0-7\]" "final" } } */ +/* { dg-final { scan-rtl-dump "UNSPEC_NONSECURE_MEM" "final" } } */ diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc index cab503c..5fc24dc 100644 --- a/gcc/tree-vect-loop.cc +++ b/gcc/tree-vect-loop.cc @@ -163,169 +163,6 @@ static void vect_estimate_min_profitable_iters (loop_vec_info, int *, int *, static stmt_vec_info vect_is_simple_reduction (loop_vec_info, stmt_vec_info, bool *, bool *, bool); -/* Subroutine of vect_determine_vf_for_stmt that handles only one - statement. VECTYPE_MAYBE_SET_P is true if STMT_VINFO_VECTYPE - may already be set for general statements (not just data refs). */ - -static opt_result -vect_determine_vectype_for_stmt_1 (vec_info *vinfo, stmt_vec_info stmt_info, - bool vectype_maybe_set_p) -{ - gimple *stmt = stmt_info->stmt; - - if ((!STMT_VINFO_RELEVANT_P (stmt_info) - && !STMT_VINFO_LIVE_P (stmt_info)) - || gimple_clobber_p (stmt)) - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "skip.\n"); - return opt_result::success (); - } - - tree stmt_vectype, nunits_vectype; - opt_result res = vect_get_vector_types_for_stmt (vinfo, stmt_info, - &stmt_vectype, - &nunits_vectype); - if (!res) - return res; - - if (stmt_vectype) - { - if (STMT_VINFO_VECTYPE (stmt_info)) - /* The only case when a vectype had been already set is for stmts - that contain a data ref, or for "pattern-stmts" (stmts generated - by the vectorizer to represent/replace a certain idiom). */ - gcc_assert ((STMT_VINFO_DATA_REF (stmt_info) - || vectype_maybe_set_p) - && STMT_VINFO_VECTYPE (stmt_info) == stmt_vectype); - else - STMT_VINFO_VECTYPE (stmt_info) = stmt_vectype; - } - - return opt_result::success (); -} - -/* Subroutine of vect_determine_vectorization_factor. Set the vector - types of STMT_INFO and all attached pattern statements and update - the vectorization factor VF accordingly. Return true on success - or false if something prevented vectorization. */ - -static opt_result -vect_determine_vectype_for_stmt (vec_info *vinfo, stmt_vec_info stmt_info) -{ - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "==> examining statement: %G", - stmt_info->stmt); - opt_result res = vect_determine_vectype_for_stmt_1 (vinfo, stmt_info, false); - if (!res) - return res; - - if (STMT_VINFO_IN_PATTERN_P (stmt_info) - && STMT_VINFO_RELATED_STMT (stmt_info)) - { - gimple *pattern_def_seq = STMT_VINFO_PATTERN_DEF_SEQ (stmt_info); - stmt_info = STMT_VINFO_RELATED_STMT (stmt_info); - - /* If a pattern statement has def stmts, analyze them too. */ - for (gimple_stmt_iterator si = gsi_start (pattern_def_seq); - !gsi_end_p (si); gsi_next (&si)) - { - stmt_vec_info def_stmt_info = vinfo->lookup_stmt (gsi_stmt (si)); - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, - "==> examining pattern def stmt: %G", - def_stmt_info->stmt); - res = vect_determine_vectype_for_stmt_1 (vinfo, def_stmt_info, true); - if (!res) - return res; - } - - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, - "==> examining pattern statement: %G", - stmt_info->stmt); - res = vect_determine_vectype_for_stmt_1 (vinfo, stmt_info, true); - if (!res) - return res; - } - - return opt_result::success (); -} - -/* Function vect_set_stmts_vectype - - Set STMT_VINFO_VECTYPE of all stmts. */ - -static opt_result -vect_set_stmts_vectype (loop_vec_info loop_vinfo) -{ - class loop *loop = LOOP_VINFO_LOOP (loop_vinfo); - basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo); - unsigned nbbs = loop->num_nodes; - tree scalar_type = NULL_TREE; - gphi *phi; - tree vectype; - stmt_vec_info stmt_info; - unsigned i; - - DUMP_VECT_SCOPE ("vect_set_stmts_vectype"); - - for (i = 0; i < nbbs; i++) - { - basic_block bb = bbs[i]; - - for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si); - gsi_next (&si)) - { - phi = si.phi (); - stmt_info = loop_vinfo->lookup_stmt (phi); - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "==> examining phi: %G", - (gimple *) phi); - - gcc_assert (stmt_info); - - if (STMT_VINFO_RELEVANT_P (stmt_info) - || STMT_VINFO_LIVE_P (stmt_info)) - { - gcc_assert (!STMT_VINFO_VECTYPE (stmt_info)); - scalar_type = TREE_TYPE (PHI_RESULT (phi)); - - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, - "get vectype for scalar type: %T\n", - scalar_type); - - vectype = get_vectype_for_scalar_type (loop_vinfo, scalar_type); - if (!vectype) - return opt_result::failure_at (phi, - "not vectorized: unsupported " - "data-type %T\n", - scalar_type); - STMT_VINFO_VECTYPE (stmt_info) = vectype; - - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "vectype: %T\n", - vectype); - } - } - - for (gimple_stmt_iterator si = gsi_start_bb (bb); !gsi_end_p (si); - gsi_next (&si)) - { - if (is_gimple_debug (gsi_stmt (si))) - continue; - stmt_info = loop_vinfo->lookup_stmt (gsi_stmt (si)); - opt_result res - = vect_determine_vectype_for_stmt (loop_vinfo, stmt_info); - if (!res) - return res; - } - } - - return opt_result::success (); -} - /* Function vect_is_simple_iv_evolution. @@ -2483,15 +2320,6 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo, bool &fatal, } LOOP_VINFO_MAX_VECT_FACTOR (loop_vinfo) = max_vf; - ok = vect_set_stmts_vectype (loop_vinfo); - if (!ok) - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "cannot determine vector types.\n"); - return ok; - } - /* Compute the scalar iteration cost. */ vect_compute_single_scalar_iteration_cost (loop_vinfo); diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index eff5e88..26d5be5 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -724,14 +724,21 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo, bool *fatal) if (vect_stmt_relevant_p (phi_info, loop_vinfo, &relevant, &live_p)) vect_mark_relevant (&worklist, phi_info, relevant, live_p); } - for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si)) + for (si = gsi_after_labels (bb); !gsi_end_p (si); gsi_next (&si)) { - if (is_gimple_debug (gsi_stmt (si))) + gimple *stmt = gsi_stmt (si); + if (is_gimple_debug (stmt)) continue; - stmt_vec_info stmt_info = loop_vinfo->lookup_stmt (gsi_stmt (si)); + stmt_vec_info stmt_info = loop_vinfo->lookup_stmt (stmt); if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "init: stmt relevant? %G", stmt_info->stmt); + "init: stmt relevant? %G", stmt); + + if (gimple_get_lhs (stmt) == NULL_TREE + && !is_a <gcond *> (stmt) + && !is_a <gcall *> (stmt)) + return opt_result::failure_at + (stmt, "not vectorized: irregular stmt: %G", stmt); if (vect_stmt_relevant_p (stmt_info, loop_vinfo, &relevant, &live_p)) vect_mark_relevant (&worklist, stmt_info, relevant, live_p); diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in index f7b48dc..e258f94 100644 --- a/libgcc/Makefile.in +++ b/libgcc/Makefile.in @@ -87,6 +87,7 @@ CC = @CC@ CFLAGS = @CFLAGS@ RANLIB = @RANLIB@ LN_S = @LN_S@ +WERROR = @WERROR@ PWD_COMMAND = $${PWDCMD-pwd} diff --git a/libgcc/config/aarch64/t-aarch64 b/libgcc/config/aarch64/t-aarch64 index d4c5922..c7d83c7 100644 --- a/libgcc/config/aarch64/t-aarch64 +++ b/libgcc/config/aarch64/t-aarch64 @@ -30,4 +30,4 @@ LIB2ADDEH += \ $(srcdir)/config/aarch64/__arm_za_disable.S SHLIB_MAPFILES += $(srcdir)/config/aarch64/libgcc-sme.ver -LIBGCC2_CFLAGS += -Werror -Wno-prio-ctor-dtor +LIBGCC2_CFLAGS += $(WERROR) -Wno-prio-ctor-dtor diff --git a/libgcc/configure b/libgcc/configure index 1841833..d5e80d2 100755 --- a/libgcc/configure +++ b/libgcc/configure @@ -586,6 +586,7 @@ ac_unique_file="static-object.mk" ac_includes_default='/* none */' ac_subst_vars='LTLIBOBJS LIBOBJS +WERROR md_unwind_header md_unwind_def_header unwind_header @@ -720,6 +721,7 @@ enable_tm_clone_registry with_glibc_version enable_tls with_gcc_major_version_only +enable_werror ' ac_precious_vars='build_alias host_alias @@ -1362,6 +1364,7 @@ Optional Features: installations without PT_GNU_EH_FRAME support --disable-tm-clone-registry disable TM clone registry --enable-tls Use thread-local storage [default=yes] + --enable-werror build with -Werror for selected targets Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -5789,6 +5792,22 @@ fi +# Check whether --enable-werror was given. +if test "${enable_werror+set}" = set; then : + enableval=$enable_werror; +case ${enable_werror} in + no) WERROR="" ;; + *) WERROR="-Werror" ;; +esac + +else + +WERROR="-Werror" + +fi + + + # We need multilib support. ac_config_files="$ac_config_files Makefile" diff --git a/libgcc/configure.ac b/libgcc/configure.ac index 85e4f1b..65cd3c6 100644 --- a/libgcc/configure.ac +++ b/libgcc/configure.ac @@ -733,6 +733,20 @@ AC_SUBST(md_unwind_header) AC_SUBST(sfp_machine_header) AC_SUBST(thread_header) +AC_ARG_ENABLE(werror, +[AS_HELP_STRING([--enable-werror], + [build with -Werror for selected targets])], +[ +case ${enable_werror} in + no) WERROR="" ;; + *) WERROR="-Werror" ;; +esac +], +[ +WERROR="-Werror" +]) +AC_SUBST(WERROR) + # We need multilib support. AC_CONFIG_FILES([Makefile]) AC_CONFIG_COMMANDS([default], diff --git a/libgcobol/libgcobol.cc b/libgcobol/libgcobol.cc index a7b4b55..eac6e31 100644 --- a/libgcobol/libgcobol.cc +++ b/libgcobol/libgcobol.cc @@ -1719,34 +1719,27 @@ int128_to_field(cblc_field_t *var, case FldPacked: { - static const unsigned char bin2pd[100] = - { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, - } ; - // Convert the binary value to packed decimal. + int digits = var->digits; - // Set the destination bytes to zero - memset(location, 0, length); + // Assume for the moment that the res unsigned char sign_nybble = 0; - if( !(var->attr & packed_no_sign_e) ) + if( var->attr & packed_no_sign_e ) + { + // This is COMP-6 packed decimal, with no sign nybble + sign_nybble = 0; + } + else { // This is COMP-3 packed decimal, so we need to make room to the // right of the final decimal digit for the sign nybble: value *= 10; + digits += 1; // Figure out what the sign nybble is going to be, and make the // the value positive: if(var->attr & signable_e) { + // It is signable, so 0xD for negative, and 0xC for positive if(value < 0) { sign_nybble = 0x0D; @@ -1759,6 +1752,7 @@ int128_to_field(cblc_field_t *var, } else { + // The value is not signable, so the sign nybble is 0xF sign_nybble = 0x0F; if(value < 0) { @@ -1766,43 +1760,25 @@ int128_to_field(cblc_field_t *var, } } } - // ploc points to the current rightmost byte of the location: - unsigned char *ploc = location + length -1 ; - // Build the target from right to left, so that the result is - // big-endian: - while( value && ploc >= location ) - { - *ploc-- = bin2pd[value%100]; - value /= 100; - } + /* We need to check if the value is too big, in case our caller + wants to check for the error condition. In any event, we need + to make sure the value actually fits, because otherwise the + result might have a bad high-place digit for a value with an + odd number of places. */ + __int128 mask = __gg__power_of_ten(digits); + size_error = !!(value / mask); + value %= mask; + + // We are now set up to do the conversion: + __gg__binary_to_packed(location, digits, value); + // We can put the sign nybble into place at this point. Note that // for COMP-6 numbers the sign_nybble value is zero, so the next // operation is harmless. location[length -1] |= sign_nybble; - // If we still have value left, we have a size error - if( value ) - { - size_error = true; - } - else - { - if( ( sign_nybble && !(var->digits&1) ) - || ( !sign_nybble && (var->digits&1) ) ) - { - // This is either - // comp-3 with an even number of digits, or - // comp-6 with an odd number of digits. - // Either way, the first byte of the target has to have a high - // nybble of zero. If it's non-zero, then we have a size error: - if( location[0] & 0xF0 ) - { - size_error = true; - } - } - } // And we're done. break; } diff --git a/libgcobol/stringbin.cc b/libgcobol/stringbin.cc index d35ea82..2cc229e 100644 --- a/libgcobol/stringbin.cc +++ b/libgcobol/stringbin.cc @@ -328,3 +328,150 @@ __gg__binary_to_string_internal(char *result, int digits, __int128 value) return retval; } + +static +void +packed_from_combined(COMBINED &combined) + { + /* The combined.value must be positive at this point. + + The combined.run value has to be the number of places needed to hold + combined.value. The proper calculation is (digits+1)/2. + + For a signable value, the caller had to multiple the original value by + ten to create room on the right for the sign nybble. */ + + static const unsigned char bin2pd[100] = + { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, + } ; + + COMBINED left; + COMBINED right; + + switch(combined.run) + { + case 1: + // We know that val8 has two digits. + combined_string[combined.start] = bin2pd[combined.val8]; + break; + + case 2: + // We know that val16 has four digits. + combined_string[combined.start ] = bin2pd[combined.val16/100]; + combined_string[combined.start+1] = bin2pd[combined.val16%100]; + break; + + case 3: + case 4: + // We know that val32 can hold up to eight digits. Break it in half. + left.start = combined.start; + left.run = combined.run - 2; + left.val16 = combined.val32 / 10000; + + right.start = combined.start+left.run; + right.run = 2; + right.val16 = combined.val32 % 10000; + + packed_from_combined(left); + packed_from_combined(right); + break; + + case 5: + case 6: + case 7: + case 8: + // We know that val64 is holding up to 18 digits. Break it into two + // eight-digit places that can each go into a val23 + left.start = combined.start; + left.run = combined.run - 4; + left.val32 = combined.val64 / 100000000; + + right.start = combined.start+left.run; + right.run = 4; + right.val32 = combined.val64 % 100000000; + + packed_from_combined(left); + packed_from_combined(right); + break; + + case 9: + // We know that val64 is holding 17 or 18 digits. Break off the + // bottom eight. + left.start = combined.start; + left.run = combined.run - 4; + left.val64 = combined.val64 / 100000000; + + right.start = combined.start+left.run; + right.run = 4; + right.val32 = combined.val64 % 100000000; + + packed_from_combined(left); + packed_from_combined(right); + break; + + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + // We know that val64 is holding between 18 and 36 digits. Break it + // two val64: + + left.start = combined.start; + left.run = combined.run - 9; + left.val64 = combined.val128 / 1000000000000000000ULL; + + right.start = combined.start+left.run; + right.run = 9; + right.val64 = combined.val128 % 1000000000000000000ULL; + + packed_from_combined(left); + packed_from_combined(right); + break; + + default: + // For twenty or more digits we peel eighteen digits at a time off the + // right side: + left.start = combined.start; + left.run = combined.run - 9; + left.val128 = combined.val128 / 1000000000000000000ULL; + + right.start = combined.start+left.run; + right.run = 9; + right.val64 = combined.val128 % 1000000000000000000ULL; + + packed_from_combined(left); + packed_from_combined(right); + break; + } + } + +extern "C" +void +__gg__binary_to_packed( unsigned char *result, + int digits, + __int128 value) + { + size_t length = (digits+1)/2; + + COMBINED combined; + combined.start = 0; + combined.run = length; + combined.val128 = value; + packed_from_combined(combined); + memcpy(result, combined_string, length); + } diff --git a/libgcobol/stringbin.h b/libgcobol/stringbin.h index 0276704..5ddb441 100644 --- a/libgcobol/stringbin.h +++ b/libgcobol/stringbin.h @@ -39,4 +39,9 @@ bool __gg__binary_to_string_internal( char *result, int digits, __int128 value); +extern "C" +void __gg__binary_to_packed( unsigned char *result, + int digits, + __int128 value); + #endif |