public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH][ARM] -mpure-code option for ARM
@ 2016-06-30 14:46 Andre Vieira (lists)
  2016-07-01 19:04 ` Sandra Loosemore
                   ` (2 more replies)
  0 siblings, 3 replies; 24+ messages in thread
From: Andre Vieira (lists) @ 2016-06-30 14:46 UTC (permalink / raw)
  To: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 2539 bytes --]

Hello,

This patch adds the -mpure-code option for ARM. This option ensures
functions are put into sections that contain only code and no data. To
ensure this throughout compilation we give these sections the ARM
processor-specific ELF section attribute "SHF_ARM_PURECODE". This option
is only supported for non-pic code for armv7-m targets.

This patch introduces a new target hook 'TARGET_ASM_ELF_FLAGS_NUMERIC'.
This target hook enables a target to use the numeric value for elf
section attributes rather than their alphabetical representation. If
TARGET_ASM_ELF_FLAGS_NUMERIC returns TRUE, the existing
'default_elf_asm_named_section', will print the numeric value of the
section attributes for the current section. This target hook has two
parameters:
unsigned int FLAGS, the input parameter that tells the function the
current section's attributes;
unsigned int *NUM, used to pass down the numerical representation of the
section's attributes.

The default implementation for TARGET_ASM_ELF_FLAGS_NUMERIC will return
false, so existing behavior is not changed.

Bootstrapped and tested for arm-none-linux-gnueabihf. Further tested for
arm-none-eabi with a Cortex-M3 target.


gcc/ChangeLog:
2016-06-30  Andre Vieira  <andre.simoesdiasvieira@arm.com>
            Terry Guo  <terry.guo@arm.com>

        * target.def (elf_flags_numeric): New target hook.
        * targhooks.h (default_asm_elf_flags_numeric): New.
        * varasm.c (default_asm_elf_flags_numeric): New.
          (default_elf_asm_named_section): Use new target hook.
        * config/arm/arm.opt (mpure-code): New.
        * config/arm/arm.h (SECTION_ARM_PURECODE): New.
        * config/arm/arm.c (arm_asm_init_sections): Add section
          attribute to default text section if -mpure-code.
          (arm_option_check_internal): Diagnose use of option with
          non supported targets and/or options.
          (arm_asm_elf_flags_numeric): New.
          (arm_function_section): New.
          (arm_elf_section_type_flags): New.
        * config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Disable
          for -mpure-code.
        * gcc/doc/texi (TARGET_ASM_ELF_FLAGS_NUMERIC): New.
        * gcc/doc/texi.in (TARGET_ASM_ELF_FLAGS_NUMERIC): Likewise.



gcc/testsuite/ChangeLog:
2016-06-30  Andre Vieira  <andre.simoesdiasvieira@arm.com>
            Terry Guo  <terry.guo@arm.com>

        * gcc.target/arm/pure-code/ffunction-sections.c: New.
        * gcc.target/arm/pure-code/no-literal-pool.c: New.
        * gcc.target/arm/pure-code/pure-code.exp: New.

[-- Attachment #2: 0001-mpure-code-for-ARM.patch --]
[-- Type: text/x-patch, Size: 21766 bytes --]

diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index f0cdd669191689bc5dcf3a7c2b60da5a2d201e3f..d10605cee0e6e0e07bbb4e1910d30c91443f8d17 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -2263,4 +2263,8 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
 /* For switching between functions with different target attributes.  */
 #define SWITCHABLE_TARGET 1
 
+/* Define SECTION_ARM_PURECODE as the ARM specific section attribute
+   representation for SHF_ARM_PURECODE in GCC.  */
+#define SECTION_ARM_PURECODE SECTION_MACH_DEP
+
 #endif /* ! GCC_ARM_H */
From 6f3e37973e0c4dbd393325addf42265c42726240 Mon Sep 17 00:00:00 2001
From: Andre Simoes Dias Vieira <andsim01@arm.com>
Date: Tue, 14 Jun 2016 11:17:12 +0100
Subject: [PATCH] -mpure-code for ARM

---
 gcc/config/arm/arm.c                               | 150 ++++++++++++++++++++-
 gcc/config/arm/arm.h                               |   4 +
 gcc/config/arm/arm.opt                             |   6 +
 gcc/config/arm/elf.h                               |   3 +-
 gcc/doc/invoke.texi                                |  11 +-
 gcc/doc/tm.texi                                    |   6 +
 gcc/doc/tm.texi.in                                 |   2 +
 gcc/target.def                                     |  10 ++
 gcc/targhooks.h                                    |   2 +
 .../gcc.target/arm/pure-code/ffunction-sections.c  |  17 +++
 .../gcc.target/arm/pure-code/no-literal-pool.c     |  73 ++++++++++
 .../gcc.target/arm/pure-code/pure-code.exp         |  54 ++++++++
 gcc/varasm.c                                       |  57 +++++---
 13 files changed, 366 insertions(+), 29 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c
 create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c
 create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index f60955438d6f1cc5d996e7eacd4b453213044181..f5cb301a0efb23dc66e4d220b4a8f32e3670e744 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -214,8 +214,8 @@ static bool arm_return_in_memory (const_tree, const_tree);
 static void arm_unwind_emit (FILE *, rtx_insn *);
 static bool arm_output_ttype (rtx);
 static void arm_asm_emit_except_personality (rtx);
-static void arm_asm_init_sections (void);
 #endif
+static void arm_asm_init_sections (void);
 static rtx arm_dwarf_register_span (rtx);
 
 static tree arm_cxx_guard_type (void);
@@ -299,7 +299,10 @@ static unsigned HOST_WIDE_INT arm_asan_shadow_offset (void);
 static void arm_sched_fusion_priority (rtx_insn *, int, int *, int*);
 static bool arm_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT,
 				     const_tree);
-
+static section *arm_function_section (tree, enum node_frequency, bool, bool);
+static bool arm_asm_elf_flags_numeric (unsigned int flags, unsigned int *num);
+static unsigned int arm_elf_section_type_flags (tree decl, const char *name,
+						int reloc);
 \f
 /* Table of machine attributes.  */
 static const struct attribute_spec arm_attribute_table[] =
@@ -587,8 +590,8 @@ static const struct attribute_spec arm_attribute_table[] =
 #define TARGET_ASM_EMIT_EXCEPT_PERSONALITY arm_asm_emit_except_personality
 
 #undef TARGET_ASM_INIT_SECTIONS
-#define TARGET_ASM_INIT_SECTIONS arm_asm_init_sections
 #endif /* ARM_UNWIND_INFO */
+#define TARGET_ASM_INIT_SECTIONS arm_asm_init_sections
 
 #undef TARGET_DWARF_REGISTER_SPAN
 #define TARGET_DWARF_REGISTER_SPAN arm_dwarf_register_span
@@ -729,6 +732,15 @@ static const struct attribute_spec arm_attribute_table[] =
 #undef TARGET_SCHED_FUSION_PRIORITY
 #define TARGET_SCHED_FUSION_PRIORITY arm_sched_fusion_priority
 
+#undef  TARGET_ASM_FUNCTION_SECTION
+#define TARGET_ASM_FUNCTION_SECTION arm_function_section
+
+#undef TARGET_ASM_ELF_FLAGS_NUMERIC
+#define TARGET_ASM_ELF_FLAGS_NUMERIC arm_asm_elf_flags_numeric
+
+#undef TARGET_SECTION_TYPE_FLAGS
+#define TARGET_SECTION_TYPE_FLAGS arm_elf_section_type_flags
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
 /* Obstack for minipool constant handling.  */
@@ -2815,6 +2827,17 @@ arm_option_check_internal (struct gcc_options *opts)
       && ((!(arm_arch7 && !arm_arch_notm) && !arm_arch7em)
 	  || (TARGET_THUMB1_P (flags) || flag_pic || TARGET_NEON)))
     error ("-mslow-flash-data only supports non-pic code on armv7-m targets");
+
+#ifdef OBJECT_FORMAT_ELF
+  /* We only support -mpure-code on Thumb-2 M-profile targets.  */
+  if (target_pure_code
+      && (!arm_arch_thumb2 || arm_arch_notm || flag_pic || TARGET_NEON))
+    error ("-mpure-code only supports non-pic code on armv7-m targets");
+#else
+  if (target_pure_code)
+    error ("-mpure-code is only available for the ELF object format.");
+#endif
+
 }
 
 /* Recompute the global settings depending on target attribute options.  */
@@ -3453,8 +3476,9 @@ arm_option_override (void)
 			 global_options.x_param_values,
 			 global_options_set.x_param_values);
 
-  /* Currently, for slow flash data, we just disable literal pools.  */
-  if (target_slow_flash_data)
+  /* Currently, for slow flash data, we just disable literal pools.  We also
+     disable it for -mpure-code.  */
+  if (target_slow_flash_data || target_pure_code)
     arm_disable_literal_pool = true;
 
   /* Disable scheduling fusion by default if it's not armv7 processor
@@ -27208,17 +27232,22 @@ arm_asm_emit_except_personality (rtx personality)
   output_addr_const (asm_out_file, personality);
   fputc ('\n', asm_out_file);
 }
+#endif /* ARM_UNWIND_INFO */
 
 /* Implement TARGET_ASM_INITIALIZE_SECTIONS.  */
 
 static void
 arm_asm_init_sections (void)
 {
+#if ARM_UNWIND_INFO
   exception_section = get_unnamed_section (0, output_section_asm_op,
 					   "\t.handlerdata");
-}
 #endif /* ARM_UNWIND_INFO */
 
+  if (target_pure_code)
+    text_section->unnamed.data = "\t.section .text,\"0x20000006\",%%progbits";
+}
+
 /* Output unwind directives for the start/end of a function.  */
 
 void
@@ -30529,4 +30558,113 @@ arm_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT vcall_offset,
   return true;
 }
 
+/* Implement the TARGET_ASM_ELF_FLAGS_NUMERIC hook.
+
+   For sections with SECTION_ARM_PURECODE flag set, make sure you pass the
+   machine specific flag attribute when printing the numeric value.  */
+
+static bool
+arm_asm_elf_flags_numeric (unsigned int flags, unsigned int *num)
+{
+
+  if (flags & SECTION_ARM_PURECODE)
+    {
+      *num = 0x20000000;
+
+      if (!(flags & SECTION_DEBUG))
+	*num |= 0x2;
+#if defined (HAVE_GAS_SECTION_EXCLUDE) && HAVE_GAS_SECTION_EXCLUDE == 1
+      if (flags & SECTION_EXCLUDE)
+	*num |= 0x80000000;
+#endif
+      if (flags & SECTION_WRITE)
+	*num |= 0x1;
+      if (flags & SECTION_CODE)
+	*num |= 0x4;
+      if (flags & SECTION_MERGE)
+	*num |= 0x10;
+      if (flags & SECTION_STRINGS)
+	*num |= 0x20;
+      if (flags & SECTION_TLS)
+	*num |= 0x400;
+      if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
+	*num |= 0x200;
+
+	return true;
+    }
+
+  return false;
+}
+
+/* Implement the TARGET_ASM_FUNCTION_SECTION hook.
+
+   If -mpure_code is passed as an option, make sure all functions are in
+   sections that have the SHF_ARM_PURECODE attribute.  */
+
+static section *
+arm_function_section (tree decl, enum node_frequency freq,
+		      bool startup, bool exit)
+{
+  const char * section_name;
+  section * sec;
+
+  if (!decl || TREE_CODE (decl) != FUNCTION_DECL)
+    return default_function_section (decl, freq, startup, exit);
+
+  if (!target_pure_code)
+    return default_function_section (decl, freq, startup, exit);
+
+
+  section_name = DECL_SECTION_NAME (decl);
+
+  /* If a function is not in a named section then it falls under the 'default'
+     text section, also known as '.text'. We can preserve previous behavior as
+     the default text section already has the SHF_ARM_PURECODE section
+     attribute.  */
+  if (!section_name)
+    {
+      section *default_sec = default_function_section (decl, freq, startup,
+						       exit);
+
+      /* If default_sec is not null, then it must be a special section like for
+	 example .text.startup. We set the pure-code attribute and return the
+	 same section to preserve behavior.  */
+      if (default_sec)
+	  default_sec->common.flags |= SECTION_ARM_PURECODE;
+      return default_sec;
+    }
+
+  /* Otherwise look whether a section has already been created with
+     'section_name'.  */
+  sec = get_named_section (decl, section_name, 0);
+  if (!sec)
+    /* If that is not the case passing NULL as the name section to
+       'get_named_section' will create a section with the declarations
+       section name.  */
+    sec = get_named_section (decl, NULL, 0);
+
+  /* Set the SHF_ARM_PURECODE attribute.  */
+  sec->common.flags |= SECTION_ARM_PURECODE;
+
+  return sec;
+}
+
+/* Implements the TARGET_SECTION_FLAGS hook.
+
+   If DECL is a function declaration and -mpure-code is passed as an option
+   then add the SFH_ARM_PURECODE attribute to the section flags.  NAME is the
+   sections name and RELOC indicates whether the declarations initializer may
+   contain runtime relocations.  */
+
+static unsigned int
+arm_elf_section_type_flags (tree decl, const char *name, int reloc)
+{
+  unsigned int flags = default_section_type_flags (decl, name, reloc);
+
+  if (decl && TREE_CODE (decl) == FUNCTION_DECL && target_pure_code)
+    flags |= SECTION_ARM_PURECODE;
+
+  return flags;
+}
+
 #include "gt-arm.h"
diff --git a/gcc/config/arm/arm.opt b/gcc/config/arm/arm.opt
index 0ebe0174390167b79a64583c35a3f8fb018f6538..f0827629710d0ac447df6469ea1cde1eb29c1d28 100644
--- a/gcc/config/arm/arm.opt
+++ b/gcc/config/arm/arm.opt
@@ -281,3 +281,9 @@ Assume loading data from flash is slower than fetching instructions.
 masm-syntax-unified
 Target Report Var(inline_asm_unified) Init(0) Save
 Assume unified syntax for inline assembly code.
+
+mpure-code
+Target Report Var(target_pure_code) Init(0)
+Assembly generated for functions are put into sections that only contain code.
+This requires that no literal pools or jump tables are generated for such
+functions.
diff --git a/gcc/config/arm/elf.h b/gcc/config/arm/elf.h
index 77f30554d5286bd83aeab0c8dc308cfd44e732dc..395a22282be0cd2edc9459e1ba14d7848073fa5d 100644
--- a/gcc/config/arm/elf.h
+++ b/gcc/config/arm/elf.h
@@ -104,7 +104,8 @@
    the code more efficient, but for Thumb-1 it's better to put them out of
    band unless we are generating compressed tables.  */
 #define JUMP_TABLES_IN_TEXT_SECTION					\
-   (TARGET_32BIT || (TARGET_THUMB && (optimize_size || flag_pic)))
+   ((TARGET_32BIT || (TARGET_THUMB && (optimize_size || flag_pic))) \
+    && !target_pure_code)
 
 #ifndef LINK_SPEC
 #define LINK_SPEC "%{mbig-endian:-EB} %{mlittle-endian:-EL} -X"
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 4f24daebc01f0fd006540df8d863014aa864d060..98f6dd01a941f91243b2ab5846b8df0b086f26e6 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -639,7 +639,8 @@ Objective-C and Objective-C++ Dialects}.
 -mneon-for-64bits @gol
 -mslow-flash-data @gol
 -masm-syntax-unified @gol
--mrestrict-it}
+-mrestrict-it @gol
+-mpure-code}
 
 @emph{AVR Options}
 @gccoptlist{-mmcu=@var{mcu} -maccumulate-args -mbranch-cost=@var{cost} @gol
@@ -14498,6 +14499,14 @@ Print CPU tuning information as comment in assembler file.  This is
 an option used only for regression testing of the compiler and not
 intended for ordinary use in compiling code.  This option is disabled
 by default.
+
+@item -mpure-code
+@opindex mpure-code
+GCC will generate assembly where instructions and data are in separate sections.
+It also gives all text sections the ELF processor-specific section attribute
+SHF_ARM_PURECODE.  This option is only available for ELF targets in thumb mode
+that support Thumb2.
+
 @end table
 
 @node AVR Options
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index b318615b7b35ab93ad13e5e535a1d4e6d02cb7f7..23225fd99c7ddfbbcafccf352aba851376d2731f 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -7543,6 +7543,12 @@ is non-NULL, it is the @code{VAR_DECL} or @code{FUNCTION_DECL} with which
 this section is associated.
 @end deftypefn
 
+@deftypefn {Target Hook} bool TARGET_ASM_ELF_FLAGS_NUMERIC (unsigned int @var{flags}, unsigned int *@var{num})
+If this function returns true, it will pass the section attributes using
+their numeric value in @var{num} based on the bits set in @var{flags}.  This
+function is called by @code{default_elf_asm_named_section}.
+@end deftypefn
+
 @deftypefn {Target Hook} {section *} TARGET_ASM_FUNCTION_SECTION (tree @var{decl}, enum node_frequency @var{freq}, bool @var{startup}, bool @var{exit})
 Return preferred text (sub)section for function @var{decl}.
 Main purpose of this function is to separate cold, normal and hot
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 1e8423cb4e255acd8144e4b105186cee3d1d04fd..17a2ca73f07516526543253c77c088c73326af2c 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -5229,6 +5229,8 @@ of the filename using this macro.
 
 @hook TARGET_ASM_NAMED_SECTION
 
+@hook TARGET_ASM_ELF_FLAGS_NUMERIC
+
 @hook TARGET_ASM_FUNCTION_SECTION
 
 @hook TARGET_ASM_FUNCTION_SWITCHED_TEXT_SECTIONS
diff --git a/gcc/target.def b/gcc/target.def
index a4df363698ce776b51d11c187baed2069ba88a52..514db908d33b6ae77b33772e1d92fc25dc760c92 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -432,6 +432,16 @@ this section is associated.",
  void, (const char *name, unsigned int flags, tree decl),
  default_no_named_section)
 
+/* Tell assembler what section attributes to assign this elf section
+   declaration, using their numerical value.  */
+DEFHOOK
+(elf_flags_numeric,
+ "If this function returns true, it will pass the section attributes using\n\
+their numeric value in @var{num} based on the bits set in @var{flags}.  This\n\
+function is called by @code{default_elf_asm_named_section}.",
+ bool, (unsigned int flags, unsigned int *num),
+ default_asm_elf_flags_numeric)
+
 /* Return preferred text (sub)section for function DECL.
    Main purpose of this function is to separate cold, normal and hot
    functions. STARTUP is true when function is known to be used only 
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index d6581cfab893e0da619c6bc0f98ff722a7ab4404..333f60f63c3222cadc8c6264b2caa1de21c3deb8 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -254,5 +254,7 @@ extern void default_setup_incoming_vararg_bounds (cumulative_args_t ca ATTRIBUTE
 						  int second_time ATTRIBUTE_UNUSED);
 extern bool default_optab_supported_p (int, machine_mode, machine_mode,
 				       optimization_type);
+extern bool default_asm_elf_flags_numeric (unsigned int flags,
+					   unsigned int *num);
 
 #endif /* GCC_TARGHOOKS_H */
diff --git a/gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c b/gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c
new file mode 100644
index 0000000000000000000000000000000000000000..26fe38c05295b70ccc35ed900d41b34aae2c87a8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-fpic" "-fPIC" } { "" } } */
+/* { dg-options "-ffunction-sections -mpure-code" } */
+#include <limits.h>
+
+char * foo (void)
+{
+  return "foo";
+}
+
+unsigned int bar (unsigned int b)
+{
+  return UINT_MAX - b;
+}
+
+/* { dg-final { scan-assembler {\.section\t\.text\.foo[^\n]*\"0x20000006\"} } } */
+/* { dg-final { scan-assembler {\.section\t\.text\.bar[^\n]*\"0x20000006\"} } } */
diff --git a/gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c b/gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c
new file mode 100644
index 0000000000000000000000000000000000000000..9f2e4ce7cff249f6f83e47bf65ae79e270bb8f74
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c
@@ -0,0 +1,73 @@
+/* The option -mslow-flash-data is just for performance tuning, it
+   doesn't totally disable the use of literal pools.  But for below
+   simple cases, the use of literal pool should be replaced by
+   movw/movt or read-only constant pool.  */
+
+/* { dg-do compile } */
+/* { dg-options "-mpure-code" } */
+/* { dg-skip-if "" { *-*-* } { "-g" "-fpic" "-fPIC" } { "" } } */
+
+float sf;
+double df;
+long long l;
+static char *p = "Hello World";
+
+float
+testsf (float *p)
+{
+  if (*p > 1.1234f)
+    return 2.1234f;
+  else
+    return 3.1234f;
+}
+
+double
+testdf (double *p)
+{
+  if (*p > 4.1234)
+    return 2.1234;
+  else
+    return 3.1234;
+}
+
+long long
+testll (long long *p)
+{
+  if (*p > 0x123456789ABCDEFll)
+    return 0x111111111ll;
+  else
+    return 0x222222222ll;
+}
+
+char *
+testchar ()
+{
+  return p + 4;
+}
+
+int
+foo (int a, int b)
+{
+  int i;
+  volatile int *labelref = &&label1;
+
+  if (a > b)
+    {
+      while (i < b)
+	{
+	  a += *labelref;
+	  i += 1;
+	}
+      goto *labelref;
+    }
+  else
+    b = b + 3;
+
+  a = a * b;
+
+label1:
+  return a + b;
+}
+
+/* { dg-final { scan-assembler-not "\\.(float|l\\?double|\d?byte|short|int|long|quad|word)\\s+\[^.\]" } } */
+/* { dg-final { scan-assembler "text,\"0x20000006\"" } } */
diff --git a/gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp b/gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp
new file mode 100644
index 0000000000000000000000000000000000000000..1abe7782c0e5dbb6e2deef25f4bea9415664f942
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp
@@ -0,0 +1,54 @@
+#   Copyright (C) 1997-2016 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
+# <http://www.gnu.org/licenses/>.
+
+# GCC testsuite for ARM's -mpure-code option, using the `dg.exp' driver.
+
+# 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"
+}
+
+# The -mpure-code option is only available for M-profile targets that support
+# thumb2.
+if {[check_effective_target_arm_thumb2_ok]
+    && ![check_effective_target_arm_arm_ok]} then {
+# Initialize `dg'.
+dg-init
+
+set saved-dg-do-what-default ${dg-do-what-default}
+set dg-do-what-default "assemble"
+
+set saved-lto_torture_options ${LTO_TORTURE_OPTIONS}
+
+# Add -ffat-lto-objects option to all LTO options such that we can do assembly
+# scans.
+proc add_fat_objects { list } {
+    set res {}
+    foreach el $list {set res [lappend res [concat $el " -ffat-lto-objects"]]}
+    return $res
+};
+set LTO_TORTURE_OPTIONS [add_fat_objects ${LTO_TORTURE_OPTIONS}]
+
+gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] \
+	"" $DEFAULT_CFLAGS
+
+# All done.
+dg-finish
+}
diff --git a/gcc/varasm.c b/gcc/varasm.c
index de8bcd6f20c823acd03991f813da3521b80547ff..4ee2b30a7d4141c346475eac68c10e815882c64e 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6239,11 +6239,19 @@ default_no_named_section (const char *name ATTRIBUTE_UNUSED,
 #define TLS_SECTION_ASM_FLAG 'T'
 #endif
 
+bool
+default_asm_elf_flags_numeric (unsigned int /* flags */,
+			       unsigned int * /* num */)
+{
+  return false;
+}
+
 void
 default_elf_asm_named_section (const char *name, unsigned int flags,
 			       tree decl)
 {
   char flagchars[11], *f = flagchars;
+  unsigned int numeric_value;
 
   /* If we have already declared this section, we can use an
      abbreviated form to switch back to it -- unless this section is
@@ -6256,31 +6264,38 @@ default_elf_asm_named_section (const char *name, unsigned int flags,
       return;
     }
 
-  if (!(flags & SECTION_DEBUG))
-    *f++ = 'a';
+  /* If we have a machine specific flag, then use the numeric value to pass
+     this on to GAS.  */
+  if (targetm.asm_out.elf_flags_numeric (flags, &numeric_value))
+      snprintf (f, sizeof (flagchars), "0x%08x", numeric_value);
+  else
+    {
+      if (!(flags & SECTION_DEBUG))
+	*f++ = 'a';
 #if defined (HAVE_GAS_SECTION_EXCLUDE) && HAVE_GAS_SECTION_EXCLUDE == 1
-  if (flags & SECTION_EXCLUDE)
-    *f++ = 'e';
+      if (flags & SECTION_EXCLUDE)
+	*f++ = 'e';
 #endif
-  if (flags & SECTION_WRITE)
-    *f++ = 'w';
-  if (flags & SECTION_CODE)
-    *f++ = 'x';
-  if (flags & SECTION_SMALL)
-    *f++ = 's';
-  if (flags & SECTION_MERGE)
-    *f++ = 'M';
-  if (flags & SECTION_STRINGS)
-    *f++ = 'S';
-  if (flags & SECTION_TLS)
-    *f++ = TLS_SECTION_ASM_FLAG;
-  if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
-    *f++ = 'G';
+      if (flags & SECTION_WRITE)
+	*f++ = 'w';
+      if (flags & SECTION_CODE)
+	*f++ = 'x';
+      if (flags & SECTION_SMALL)
+	*f++ = 's';
+      if (flags & SECTION_MERGE)
+	*f++ = 'M';
+      if (flags & SECTION_STRINGS)
+	*f++ = 'S';
+      if (flags & SECTION_TLS)
+	*f++ = TLS_SECTION_ASM_FLAG;
+      if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
+	*f++ = 'G';
 #ifdef MACH_DEP_SECTION_ASM_FLAG
-  if (flags & SECTION_MACH_DEP)
-    *f++ = MACH_DEP_SECTION_ASM_FLAG;
+      if (flags & SECTION_MACH_DEP)
+	*f++ = MACH_DEP_SECTION_ASM_FLAG;
 #endif
-  *f = '\0';
+      *f = '\0';
+    }
 
   fprintf (asm_out_file, "\t.section\t%s,\"%s\"", name, flagchars);
 
-- 
1.9.1


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH][ARM] -mpure-code option for ARM
  2016-06-30 14:46 [PATCH][ARM] -mpure-code option for ARM Andre Vieira (lists)
@ 2016-07-01 19:04 ` Sandra Loosemore
  2016-07-07 12:29 ` mickael guene
  2016-07-07 12:31 ` mickael guene
  2 siblings, 0 replies; 24+ messages in thread
From: Sandra Loosemore @ 2016-07-01 19:04 UTC (permalink / raw)
  To: Andre Vieira (lists), GCC Patches

On 06/30/2016 08:32 AM, Andre Vieira (lists) wrote:

> @@ -14498,6 +14499,14 @@ Print CPU tuning information as comment in assembler file.  This is
>  an option used only for regression testing of the compiler and not
>  intended for ordinary use in compiling code.  This option is disabled
>  by default.
> +
> +@item -mpure-code
> +@opindex mpure-code
> +GCC will generate assembly where instructions and data are in separate sections.

s/will generate/generates/

> +It also gives all text sections the ELF processor-specific section attribute
> +SHF_ARM_PURECODE.  This option is only available for ELF targets in thumb mode
> +that support Thumb2.

The proper spellings are "Thumb" and "Thumb-2", but wouldn't it be more 
clear just to say  "This option is only available when generating 
Thumb-2 code for ELF targets." ??

> diff --git a/gcc/target.def b/gcc/target.def
> index a4df363698ce776b51d11c187baed2069ba88a52..514db908d33b6ae77b33772e1d92fc25dc760c92 100644
> --- a/gcc/target.def
> +++ b/gcc/target.def
> @@ -432,6 +432,16 @@ this section is associated.",
>   void, (const char *name, unsigned int flags, tree decl),
>   default_no_named_section)
>
> +/* Tell assembler what section attributes to assign this elf section
> +   declaration, using their numerical value.  */
> +DEFHOOK
> +(elf_flags_numeric,
> + "If this function returns true, it will pass the section attributes using\n\
> +their numeric value in @var{num} based on the bits set in @var{flags}.  This\n\
> +function is called by @code{default_elf_asm_named_section}.",
> + bool, (unsigned int flags, unsigned int *num),
> + default_asm_elf_flags_numeric)
> +

I don't understand "will pass" means in this context, even with the 
additional description you included in your patch e-mail.  I think it 
would be more helpful to communicate the purpose of this hook if you 
could rethink this as "If the target needs to <do X>, this hook should 
be implemented to <do y>."  And again, please document current behavior 
in the present tense, not the future tense.

-Sandra

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH][ARM] -mpure-code option for ARM
  2016-06-30 14:46 [PATCH][ARM] -mpure-code option for ARM Andre Vieira (lists)
  2016-07-01 19:04 ` Sandra Loosemore
@ 2016-07-07 12:29 ` mickael guene
  2016-07-07 12:31 ` mickael guene
  2 siblings, 0 replies; 24+ messages in thread
From: mickael guene @ 2016-07-07 12:29 UTC (permalink / raw)
  To: Andre Vieira (lists), GCC Patches

Hi Andre,

  I think you have a typo in your patch. I need to change :
+    text_section->unnamed.data = "\t.section 
.text,\"0x20000006\",%%progbits";

into
+    text_section->unnamed.data = "\t.section 
.text,\"0x20000006\",%progbits";

to make it works.

Regards
Mickael

On 06/30/2016 04:32 PM, Andre Vieira (lists) wrote:
> Hello,
>
> This patch adds the -mpure-code option for ARM. This option ensures
> functions are put into sections that contain only code and no data. To
> ensure this throughout compilation we give these sections the ARM
> processor-specific ELF section attribute "SHF_ARM_PURECODE". This option
> is only supported for non-pic code for armv7-m targets.
>
> This patch introduces a new target hook 'TARGET_ASM_ELF_FLAGS_NUMERIC'.
> This target hook enables a target to use the numeric value for elf
> section attributes rather than their alphabetical representation. If
> TARGET_ASM_ELF_FLAGS_NUMERIC returns TRUE, the existing
> 'default_elf_asm_named_section', will print the numeric value of the
> section attributes for the current section. This target hook has two
> parameters:
> unsigned int FLAGS, the input parameter that tells the function the
> current section's attributes;
> unsigned int *NUM, used to pass down the numerical representation of the
> section's attributes.
>
> The default implementation for TARGET_ASM_ELF_FLAGS_NUMERIC will return
> false, so existing behavior is not changed.
>
> Bootstrapped and tested for arm-none-linux-gnueabihf. Further tested for
> arm-none-eabi with a Cortex-M3 target.
>
>
> gcc/ChangeLog:
> 2016-06-30  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>             Terry Guo  <terry.guo@arm.com>
>
>         * target.def (elf_flags_numeric): New target hook.
>         * targhooks.h (default_asm_elf_flags_numeric): New.
>         * varasm.c (default_asm_elf_flags_numeric): New.
>           (default_elf_asm_named_section): Use new target hook.
>         * config/arm/arm.opt (mpure-code): New.
>         * config/arm/arm.h (SECTION_ARM_PURECODE): New.
>         * config/arm/arm.c (arm_asm_init_sections): Add section
>           attribute to default text section if -mpure-code.
>           (arm_option_check_internal): Diagnose use of option with
>           non supported targets and/or options.
>           (arm_asm_elf_flags_numeric): New.
>           (arm_function_section): New.
>           (arm_elf_section_type_flags): New.
>         * config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Disable
>           for -mpure-code.
>         * gcc/doc/texi (TARGET_ASM_ELF_FLAGS_NUMERIC): New.
>         * gcc/doc/texi.in (TARGET_ASM_ELF_FLAGS_NUMERIC): Likewise.
>
>
>
> gcc/testsuite/ChangeLog:
> 2016-06-30  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>             Terry Guo  <terry.guo@arm.com>
>
>         * gcc.target/arm/pure-code/ffunction-sections.c: New.
>         * gcc.target/arm/pure-code/no-literal-pool.c: New.
>         * gcc.target/arm/pure-code/pure-code.exp: New.
>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH][ARM] -mpure-code option for ARM
  2016-06-30 14:46 [PATCH][ARM] -mpure-code option for ARM Andre Vieira (lists)
  2016-07-01 19:04 ` Sandra Loosemore
  2016-07-07 12:29 ` mickael guene
@ 2016-07-07 12:31 ` mickael guene
  2016-07-11 16:57   ` [PATCHv2][ARM] " Andre Vieira (lists)
  2 siblings, 1 reply; 24+ messages in thread
From: mickael guene @ 2016-07-07 12:31 UTC (permalink / raw)
  To: Andre Vieira (lists), GCC Patches

Hi Andre,

  Another feedback on your purecode patch.
  You have to disable casesi pattern since then it will
generate wrong code with -mpure-code option.
  Indeed it will generate an 'adr rx, .Lx' (aka
'subs rx, PC, #offset') which will not work in our
case since 'Lx' label is put in an .rodata section.
So offset value is unknown and can be impossible
to encode correctly.

Regards
Mickael

On 06/30/2016 04:32 PM, Andre Vieira (lists) wrote:
> Hello,
>
> This patch adds the -mpure-code option for ARM. This option ensures
> functions are put into sections that contain only code and no data. To
> ensure this throughout compilation we give these sections the ARM
> processor-specific ELF section attribute "SHF_ARM_PURECODE". This option
> is only supported for non-pic code for armv7-m targets.
>
> This patch introduces a new target hook 'TARGET_ASM_ELF_FLAGS_NUMERIC'.
> This target hook enables a target to use the numeric value for elf
> section attributes rather than their alphabetical representation. If
> TARGET_ASM_ELF_FLAGS_NUMERIC returns TRUE, the existing
> 'default_elf_asm_named_section', will print the numeric value of the
> section attributes for the current section. This target hook has two
> parameters:
> unsigned int FLAGS, the input parameter that tells the function the
> current section's attributes;
> unsigned int *NUM, used to pass down the numerical representation of the
> section's attributes.
>
> The default implementation for TARGET_ASM_ELF_FLAGS_NUMERIC will return
> false, so existing behavior is not changed.
>
> Bootstrapped and tested for arm-none-linux-gnueabihf. Further tested for
> arm-none-eabi with a Cortex-M3 target.
>
>
> gcc/ChangeLog:
> 2016-06-30  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>             Terry Guo  <terry.guo@arm.com>
>
>         * target.def (elf_flags_numeric): New target hook.
>         * targhooks.h (default_asm_elf_flags_numeric): New.
>         * varasm.c (default_asm_elf_flags_numeric): New.
>           (default_elf_asm_named_section): Use new target hook.
>         * config/arm/arm.opt (mpure-code): New.
>         * config/arm/arm.h (SECTION_ARM_PURECODE): New.
>         * config/arm/arm.c (arm_asm_init_sections): Add section
>           attribute to default text section if -mpure-code.
>           (arm_option_check_internal): Diagnose use of option with
>           non supported targets and/or options.
>           (arm_asm_elf_flags_numeric): New.
>           (arm_function_section): New.
>           (arm_elf_section_type_flags): New.
>         * config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Disable
>           for -mpure-code.
>         * gcc/doc/texi (TARGET_ASM_ELF_FLAGS_NUMERIC): New.
>         * gcc/doc/texi.in (TARGET_ASM_ELF_FLAGS_NUMERIC): Likewise.
>
>
>
> gcc/testsuite/ChangeLog:
> 2016-06-30  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>             Terry Guo  <terry.guo@arm.com>
>
>         * gcc.target/arm/pure-code/ffunction-sections.c: New.
>         * gcc.target/arm/pure-code/no-literal-pool.c: New.
>         * gcc.target/arm/pure-code/pure-code.exp: New.
>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCHv2][ARM] -mpure-code option for ARM
  2016-07-07 12:31 ` mickael guene
@ 2016-07-11 16:57   ` Andre Vieira (lists)
  2016-07-25 10:52     ` [PATCHv2, PING][ARM] " Andre Vieira (lists)
  2016-09-22 14:22     ` [PATCHv2][ARM] " Richard Earnshaw (lists)
  0 siblings, 2 replies; 24+ messages in thread
From: Andre Vieira (lists) @ 2016-07-11 16:57 UTC (permalink / raw)
  To: GCC Patches; +Cc: mickael guene, sandra

[-- Attachment #1: Type: text/plain, Size: 5302 bytes --]

On 07/07/16 13:30, mickael guene wrote:
> Hi Andre,
> 
>  Another feedback on your purecode patch.
>  You have to disable casesi pattern since then it will
> generate wrong code with -mpure-code option.
>  Indeed it will generate an 'adr rx, .Lx' (aka
> 'subs rx, PC, #offset') which will not work in our
> case since 'Lx' label is put in an .rodata section.
> So offset value is unknown and can be impossible
> to encode correctly.
> 
> Regards
> Mickael
> 
> On 06/30/2016 04:32 PM, Andre Vieira (lists) wrote:
>> Hello,
>>
>> This patch adds the -mpure-code option for ARM. This option ensures
>> functions are put into sections that contain only code and no data. To
>> ensure this throughout compilation we give these sections the ARM
>> processor-specific ELF section attribute "SHF_ARM_PURECODE". This option
>> is only supported for non-pic code for armv7-m targets.
>>
>> This patch introduces a new target hook 'TARGET_ASM_ELF_FLAGS_NUMERIC'.
>> This target hook enables a target to use the numeric value for elf
>> section attributes rather than their alphabetical representation. If
>> TARGET_ASM_ELF_FLAGS_NUMERIC returns TRUE, the existing
>> 'default_elf_asm_named_section', will print the numeric value of the
>> section attributes for the current section. This target hook has two
>> parameters:
>> unsigned int FLAGS, the input parameter that tells the function the
>> current section's attributes;
>> unsigned int *NUM, used to pass down the numerical representation of the
>> section's attributes.
>>
>> The default implementation for TARGET_ASM_ELF_FLAGS_NUMERIC will return
>> false, so existing behavior is not changed.
>>
>> Bootstrapped and tested for arm-none-linux-gnueabihf. Further tested for
>> arm-none-eabi with a Cortex-M3 target.
>>
>>
>> gcc/ChangeLog:
>> 2016-06-30  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>             Terry Guo  <terry.guo@arm.com>
>>
>>         * target.def (elf_flags_numeric): New target hook.
>>         * targhooks.h (default_asm_elf_flags_numeric): New.
>>         * varasm.c (default_asm_elf_flags_numeric): New.
>>           (default_elf_asm_named_section): Use new target hook.
>>         * config/arm/arm.opt (mpure-code): New.
>>         * config/arm/arm.h (SECTION_ARM_PURECODE): New.
>>         * config/arm/arm.c (arm_asm_init_sections): Add section
>>           attribute to default text section if -mpure-code.
>>           (arm_option_check_internal): Diagnose use of option with
>>           non supported targets and/or options.
>>           (arm_asm_elf_flags_numeric): New.
>>           (arm_function_section): New.
>>           (arm_elf_section_type_flags): New.
>>         * config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Disable
>>           for -mpure-code.
>>         * gcc/doc/texi (TARGET_ASM_ELF_FLAGS_NUMERIC): New.
>>         * gcc/doc/texi.in (TARGET_ASM_ELF_FLAGS_NUMERIC): Likewise.
>>
>>
>>
>> gcc/testsuite/ChangeLog:
>> 2016-06-30  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>             Terry Guo  <terry.guo@arm.com>
>>
>>         * gcc.target/arm/pure-code/ffunction-sections.c: New.
>>         * gcc.target/arm/pure-code/no-literal-pool.c: New.
>>         * gcc.target/arm/pure-code/pure-code.exp: New.
>>
> 
Hi Sandra, Mickael,

Thank you for your comments. I changed the description of -mpure-code in
invoke.texi to better reflect the error message you get wrt supported
targets.

As for the target hook description, I hope the text is clearer now. Let
me know if you think it needs further explanation.

I also fixed the double '%' in the text string for unnamed text sections
and disabled the casesi pattern.

I duplicated the original casesi test
'gcc/testsuite/gcc.c-torture/compile/pr46934.c' for pure-code to make
sure the casesi was disabled and other patterns were selected instead.

Reran regressions for pure-code.exp for Cortex-M3.

Cheers,
Andre


gcc/ChangeLog:
2016-07-11  Andre Vieira  <andre.simoesdiasvieira@arm.com>
            Terry Guo  <terry.guo@arm.com>

        * target.def (elf_flags_numeric): New target hook.
        * hooks.c (hook_uint_uintp_false): New generic hook.
        * varasm.c (default_elf_asm_named_section): Use new target hook.
        * config/arm/arm.opt (mpure-code): New.
        * config/arm/arm.h (SECTION_ARM_PURECODE): New.
        * config/arm/arm.c (arm_asm_init_sections): Add section
        attribute to default text section if -mpure-code.
        (arm_option_check_internal): Diagnose use of option with
        non supported targets and/or options.
        (arm_asm_elf_flags_numeric): New.
        (arm_function_section): New.
        (arm_elf_section_type_flags): New.
        * config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Disable
        for -mpure-code.
        * config/arm/arm.md (casesi): Disable pattern for
        -mpure-code.
        * gcc/doc/texi (TARGET_ASM_ELF_FLAGS_NUMERIC): New.
        * gcc/doc/texi.in (TARGET_ASM_ELF_FLAGS_NUMERIC): Likewise.



gcc/testsuite/ChangeLog:
2016-07-11  Andre Vieira  <andre.simoesdiasvieira@arm.com>
            Terry Guo  <terry.guo@arm.com>

        * gcc.target/arm/pure-code/ffunction-sections.c: New.
        * gcc.target/arm/pure-code/no-literal-pool.c: New.
        * gcc.target/arm/pure-code/no-casesi.c: New.
        * gcc.target/arm/pure-code/pure-code.exp: New.

[-- Attachment #2: 0001-mpure-code-for-ARM.patch --]
[-- Type: text/x-patch, Size: 23823 bytes --]

diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index f0cdd669191689bc5dcf3a7c2b60da5a2d201e3f..d10605cee0e6e0e07bbb4e1910d30c91443f8d17 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -2263,4 +2263,8 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
 /* For switching between functions with different target attributes.  */
 #define SWITCHABLE_TARGET 1
 
+/* Define SECTION_ARM_PURECODE as the ARM specific section attribute
+   representation for SHF_ARM_PURECODE in GCC.  */
+#define SECTION_ARM_PURECODE SECTION_MACH_DEP
+
 #endif /* ! GCC_ARM_H */
From b35a27e363a6123c6c50bd29e284c89f6ae434a5 Mon Sep 17 00:00:00 2001
From: Andre Simoes Dias Vieira <andsim01@arm.com>
Date: Tue, 14 Jun 2016 11:17:12 +0100
Subject: [PATCH] -mpure-code for ARM

---
 gcc/config/arm/arm.c                               | 150 ++++++++++++++++++++-
 gcc/config/arm/arm.h                               |   4 +
 gcc/config/arm/arm.md                              |   2 +-
 gcc/config/arm/arm.opt                             |   6 +
 gcc/config/arm/elf.h                               |   3 +-
 gcc/doc/invoke.texi                                |  11 +-
 gcc/doc/tm.texi                                    |   9 ++
 gcc/doc/tm.texi.in                                 |   2 +
 gcc/hooks.c                                        |  10 ++
 gcc/target.def                                     |  13 ++
 gcc/targhooks.h                                    |   1 -
 .../gcc.target/arm/pure-code/ffunction-sections.c  |  17 +++
 gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c |  29 ++++
 .../gcc.target/arm/pure-code/no-literal-pool.c     |  68 ++++++++++
 .../gcc.target/arm/pure-code/pure-code.exp         |  54 ++++++++
 gcc/varasm.c                                       |  50 ++++---
 16 files changed, 398 insertions(+), 31 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c
 create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c
 create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c
 create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index f60955438d6f1cc5d996e7eacd4b453213044181..9b5013a069235d18eebc10a312e364de9f756906 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -214,8 +214,8 @@ static bool arm_return_in_memory (const_tree, const_tree);
 static void arm_unwind_emit (FILE *, rtx_insn *);
 static bool arm_output_ttype (rtx);
 static void arm_asm_emit_except_personality (rtx);
-static void arm_asm_init_sections (void);
 #endif
+static void arm_asm_init_sections (void);
 static rtx arm_dwarf_register_span (rtx);
 
 static tree arm_cxx_guard_type (void);
@@ -299,7 +299,10 @@ static unsigned HOST_WIDE_INT arm_asan_shadow_offset (void);
 static void arm_sched_fusion_priority (rtx_insn *, int, int *, int*);
 static bool arm_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT,
 				     const_tree);
-
+static section *arm_function_section (tree, enum node_frequency, bool, bool);
+static bool arm_asm_elf_flags_numeric (unsigned int flags, unsigned int *num);
+static unsigned int arm_elf_section_type_flags (tree decl, const char *name,
+						int reloc);
 \f
 /* Table of machine attributes.  */
 static const struct attribute_spec arm_attribute_table[] =
@@ -587,8 +590,8 @@ static const struct attribute_spec arm_attribute_table[] =
 #define TARGET_ASM_EMIT_EXCEPT_PERSONALITY arm_asm_emit_except_personality
 
 #undef TARGET_ASM_INIT_SECTIONS
-#define TARGET_ASM_INIT_SECTIONS arm_asm_init_sections
 #endif /* ARM_UNWIND_INFO */
+#define TARGET_ASM_INIT_SECTIONS arm_asm_init_sections
 
 #undef TARGET_DWARF_REGISTER_SPAN
 #define TARGET_DWARF_REGISTER_SPAN arm_dwarf_register_span
@@ -729,6 +732,15 @@ static const struct attribute_spec arm_attribute_table[] =
 #undef TARGET_SCHED_FUSION_PRIORITY
 #define TARGET_SCHED_FUSION_PRIORITY arm_sched_fusion_priority
 
+#undef  TARGET_ASM_FUNCTION_SECTION
+#define TARGET_ASM_FUNCTION_SECTION arm_function_section
+
+#undef TARGET_ASM_ELF_FLAGS_NUMERIC
+#define TARGET_ASM_ELF_FLAGS_NUMERIC arm_asm_elf_flags_numeric
+
+#undef TARGET_SECTION_TYPE_FLAGS
+#define TARGET_SECTION_TYPE_FLAGS arm_elf_section_type_flags
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
 /* Obstack for minipool constant handling.  */
@@ -2815,6 +2827,17 @@ arm_option_check_internal (struct gcc_options *opts)
       && ((!(arm_arch7 && !arm_arch_notm) && !arm_arch7em)
 	  || (TARGET_THUMB1_P (flags) || flag_pic || TARGET_NEON)))
     error ("-mslow-flash-data only supports non-pic code on armv7-m targets");
+
+#ifdef OBJECT_FORMAT_ELF
+  /* We only support -mpure-code on Thumb-2 M-profile targets.  */
+  if (target_pure_code
+      && (!arm_arch_thumb2 || arm_arch_notm || flag_pic || TARGET_NEON))
+    error ("-mpure-code only supports non-pic code on armv7-m targets");
+#else
+  if (target_pure_code)
+    error ("-mpure-code is only available for the ELF object format.");
+#endif
+
 }
 
 /* Recompute the global settings depending on target attribute options.  */
@@ -3453,8 +3476,9 @@ arm_option_override (void)
 			 global_options.x_param_values,
 			 global_options_set.x_param_values);
 
-  /* Currently, for slow flash data, we just disable literal pools.  */
-  if (target_slow_flash_data)
+  /* Currently, for slow flash data, we just disable literal pools.  We also
+     disable it for -mpure-code.  */
+  if (target_slow_flash_data || target_pure_code)
     arm_disable_literal_pool = true;
 
   /* Disable scheduling fusion by default if it's not armv7 processor
@@ -27208,17 +27232,22 @@ arm_asm_emit_except_personality (rtx personality)
   output_addr_const (asm_out_file, personality);
   fputc ('\n', asm_out_file);
 }
+#endif /* ARM_UNWIND_INFO */
 
 /* Implement TARGET_ASM_INITIALIZE_SECTIONS.  */
 
 static void
 arm_asm_init_sections (void)
 {
+#if ARM_UNWIND_INFO
   exception_section = get_unnamed_section (0, output_section_asm_op,
 					   "\t.handlerdata");
-}
 #endif /* ARM_UNWIND_INFO */
 
+  if (target_pure_code)
+    text_section->unnamed.data = "\t.section .text,\"0x20000006\",%progbits";
+}
+
 /* Output unwind directives for the start/end of a function.  */
 
 void
@@ -30529,4 +30558,113 @@ arm_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT vcall_offset,
   return true;
 }
 
+/* Implement the TARGET_ASM_ELF_FLAGS_NUMERIC hook.
+
+   For sections with SECTION_ARM_PURECODE flag set, make sure you pass the
+   machine specific flag attribute when printing the numeric value.  */
+
+static bool
+arm_asm_elf_flags_numeric (unsigned int flags, unsigned int *num)
+{
+
+  if (flags & SECTION_ARM_PURECODE)
+    {
+      *num = 0x20000000;
+
+      if (!(flags & SECTION_DEBUG))
+	*num |= 0x2;
+#if defined (HAVE_GAS_SECTION_EXCLUDE) && HAVE_GAS_SECTION_EXCLUDE == 1
+      if (flags & SECTION_EXCLUDE)
+	*num |= 0x80000000;
+#endif
+      if (flags & SECTION_WRITE)
+	*num |= 0x1;
+      if (flags & SECTION_CODE)
+	*num |= 0x4;
+      if (flags & SECTION_MERGE)
+	*num |= 0x10;
+      if (flags & SECTION_STRINGS)
+	*num |= 0x20;
+      if (flags & SECTION_TLS)
+	*num |= 0x400;
+      if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
+	*num |= 0x200;
+
+	return true;
+    }
+
+  return false;
+}
+
+/* Implement the TARGET_ASM_FUNCTION_SECTION hook.
+
+   If -mpure_code is passed as an option, make sure all functions are in
+   sections that have the SHF_ARM_PURECODE attribute.  */
+
+static section *
+arm_function_section (tree decl, enum node_frequency freq,
+		      bool startup, bool exit)
+{
+  const char * section_name;
+  section * sec;
+
+  if (!decl || TREE_CODE (decl) != FUNCTION_DECL)
+    return default_function_section (decl, freq, startup, exit);
+
+  if (!target_pure_code)
+    return default_function_section (decl, freq, startup, exit);
+
+
+  section_name = DECL_SECTION_NAME (decl);
+
+  /* If a function is not in a named section then it falls under the 'default'
+     text section, also known as '.text'. We can preserve previous behavior as
+     the default text section already has the SHF_ARM_PURECODE section
+     attribute.  */
+  if (!section_name)
+    {
+      section *default_sec = default_function_section (decl, freq, startup,
+						       exit);
+
+      /* If default_sec is not null, then it must be a special section like for
+	 example .text.startup. We set the pure-code attribute and return the
+	 same section to preserve behavior.  */
+      if (default_sec)
+	  default_sec->common.flags |= SECTION_ARM_PURECODE;
+      return default_sec;
+    }
+
+  /* Otherwise look whether a section has already been created with
+     'section_name'.  */
+  sec = get_named_section (decl, section_name, 0);
+  if (!sec)
+    /* If that is not the case passing NULL as the name section to
+       'get_named_section' will create a section with the declarations
+       section name.  */
+    sec = get_named_section (decl, NULL, 0);
+
+  /* Set the SHF_ARM_PURECODE attribute.  */
+  sec->common.flags |= SECTION_ARM_PURECODE;
+
+  return sec;
+}
+
+/* Implements the TARGET_SECTION_FLAGS hook.
+
+   If DECL is a function declaration and -mpure-code is passed as an option
+   then add the SFH_ARM_PURECODE attribute to the section flags.  NAME is the
+   sections name and RELOC indicates whether the declarations initializer may
+   contain runtime relocations.  */
+
+static unsigned int
+arm_elf_section_type_flags (tree decl, const char *name, int reloc)
+{
+  unsigned int flags = default_section_type_flags (decl, name, reloc);
+
+  if (decl && TREE_CODE (decl) == FUNCTION_DECL && target_pure_code)
+    flags |= SECTION_ARM_PURECODE;
+
+  return flags;
+}
+
 #include "gt-arm.h"
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 16498316bee9f19baff414885efe1e78191da047..9f49ab6014e61e7b49972f29c96ad03c11101aa1 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -8180,7 +8180,7 @@
    (match_operand:SI 2 "const_int_operand" "")	; total range
    (match_operand:SI 3 "" "")			; table label
    (match_operand:SI 4 "" "")]			; Out of range label
-  "TARGET_32BIT || optimize_size || flag_pic"
+  "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
   "
   {
     enum insn_code code;
diff --git a/gcc/config/arm/arm.opt b/gcc/config/arm/arm.opt
index 0ebe0174390167b79a64583c35a3f8fb018f6538..6c142d9fc6bee9d5ec30f7a25bd017e8bc02b801 100644
--- a/gcc/config/arm/arm.opt
+++ b/gcc/config/arm/arm.opt
@@ -281,3 +281,9 @@ Assume loading data from flash is slower than fetching instructions.
 masm-syntax-unified
 Target Report Var(inline_asm_unified) Init(0) Save
 Assume unified syntax for inline assembly code.
+
+mpure-code
+Target Report Var(target_pure_code) Init(0)
+Generate assembly which places functions in sections that contain only code.
+This requires that no literal pools are generated for such
+functions and that jump tables are not put in the same section.
diff --git a/gcc/config/arm/elf.h b/gcc/config/arm/elf.h
index 77f30554d5286bd83aeab0c8dc308cfd44e732dc..395a22282be0cd2edc9459e1ba14d7848073fa5d 100644
--- a/gcc/config/arm/elf.h
+++ b/gcc/config/arm/elf.h
@@ -104,7 +104,8 @@
    the code more efficient, but for Thumb-1 it's better to put them out of
    band unless we are generating compressed tables.  */
 #define JUMP_TABLES_IN_TEXT_SECTION					\
-   (TARGET_32BIT || (TARGET_THUMB && (optimize_size || flag_pic)))
+   ((TARGET_32BIT || (TARGET_THUMB && (optimize_size || flag_pic))) \
+    && !target_pure_code)
 
 #ifndef LINK_SPEC
 #define LINK_SPEC "%{mbig-endian:-EB} %{mlittle-endian:-EL} -X"
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 4f24daebc01f0fd006540df8d863014aa864d060..faeb4299acc1f0859eafa3e13cf4b24c4d0224d6 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -639,7 +639,8 @@ Objective-C and Objective-C++ Dialects}.
 -mneon-for-64bits @gol
 -mslow-flash-data @gol
 -masm-syntax-unified @gol
--mrestrict-it}
+-mrestrict-it @gol
+-mpure-code}
 
 @emph{AVR Options}
 @gccoptlist{-mmcu=@var{mcu} -maccumulate-args -mbranch-cost=@var{cost} @gol
@@ -14498,6 +14499,14 @@ Print CPU tuning information as comment in assembler file.  This is
 an option used only for regression testing of the compiler and not
 intended for ordinary use in compiling code.  This option is disabled
 by default.
+
+@item -mpure-code
+@opindex mpure-code
+Generate assembly where instructions and data are in separate sections.
+Additionally, give all text sections the ELF processor-specific section
+attribute SHF_ARM_PURECODE.  This option is only available when generating
+non-pic code in ELF object format for ARMv7-M targets.
+
 @end table
 
 @node AVR Options
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index b318615b7b35ab93ad13e5e535a1d4e6d02cb7f7..c9e1489a0453845a2bffb2df514cc3b5b73933dc 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -7543,6 +7543,15 @@ is non-NULL, it is the @code{VAR_DECL} or @code{FUNCTION_DECL} with which
 this section is associated.
 @end deftypefn
 
+@deftypefn {Target Hook} bool TARGET_ASM_ELF_FLAGS_NUMERIC (unsigned int @var{flags}, unsigned int *@var{num})
+If the target needs to represent ELF section attributes using their
+numerical value, then this hook should be implemented to return true and
+write the numerical value of @var{flags} in @var{num}.  This function is
+called by @code{default_elf_asm_named_section}, which prints @var{num}
+as the value representing the ELF section attributes if this function
+returns true.
+@end deftypefn
+
 @deftypefn {Target Hook} {section *} TARGET_ASM_FUNCTION_SECTION (tree @var{decl}, enum node_frequency @var{freq}, bool @var{startup}, bool @var{exit})
 Return preferred text (sub)section for function @var{decl}.
 Main purpose of this function is to separate cold, normal and hot
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 1e8423cb4e255acd8144e4b105186cee3d1d04fd..17a2ca73f07516526543253c77c088c73326af2c 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -5229,6 +5229,8 @@ of the filename using this macro.
 
 @hook TARGET_ASM_NAMED_SECTION
 
+@hook TARGET_ASM_ELF_FLAGS_NUMERIC
+
 @hook TARGET_ASM_FUNCTION_SECTION
 
 @hook TARGET_ASM_FUNCTION_SWITCHED_TEXT_SECTIONS
diff --git a/gcc/hooks.c b/gcc/hooks.c
index 99ec4014adb6fcbb073bf538dd00fe8695ee6cb2..1e925645c3173f8d97e104b9b2f480fca2ede438 100644
--- a/gcc/hooks.c
+++ b/gcc/hooks.c
@@ -481,3 +481,13 @@ void
 hook_void_gcc_optionsp (struct gcc_options *opts ATTRIBUTE_UNUSED)
 {
 }
+
+/* Generic hook that takes an unsigned int, an unsigned int pointer and
+   returns false.  */
+
+bool
+hook_uint_uintp_false (unsigned int, unsigned int *)
+{
+  return false;
+}
+
diff --git a/gcc/target.def b/gcc/target.def
index a4df363698ce776b51d11c187baed2069ba88a52..a3d46fa48d919a16699c33b2b78236e62a33e025 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -432,6 +432,19 @@ this section is associated.",
  void, (const char *name, unsigned int flags, tree decl),
  default_no_named_section)
 
+/* Tell assembler what section attributes to assign this elf section
+   declaration, using their numerical value.  */
+DEFHOOK
+(elf_flags_numeric,
+ "If the target needs to represent ELF section attributes using their\n\
+numerical value, then this hook should be implemented to return true and\n\
+write the numerical value of @var{flags} in @var{num}.  This function is\n\
+called by @code{default_elf_asm_named_section}, which prints @var{num}\n\
+as the value representing the ELF section attributes if this function\n\
+returns true.",
+ bool, (unsigned int flags, unsigned int *num),
+ hook_uint_uintp_false)
+
 /* Return preferred text (sub)section for function DECL.
    Main purpose of this function is to separate cold, normal and hot
    functions. STARTUP is true when function is known to be used only 
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index d6581cfab893e0da619c6bc0f98ff722a7ab4404..19ad97fa453cf6102b1502f97d8b66fe413284ee 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -254,5 +254,4 @@ extern void default_setup_incoming_vararg_bounds (cumulative_args_t ca ATTRIBUTE
 						  int second_time ATTRIBUTE_UNUSED);
 extern bool default_optab_supported_p (int, machine_mode, machine_mode,
 				       optimization_type);
-
 #endif /* GCC_TARGHOOKS_H */
diff --git a/gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c b/gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c
new file mode 100644
index 0000000000000000000000000000000000000000..26fe38c05295b70ccc35ed900d41b34aae2c87a8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-fpic" "-fPIC" } { "" } } */
+/* { dg-options "-ffunction-sections -mpure-code" } */
+#include <limits.h>
+
+char * foo (void)
+{
+  return "foo";
+}
+
+unsigned int bar (unsigned int b)
+{
+  return UINT_MAX - b;
+}
+
+/* { dg-final { scan-assembler {\.section\t\.text\.foo[^\n]*\"0x20000006\"} } } */
+/* { dg-final { scan-assembler {\.section\t\.text\.bar[^\n]*\"0x20000006\"} } } */
diff --git a/gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c b/gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c
new file mode 100644
index 0000000000000000000000000000000000000000..ba116a8261b16610e6af47d26a6e1a07b0127561
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-mpure-code" } */
+/* { dg-skip-if "" { *-*-* } { "-g" "-fpic" "-fPIC" } { "" } } */
+
+extern int foo (void);
+extern int bar (void);
+extern int baz (void);
+extern int fooz (void);
+
+int caller (unsigned int reg_type)
+{
+  switch (reg_type)
+    {
+    case 0x80000000:
+      return (int) foo ();
+
+    case 0x80000003:
+      return (int) bar ();
+
+    case 0x80000001:
+      return (int) baz ();
+
+    case 0x80000004:
+      return (int) fooz ();
+    }
+}
+
+/* { dg-final { scan-assembler-not "\\.(float|l\\?double|\d?byte|short|int|long|quad|word)\\s+\[^.\]" } } */
+/* { dg-final { scan-assembler "text,\"0x20000006\"" } } */
diff --git a/gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c b/gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c
new file mode 100644
index 0000000000000000000000000000000000000000..4b893fd32f722e6cd7dfde5c8542ab98327ba375
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-mpure-code" } */
+/* { dg-skip-if "" { *-*-* } { "-g" "-fpic" "-fPIC" } { "" } } */
+
+float sf;
+double df;
+long long l;
+static char *p = "Hello World";
+
+float
+testsf (float *p)
+{
+  if (*p > 1.1234f)
+    return 2.1234f;
+  else
+    return 3.1234f;
+}
+
+double
+testdf (double *p)
+{
+  if (*p > 4.1234)
+    return 2.1234;
+  else
+    return 3.1234;
+}
+
+long long
+testll (long long *p)
+{
+  if (*p > 0x123456789ABCDEFll)
+    return 0x111111111ll;
+  else
+    return 0x222222222ll;
+}
+
+char *
+testchar ()
+{
+  return p + 4;
+}
+
+int
+foo (int a, int b)
+{
+  int i;
+  volatile int *labelref = &&label1;
+
+  if (a > b)
+    {
+      while (i < b)
+	{
+	  a += *labelref;
+	  i += 1;
+	}
+      goto *labelref;
+    }
+  else
+    b = b + 3;
+
+  a = a * b;
+
+label1:
+  return a + b;
+}
+
+/* { dg-final { scan-assembler-not "\\.(float|l\\?double|\d?byte|short|int|long|quad|word)\\s+\[^.\]" } } */
+/* { dg-final { scan-assembler "text,\"0x20000006\"" } } */
diff --git a/gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp b/gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp
new file mode 100644
index 0000000000000000000000000000000000000000..1abe7782c0e5dbb6e2deef25f4bea9415664f942
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp
@@ -0,0 +1,54 @@
+#   Copyright (C) 1997-2016 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
+# <http://www.gnu.org/licenses/>.
+
+# GCC testsuite for ARM's -mpure-code option, using the `dg.exp' driver.
+
+# 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"
+}
+
+# The -mpure-code option is only available for M-profile targets that support
+# thumb2.
+if {[check_effective_target_arm_thumb2_ok]
+    && ![check_effective_target_arm_arm_ok]} then {
+# Initialize `dg'.
+dg-init
+
+set saved-dg-do-what-default ${dg-do-what-default}
+set dg-do-what-default "assemble"
+
+set saved-lto_torture_options ${LTO_TORTURE_OPTIONS}
+
+# Add -ffat-lto-objects option to all LTO options such that we can do assembly
+# scans.
+proc add_fat_objects { list } {
+    set res {}
+    foreach el $list {set res [lappend res [concat $el " -ffat-lto-objects"]]}
+    return $res
+};
+set LTO_TORTURE_OPTIONS [add_fat_objects ${LTO_TORTURE_OPTIONS}]
+
+gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] \
+	"" $DEFAULT_CFLAGS
+
+# All done.
+dg-finish
+}
diff --git a/gcc/varasm.c b/gcc/varasm.c
index de8bcd6f20c823acd03991f813da3521b80547ff..13007d8c1ce2d094633422abeb01d91b1e986ac4 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6244,6 +6244,7 @@ default_elf_asm_named_section (const char *name, unsigned int flags,
 			       tree decl)
 {
   char flagchars[11], *f = flagchars;
+  unsigned int numeric_value;
 
   /* If we have already declared this section, we can use an
      abbreviated form to switch back to it -- unless this section is
@@ -6256,31 +6257,38 @@ default_elf_asm_named_section (const char *name, unsigned int flags,
       return;
     }
 
-  if (!(flags & SECTION_DEBUG))
-    *f++ = 'a';
+  /* If we have a machine specific flag, then use the numeric value to pass
+     this on to GAS.  */
+  if (targetm.asm_out.elf_flags_numeric (flags, &numeric_value))
+      snprintf (f, sizeof (flagchars), "0x%08x", numeric_value);
+  else
+    {
+      if (!(flags & SECTION_DEBUG))
+	*f++ = 'a';
 #if defined (HAVE_GAS_SECTION_EXCLUDE) && HAVE_GAS_SECTION_EXCLUDE == 1
-  if (flags & SECTION_EXCLUDE)
-    *f++ = 'e';
+      if (flags & SECTION_EXCLUDE)
+	*f++ = 'e';
 #endif
-  if (flags & SECTION_WRITE)
-    *f++ = 'w';
-  if (flags & SECTION_CODE)
-    *f++ = 'x';
-  if (flags & SECTION_SMALL)
-    *f++ = 's';
-  if (flags & SECTION_MERGE)
-    *f++ = 'M';
-  if (flags & SECTION_STRINGS)
-    *f++ = 'S';
-  if (flags & SECTION_TLS)
-    *f++ = TLS_SECTION_ASM_FLAG;
-  if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
-    *f++ = 'G';
+      if (flags & SECTION_WRITE)
+	*f++ = 'w';
+      if (flags & SECTION_CODE)
+	*f++ = 'x';
+      if (flags & SECTION_SMALL)
+	*f++ = 's';
+      if (flags & SECTION_MERGE)
+	*f++ = 'M';
+      if (flags & SECTION_STRINGS)
+	*f++ = 'S';
+      if (flags & SECTION_TLS)
+	*f++ = TLS_SECTION_ASM_FLAG;
+      if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
+	*f++ = 'G';
 #ifdef MACH_DEP_SECTION_ASM_FLAG
-  if (flags & SECTION_MACH_DEP)
-    *f++ = MACH_DEP_SECTION_ASM_FLAG;
+      if (flags & SECTION_MACH_DEP)
+	*f++ = MACH_DEP_SECTION_ASM_FLAG;
 #endif
-  *f = '\0';
+      *f = '\0';
+    }
 
   fprintf (asm_out_file, "\t.section\t%s,\"%s\"", name, flagchars);
 
-- 
1.9.1


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCHv2, PING][ARM] -mpure-code option for ARM
  2016-07-11 16:57   ` [PATCHv2][ARM] " Andre Vieira (lists)
@ 2016-07-25 10:52     ` Andre Vieira (lists)
  2016-08-11 14:13       ` [PATCHv2, PING 2][ARM] " Andre Vieira (lists)
  2016-09-22 14:22     ` [PATCHv2][ARM] " Richard Earnshaw (lists)
  1 sibling, 1 reply; 24+ messages in thread
From: Andre Vieira (lists) @ 2016-07-25 10:52 UTC (permalink / raw)
  To: gcc-patches

On 11/07/16 17:56, Andre Vieira (lists) wrote:
> On 07/07/16 13:30, mickael guene wrote:
>> Hi Andre,
>>
>>  Another feedback on your purecode patch.
>>  You have to disable casesi pattern since then it will
>> generate wrong code with -mpure-code option.
>>  Indeed it will generate an 'adr rx, .Lx' (aka
>> 'subs rx, PC, #offset') which will not work in our
>> case since 'Lx' label is put in an .rodata section.
>> So offset value is unknown and can be impossible
>> to encode correctly.
>>
>> Regards
>> Mickael
>>
>> On 06/30/2016 04:32 PM, Andre Vieira (lists) wrote:
>>> Hello,
>>>
>>> This patch adds the -mpure-code option for ARM. This option ensures
>>> functions are put into sections that contain only code and no data. To
>>> ensure this throughout compilation we give these sections the ARM
>>> processor-specific ELF section attribute "SHF_ARM_PURECODE". This option
>>> is only supported for non-pic code for armv7-m targets.
>>>
>>> This patch introduces a new target hook 'TARGET_ASM_ELF_FLAGS_NUMERIC'.
>>> This target hook enables a target to use the numeric value for elf
>>> section attributes rather than their alphabetical representation. If
>>> TARGET_ASM_ELF_FLAGS_NUMERIC returns TRUE, the existing
>>> 'default_elf_asm_named_section', will print the numeric value of the
>>> section attributes for the current section. This target hook has two
>>> parameters:
>>> unsigned int FLAGS, the input parameter that tells the function the
>>> current section's attributes;
>>> unsigned int *NUM, used to pass down the numerical representation of the
>>> section's attributes.
>>>
>>> The default implementation for TARGET_ASM_ELF_FLAGS_NUMERIC will return
>>> false, so existing behavior is not changed.
>>>
>>> Bootstrapped and tested for arm-none-linux-gnueabihf. Further tested for
>>> arm-none-eabi with a Cortex-M3 target.
>>>
>>>
>>> gcc/ChangeLog:
>>> 2016-06-30  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>>             Terry Guo  <terry.guo@arm.com>
>>>
>>>         * target.def (elf_flags_numeric): New target hook.
>>>         * targhooks.h (default_asm_elf_flags_numeric): New.
>>>         * varasm.c (default_asm_elf_flags_numeric): New.
>>>           (default_elf_asm_named_section): Use new target hook.
>>>         * config/arm/arm.opt (mpure-code): New.
>>>         * config/arm/arm.h (SECTION_ARM_PURECODE): New.
>>>         * config/arm/arm.c (arm_asm_init_sections): Add section
>>>           attribute to default text section if -mpure-code.
>>>           (arm_option_check_internal): Diagnose use of option with
>>>           non supported targets and/or options.
>>>           (arm_asm_elf_flags_numeric): New.
>>>           (arm_function_section): New.
>>>           (arm_elf_section_type_flags): New.
>>>         * config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Disable
>>>           for -mpure-code.
>>>         * gcc/doc/texi (TARGET_ASM_ELF_FLAGS_NUMERIC): New.
>>>         * gcc/doc/texi.in (TARGET_ASM_ELF_FLAGS_NUMERIC): Likewise.
>>>
>>>
>>>
>>> gcc/testsuite/ChangeLog:
>>> 2016-06-30  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>>             Terry Guo  <terry.guo@arm.com>
>>>
>>>         * gcc.target/arm/pure-code/ffunction-sections.c: New.
>>>         * gcc.target/arm/pure-code/no-literal-pool.c: New.
>>>         * gcc.target/arm/pure-code/pure-code.exp: New.
>>>
>>
> Hi Sandra, Mickael,
> 
> Thank you for your comments. I changed the description of -mpure-code in
> invoke.texi to better reflect the error message you get wrt supported
> targets.
> 
> As for the target hook description, I hope the text is clearer now. Let
> me know if you think it needs further explanation.
> 
> I also fixed the double '%' in the text string for unnamed text sections
> and disabled the casesi pattern.
> 
> I duplicated the original casesi test
> 'gcc/testsuite/gcc.c-torture/compile/pr46934.c' for pure-code to make
> sure the casesi was disabled and other patterns were selected instead.
> 
> Reran regressions for pure-code.exp for Cortex-M3.
> 
> Cheers,
> Andre
> 
> 
> gcc/ChangeLog:
> 2016-07-11  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>             Terry Guo  <terry.guo@arm.com>
> 
>         * target.def (elf_flags_numeric): New target hook.
>         * hooks.c (hook_uint_uintp_false): New generic hook.
>         * varasm.c (default_elf_asm_named_section): Use new target hook.
>         * config/arm/arm.opt (mpure-code): New.
>         * config/arm/arm.h (SECTION_ARM_PURECODE): New.
>         * config/arm/arm.c (arm_asm_init_sections): Add section
>         attribute to default text section if -mpure-code.
>         (arm_option_check_internal): Diagnose use of option with
>         non supported targets and/or options.
>         (arm_asm_elf_flags_numeric): New.
>         (arm_function_section): New.
>         (arm_elf_section_type_flags): New.
>         * config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Disable
>         for -mpure-code.
>         * config/arm/arm.md (casesi): Disable pattern for
>         -mpure-code.
>         * gcc/doc/texi (TARGET_ASM_ELF_FLAGS_NUMERIC): New.
>         * gcc/doc/texi.in (TARGET_ASM_ELF_FLAGS_NUMERIC): Likewise.
> 
> 
> 
> gcc/testsuite/ChangeLog:
> 2016-07-11  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>             Terry Guo  <terry.guo@arm.com>
> 
>         * gcc.target/arm/pure-code/ffunction-sections.c: New.
>         * gcc.target/arm/pure-code/no-literal-pool.c: New.
>         * gcc.target/arm/pure-code/no-casesi.c: New.
>         * gcc.target/arm/pure-code/pure-code.exp: New.
> 
Ping.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCHv2, PING 2][ARM] -mpure-code option for ARM
  2016-07-25 10:52     ` [PATCHv2, PING][ARM] " Andre Vieira (lists)
@ 2016-08-11 14:13       ` Andre Vieira (lists)
  2016-08-30  8:01         ` [PATCHv2, PING 3][ARM] " Andre Vieira (lists)
  0 siblings, 1 reply; 24+ messages in thread
From: Andre Vieira (lists) @ 2016-08-11 14:13 UTC (permalink / raw)
  To: gcc-patches

On 25/07/16 11:52, Andre Vieira (lists) wrote:
> On 11/07/16 17:56, Andre Vieira (lists) wrote:
>> On 07/07/16 13:30, mickael guene wrote:
>>> Hi Andre,
>>>
>>>  Another feedback on your purecode patch.
>>>  You have to disable casesi pattern since then it will
>>> generate wrong code with -mpure-code option.
>>>  Indeed it will generate an 'adr rx, .Lx' (aka
>>> 'subs rx, PC, #offset') which will not work in our
>>> case since 'Lx' label is put in an .rodata section.
>>> So offset value is unknown and can be impossible
>>> to encode correctly.
>>>
>>> Regards
>>> Mickael
>>>
>>> On 06/30/2016 04:32 PM, Andre Vieira (lists) wrote:
>>>> Hello,
>>>>
>>>> This patch adds the -mpure-code option for ARM. This option ensures
>>>> functions are put into sections that contain only code and no data. To
>>>> ensure this throughout compilation we give these sections the ARM
>>>> processor-specific ELF section attribute "SHF_ARM_PURECODE". This option
>>>> is only supported for non-pic code for armv7-m targets.
>>>>
>>>> This patch introduces a new target hook 'TARGET_ASM_ELF_FLAGS_NUMERIC'.
>>>> This target hook enables a target to use the numeric value for elf
>>>> section attributes rather than their alphabetical representation. If
>>>> TARGET_ASM_ELF_FLAGS_NUMERIC returns TRUE, the existing
>>>> 'default_elf_asm_named_section', will print the numeric value of the
>>>> section attributes for the current section. This target hook has two
>>>> parameters:
>>>> unsigned int FLAGS, the input parameter that tells the function the
>>>> current section's attributes;
>>>> unsigned int *NUM, used to pass down the numerical representation of the
>>>> section's attributes.
>>>>
>>>> The default implementation for TARGET_ASM_ELF_FLAGS_NUMERIC will return
>>>> false, so existing behavior is not changed.
>>>>
>>>> Bootstrapped and tested for arm-none-linux-gnueabihf. Further tested for
>>>> arm-none-eabi with a Cortex-M3 target.
>>>>
>>>>
>>>> gcc/ChangeLog:
>>>> 2016-06-30  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>>>             Terry Guo  <terry.guo@arm.com>
>>>>
>>>>         * target.def (elf_flags_numeric): New target hook.
>>>>         * targhooks.h (default_asm_elf_flags_numeric): New.
>>>>         * varasm.c (default_asm_elf_flags_numeric): New.
>>>>           (default_elf_asm_named_section): Use new target hook.
>>>>         * config/arm/arm.opt (mpure-code): New.
>>>>         * config/arm/arm.h (SECTION_ARM_PURECODE): New.
>>>>         * config/arm/arm.c (arm_asm_init_sections): Add section
>>>>           attribute to default text section if -mpure-code.
>>>>           (arm_option_check_internal): Diagnose use of option with
>>>>           non supported targets and/or options.
>>>>           (arm_asm_elf_flags_numeric): New.
>>>>           (arm_function_section): New.
>>>>           (arm_elf_section_type_flags): New.
>>>>         * config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Disable
>>>>           for -mpure-code.
>>>>         * gcc/doc/texi (TARGET_ASM_ELF_FLAGS_NUMERIC): New.
>>>>         * gcc/doc/texi.in (TARGET_ASM_ELF_FLAGS_NUMERIC): Likewise.
>>>>
>>>>
>>>>
>>>> gcc/testsuite/ChangeLog:
>>>> 2016-06-30  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>>>             Terry Guo  <terry.guo@arm.com>
>>>>
>>>>         * gcc.target/arm/pure-code/ffunction-sections.c: New.
>>>>         * gcc.target/arm/pure-code/no-literal-pool.c: New.
>>>>         * gcc.target/arm/pure-code/pure-code.exp: New.
>>>>
>>>
>> Hi Sandra, Mickael,
>>
>> Thank you for your comments. I changed the description of -mpure-code in
>> invoke.texi to better reflect the error message you get wrt supported
>> targets.
>>
>> As for the target hook description, I hope the text is clearer now. Let
>> me know if you think it needs further explanation.
>>
>> I also fixed the double '%' in the text string for unnamed text sections
>> and disabled the casesi pattern.
>>
>> I duplicated the original casesi test
>> 'gcc/testsuite/gcc.c-torture/compile/pr46934.c' for pure-code to make
>> sure the casesi was disabled and other patterns were selected instead.
>>
>> Reran regressions for pure-code.exp for Cortex-M3.
>>
>> Cheers,
>> Andre
>>
>>
>> gcc/ChangeLog:
>> 2016-07-11  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>             Terry Guo  <terry.guo@arm.com>
>>
>>         * target.def (elf_flags_numeric): New target hook.
>>         * hooks.c (hook_uint_uintp_false): New generic hook.
>>         * varasm.c (default_elf_asm_named_section): Use new target hook.
>>         * config/arm/arm.opt (mpure-code): New.
>>         * config/arm/arm.h (SECTION_ARM_PURECODE): New.
>>         * config/arm/arm.c (arm_asm_init_sections): Add section
>>         attribute to default text section if -mpure-code.
>>         (arm_option_check_internal): Diagnose use of option with
>>         non supported targets and/or options.
>>         (arm_asm_elf_flags_numeric): New.
>>         (arm_function_section): New.
>>         (arm_elf_section_type_flags): New.
>>         * config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Disable
>>         for -mpure-code.
>>         * config/arm/arm.md (casesi): Disable pattern for
>>         -mpure-code.
>>         * gcc/doc/texi (TARGET_ASM_ELF_FLAGS_NUMERIC): New.
>>         * gcc/doc/texi.in (TARGET_ASM_ELF_FLAGS_NUMERIC): Likewise.
>>
>>
>>
>> gcc/testsuite/ChangeLog:
>> 2016-07-11  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>             Terry Guo  <terry.guo@arm.com>
>>
>>         * gcc.target/arm/pure-code/ffunction-sections.c: New.
>>         * gcc.target/arm/pure-code/no-literal-pool.c: New.
>>         * gcc.target/arm/pure-code/no-casesi.c: New.
>>         * gcc.target/arm/pure-code/pure-code.exp: New.
>>
> Ping.
> 
Ping

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCHv2, PING 3][ARM] -mpure-code option for ARM
  2016-08-11 14:13       ` [PATCHv2, PING 2][ARM] " Andre Vieira (lists)
@ 2016-08-30  8:01         ` Andre Vieira (lists)
  2016-09-19  9:25           ` [PATCHv2, PING 4][ARM] " Andre Vieira (lists)
  0 siblings, 1 reply; 24+ messages in thread
From: Andre Vieira (lists) @ 2016-08-30  8:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: Ramana Radhakrishnan

On 11/08/16 15:13, Andre Vieira (lists) wrote:
> On 25/07/16 11:52, Andre Vieira (lists) wrote:
>> On 11/07/16 17:56, Andre Vieira (lists) wrote:
>>> On 07/07/16 13:30, mickael guene wrote:
>>>> Hi Andre,
>>>>
>>>>  Another feedback on your purecode patch.
>>>>  You have to disable casesi pattern since then it will
>>>> generate wrong code with -mpure-code option.
>>>>  Indeed it will generate an 'adr rx, .Lx' (aka
>>>> 'subs rx, PC, #offset') which will not work in our
>>>> case since 'Lx' label is put in an .rodata section.
>>>> So offset value is unknown and can be impossible
>>>> to encode correctly.
>>>>
>>>> Regards
>>>> Mickael
>>>>
>>>> On 06/30/2016 04:32 PM, Andre Vieira (lists) wrote:
>>>>> Hello,
>>>>>
>>>>> This patch adds the -mpure-code option for ARM. This option ensures
>>>>> functions are put into sections that contain only code and no data. To
>>>>> ensure this throughout compilation we give these sections the ARM
>>>>> processor-specific ELF section attribute "SHF_ARM_PURECODE". This option
>>>>> is only supported for non-pic code for armv7-m targets.
>>>>>
>>>>> This patch introduces a new target hook 'TARGET_ASM_ELF_FLAGS_NUMERIC'.
>>>>> This target hook enables a target to use the numeric value for elf
>>>>> section attributes rather than their alphabetical representation. If
>>>>> TARGET_ASM_ELF_FLAGS_NUMERIC returns TRUE, the existing
>>>>> 'default_elf_asm_named_section', will print the numeric value of the
>>>>> section attributes for the current section. This target hook has two
>>>>> parameters:
>>>>> unsigned int FLAGS, the input parameter that tells the function the
>>>>> current section's attributes;
>>>>> unsigned int *NUM, used to pass down the numerical representation of the
>>>>> section's attributes.
>>>>>
>>>>> The default implementation for TARGET_ASM_ELF_FLAGS_NUMERIC will return
>>>>> false, so existing behavior is not changed.
>>>>>
>>>>> Bootstrapped and tested for arm-none-linux-gnueabihf. Further tested for
>>>>> arm-none-eabi with a Cortex-M3 target.
>>>>>
>>>>>
>>>>> gcc/ChangeLog:
>>>>> 2016-06-30  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>>>>             Terry Guo  <terry.guo@arm.com>
>>>>>
>>>>>         * target.def (elf_flags_numeric): New target hook.
>>>>>         * targhooks.h (default_asm_elf_flags_numeric): New.
>>>>>         * varasm.c (default_asm_elf_flags_numeric): New.
>>>>>           (default_elf_asm_named_section): Use new target hook.
>>>>>         * config/arm/arm.opt (mpure-code): New.
>>>>>         * config/arm/arm.h (SECTION_ARM_PURECODE): New.
>>>>>         * config/arm/arm.c (arm_asm_init_sections): Add section
>>>>>           attribute to default text section if -mpure-code.
>>>>>           (arm_option_check_internal): Diagnose use of option with
>>>>>           non supported targets and/or options.
>>>>>           (arm_asm_elf_flags_numeric): New.
>>>>>           (arm_function_section): New.
>>>>>           (arm_elf_section_type_flags): New.
>>>>>         * config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Disable
>>>>>           for -mpure-code.
>>>>>         * gcc/doc/texi (TARGET_ASM_ELF_FLAGS_NUMERIC): New.
>>>>>         * gcc/doc/texi.in (TARGET_ASM_ELF_FLAGS_NUMERIC): Likewise.
>>>>>
>>>>>
>>>>>
>>>>> gcc/testsuite/ChangeLog:
>>>>> 2016-06-30  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>>>>             Terry Guo  <terry.guo@arm.com>
>>>>>
>>>>>         * gcc.target/arm/pure-code/ffunction-sections.c: New.
>>>>>         * gcc.target/arm/pure-code/no-literal-pool.c: New.
>>>>>         * gcc.target/arm/pure-code/pure-code.exp: New.
>>>>>
>>>>
>>> Hi Sandra, Mickael,
>>>
>>> Thank you for your comments. I changed the description of -mpure-code in
>>> invoke.texi to better reflect the error message you get wrt supported
>>> targets.
>>>
>>> As for the target hook description, I hope the text is clearer now. Let
>>> me know if you think it needs further explanation.
>>>
>>> I also fixed the double '%' in the text string for unnamed text sections
>>> and disabled the casesi pattern.
>>>
>>> I duplicated the original casesi test
>>> 'gcc/testsuite/gcc.c-torture/compile/pr46934.c' for pure-code to make
>>> sure the casesi was disabled and other patterns were selected instead.
>>>
>>> Reran regressions for pure-code.exp for Cortex-M3.
>>>
>>> Cheers,
>>> Andre
>>>
>>>
>>> gcc/ChangeLog:
>>> 2016-07-11  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>>             Terry Guo  <terry.guo@arm.com>
>>>
>>>         * target.def (elf_flags_numeric): New target hook.
>>>         * hooks.c (hook_uint_uintp_false): New generic hook.
>>>         * varasm.c (default_elf_asm_named_section): Use new target hook.
>>>         * config/arm/arm.opt (mpure-code): New.
>>>         * config/arm/arm.h (SECTION_ARM_PURECODE): New.
>>>         * config/arm/arm.c (arm_asm_init_sections): Add section
>>>         attribute to default text section if -mpure-code.
>>>         (arm_option_check_internal): Diagnose use of option with
>>>         non supported targets and/or options.
>>>         (arm_asm_elf_flags_numeric): New.
>>>         (arm_function_section): New.
>>>         (arm_elf_section_type_flags): New.
>>>         * config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Disable
>>>         for -mpure-code.
>>>         * config/arm/arm.md (casesi): Disable pattern for
>>>         -mpure-code.
>>>         * gcc/doc/texi (TARGET_ASM_ELF_FLAGS_NUMERIC): New.
>>>         * gcc/doc/texi.in (TARGET_ASM_ELF_FLAGS_NUMERIC): Likewise.
>>>
>>>
>>>
>>> gcc/testsuite/ChangeLog:
>>> 2016-07-11  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>>             Terry Guo  <terry.guo@arm.com>
>>>
>>>         * gcc.target/arm/pure-code/ffunction-sections.c: New.
>>>         * gcc.target/arm/pure-code/no-literal-pool.c: New.
>>>         * gcc.target/arm/pure-code/no-casesi.c: New.
>>>         * gcc.target/arm/pure-code/pure-code.exp: New.
>>>
>> Ping.
>>
> Ping
> 

Ping

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCHv2, PING 4][ARM] -mpure-code option for ARM
  2016-08-30  8:01         ` [PATCHv2, PING 3][ARM] " Andre Vieira (lists)
@ 2016-09-19  9:25           ` Andre Vieira (lists)
  0 siblings, 0 replies; 24+ messages in thread
From: Andre Vieira (lists) @ 2016-09-19  9:25 UTC (permalink / raw)
  To: gcc-patches; +Cc: Richard Earnshaw

On 30/08/16 09:01, Andre Vieira (lists) wrote:
> On 11/08/16 15:13, Andre Vieira (lists) wrote:
>> On 25/07/16 11:52, Andre Vieira (lists) wrote:
>>> On 11/07/16 17:56, Andre Vieira (lists) wrote:
>>>> On 07/07/16 13:30, mickael guene wrote:
>>>>> Hi Andre,
>>>>>
>>>>>  Another feedback on your purecode patch.
>>>>>  You have to disable casesi pattern since then it will
>>>>> generate wrong code with -mpure-code option.
>>>>>  Indeed it will generate an 'adr rx, .Lx' (aka
>>>>> 'subs rx, PC, #offset') which will not work in our
>>>>> case since 'Lx' label is put in an .rodata section.
>>>>> So offset value is unknown and can be impossible
>>>>> to encode correctly.
>>>>>
>>>>> Regards
>>>>> Mickael
>>>>>
>>>>> On 06/30/2016 04:32 PM, Andre Vieira (lists) wrote:
>>>>>> Hello,
>>>>>>
>>>>>> This patch adds the -mpure-code option for ARM. This option ensures
>>>>>> functions are put into sections that contain only code and no data. To
>>>>>> ensure this throughout compilation we give these sections the ARM
>>>>>> processor-specific ELF section attribute "SHF_ARM_PURECODE". This option
>>>>>> is only supported for non-pic code for armv7-m targets.
>>>>>>
>>>>>> This patch introduces a new target hook 'TARGET_ASM_ELF_FLAGS_NUMERIC'.
>>>>>> This target hook enables a target to use the numeric value for elf
>>>>>> section attributes rather than their alphabetical representation. If
>>>>>> TARGET_ASM_ELF_FLAGS_NUMERIC returns TRUE, the existing
>>>>>> 'default_elf_asm_named_section', will print the numeric value of the
>>>>>> section attributes for the current section. This target hook has two
>>>>>> parameters:
>>>>>> unsigned int FLAGS, the input parameter that tells the function the
>>>>>> current section's attributes;
>>>>>> unsigned int *NUM, used to pass down the numerical representation of the
>>>>>> section's attributes.
>>>>>>
>>>>>> The default implementation for TARGET_ASM_ELF_FLAGS_NUMERIC will return
>>>>>> false, so existing behavior is not changed.
>>>>>>
>>>>>> Bootstrapped and tested for arm-none-linux-gnueabihf. Further tested for
>>>>>> arm-none-eabi with a Cortex-M3 target.
>>>>>>
>>>>>>
>>>>>> gcc/ChangeLog:
>>>>>> 2016-06-30  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>>>>>             Terry Guo  <terry.guo@arm.com>
>>>>>>
>>>>>>         * target.def (elf_flags_numeric): New target hook.
>>>>>>         * targhooks.h (default_asm_elf_flags_numeric): New.
>>>>>>         * varasm.c (default_asm_elf_flags_numeric): New.
>>>>>>           (default_elf_asm_named_section): Use new target hook.
>>>>>>         * config/arm/arm.opt (mpure-code): New.
>>>>>>         * config/arm/arm.h (SECTION_ARM_PURECODE): New.
>>>>>>         * config/arm/arm.c (arm_asm_init_sections): Add section
>>>>>>           attribute to default text section if -mpure-code.
>>>>>>           (arm_option_check_internal): Diagnose use of option with
>>>>>>           non supported targets and/or options.
>>>>>>           (arm_asm_elf_flags_numeric): New.
>>>>>>           (arm_function_section): New.
>>>>>>           (arm_elf_section_type_flags): New.
>>>>>>         * config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Disable
>>>>>>           for -mpure-code.
>>>>>>         * gcc/doc/texi (TARGET_ASM_ELF_FLAGS_NUMERIC): New.
>>>>>>         * gcc/doc/texi.in (TARGET_ASM_ELF_FLAGS_NUMERIC): Likewise.
>>>>>>
>>>>>>
>>>>>>
>>>>>> gcc/testsuite/ChangeLog:
>>>>>> 2016-06-30  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>>>>>             Terry Guo  <terry.guo@arm.com>
>>>>>>
>>>>>>         * gcc.target/arm/pure-code/ffunction-sections.c: New.
>>>>>>         * gcc.target/arm/pure-code/no-literal-pool.c: New.
>>>>>>         * gcc.target/arm/pure-code/pure-code.exp: New.
>>>>>>
>>>>>
>>>> Hi Sandra, Mickael,
>>>>
>>>> Thank you for your comments. I changed the description of -mpure-code in
>>>> invoke.texi to better reflect the error message you get wrt supported
>>>> targets.
>>>>
>>>> As for the target hook description, I hope the text is clearer now. Let
>>>> me know if you think it needs further explanation.
>>>>
>>>> I also fixed the double '%' in the text string for unnamed text sections
>>>> and disabled the casesi pattern.
>>>>
>>>> I duplicated the original casesi test
>>>> 'gcc/testsuite/gcc.c-torture/compile/pr46934.c' for pure-code to make
>>>> sure the casesi was disabled and other patterns were selected instead.
>>>>
>>>> Reran regressions for pure-code.exp for Cortex-M3.
>>>>
>>>> Cheers,
>>>> Andre
>>>>
>>>>
>>>> gcc/ChangeLog:
>>>> 2016-07-11  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>>>             Terry Guo  <terry.guo@arm.com>
>>>>
>>>>         * target.def (elf_flags_numeric): New target hook.
>>>>         * hooks.c (hook_uint_uintp_false): New generic hook.
>>>>         * varasm.c (default_elf_asm_named_section): Use new target hook.
>>>>         * config/arm/arm.opt (mpure-code): New.
>>>>         * config/arm/arm.h (SECTION_ARM_PURECODE): New.
>>>>         * config/arm/arm.c (arm_asm_init_sections): Add section
>>>>         attribute to default text section if -mpure-code.
>>>>         (arm_option_check_internal): Diagnose use of option with
>>>>         non supported targets and/or options.
>>>>         (arm_asm_elf_flags_numeric): New.
>>>>         (arm_function_section): New.
>>>>         (arm_elf_section_type_flags): New.
>>>>         * config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Disable
>>>>         for -mpure-code.
>>>>         * config/arm/arm.md (casesi): Disable pattern for
>>>>         -mpure-code.
>>>>         * gcc/doc/texi (TARGET_ASM_ELF_FLAGS_NUMERIC): New.
>>>>         * gcc/doc/texi.in (TARGET_ASM_ELF_FLAGS_NUMERIC): Likewise.
>>>>
>>>>
>>>>
>>>> gcc/testsuite/ChangeLog:
>>>> 2016-07-11  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>>>             Terry Guo  <terry.guo@arm.com>
>>>>
>>>>         * gcc.target/arm/pure-code/ffunction-sections.c: New.
>>>>         * gcc.target/arm/pure-code/no-literal-pool.c: New.
>>>>         * gcc.target/arm/pure-code/no-casesi.c: New.
>>>>         * gcc.target/arm/pure-code/pure-code.exp: New.
>>>>
>>> Ping.
>>>
>> Ping
>>
> 
> Ping
> 
Ping

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCHv2][ARM] -mpure-code option for ARM
  2016-07-11 16:57   ` [PATCHv2][ARM] " Andre Vieira (lists)
  2016-07-25 10:52     ` [PATCHv2, PING][ARM] " Andre Vieira (lists)
@ 2016-09-22 14:22     ` Richard Earnshaw (lists)
  2016-09-22 15:10       ` [PATCHv3][ARM] " Andre Vieira (lists)
  2016-09-23  6:31       ` [PATCHv2][ARM] " Sandra Loosemore
  1 sibling, 2 replies; 24+ messages in thread
From: Richard Earnshaw (lists) @ 2016-09-22 14:22 UTC (permalink / raw)
  To: Andre Vieira (lists), GCC Patches; +Cc: mickael guene, sandra

On 11/07/16 17:56, Andre Vieira (lists) wrote:
> On 07/07/16 13:30, mickael guene wrote:
>> Hi Andre,
>>
>>  Another feedback on your purecode patch.
>>  You have to disable casesi pattern since then it will
>> generate wrong code with -mpure-code option.
>>  Indeed it will generate an 'adr rx, .Lx' (aka
>> 'subs rx, PC, #offset') which will not work in our
>> case since 'Lx' label is put in an .rodata section.
>> So offset value is unknown and can be impossible
>> to encode correctly.
>>
>> Regards
>> Mickael
>>
>> On 06/30/2016 04:32 PM, Andre Vieira (lists) wrote:
>>> Hello,
>>>
>>> This patch adds the -mpure-code option for ARM. This option ensures
>>> functions are put into sections that contain only code and no data. To
>>> ensure this throughout compilation we give these sections the ARM
>>> processor-specific ELF section attribute "SHF_ARM_PURECODE". This option
>>> is only supported for non-pic code for armv7-m targets.
>>>
>>> This patch introduces a new target hook 'TARGET_ASM_ELF_FLAGS_NUMERIC'.
>>> This target hook enables a target to use the numeric value for elf
>>> section attributes rather than their alphabetical representation. If
>>> TARGET_ASM_ELF_FLAGS_NUMERIC returns TRUE, the existing
>>> 'default_elf_asm_named_section', will print the numeric value of the
>>> section attributes for the current section. This target hook has two
>>> parameters:
>>> unsigned int FLAGS, the input parameter that tells the function the
>>> current section's attributes;
>>> unsigned int *NUM, used to pass down the numerical representation of the
>>> section's attributes.
>>>
>>> The default implementation for TARGET_ASM_ELF_FLAGS_NUMERIC will return
>>> false, so existing behavior is not changed.
>>>
>>> Bootstrapped and tested for arm-none-linux-gnueabihf. Further tested for
>>> arm-none-eabi with a Cortex-M3 target.
>>>
>>>
>>> gcc/ChangeLog:
>>> 2016-06-30  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>>             Terry Guo  <terry.guo@arm.com>
>>>
>>>         * target.def (elf_flags_numeric): New target hook.
>>>         * targhooks.h (default_asm_elf_flags_numeric): New.
>>>         * varasm.c (default_asm_elf_flags_numeric): New.
>>>           (default_elf_asm_named_section): Use new target hook.
>>>         * config/arm/arm.opt (mpure-code): New.
>>>         * config/arm/arm.h (SECTION_ARM_PURECODE): New.
>>>         * config/arm/arm.c (arm_asm_init_sections): Add section
>>>           attribute to default text section if -mpure-code.
>>>           (arm_option_check_internal): Diagnose use of option with
>>>           non supported targets and/or options.
>>>           (arm_asm_elf_flags_numeric): New.
>>>           (arm_function_section): New.
>>>           (arm_elf_section_type_flags): New.
>>>         * config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Disable
>>>           for -mpure-code.
>>>         * gcc/doc/texi (TARGET_ASM_ELF_FLAGS_NUMERIC): New.
>>>         * gcc/doc/texi.in (TARGET_ASM_ELF_FLAGS_NUMERIC): Likewise.
>>>
>>>
>>>
>>> gcc/testsuite/ChangeLog:
>>> 2016-06-30  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>>             Terry Guo  <terry.guo@arm.com>
>>>
>>>         * gcc.target/arm/pure-code/ffunction-sections.c: New.
>>>         * gcc.target/arm/pure-code/no-literal-pool.c: New.
>>>         * gcc.target/arm/pure-code/pure-code.exp: New.
>>>
>>
> Hi Sandra, Mickael,
> 
> Thank you for your comments. I changed the description of -mpure-code in
> invoke.texi to better reflect the error message you get wrt supported
> targets.
> 
> As for the target hook description, I hope the text is clearer now. Let
> me know if you think it needs further explanation.
> 
> I also fixed the double '%' in the text string for unnamed text sections
> and disabled the casesi pattern.
> 
> I duplicated the original casesi test
> 'gcc/testsuite/gcc.c-torture/compile/pr46934.c' for pure-code to make
> sure the casesi was disabled and other patterns were selected instead.
> 
> Reran regressions for pure-code.exp for Cortex-M3.
> 
> Cheers,
> Andre
> 
> 
> gcc/ChangeLog:
> 2016-07-11  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>             Terry Guo  <terry.guo@arm.com>
> 
>         * target.def (elf_flags_numeric): New target hook.
>         * hooks.c (hook_uint_uintp_false): New generic hook.
>         * varasm.c (default_elf_asm_named_section): Use new target hook.
>         * config/arm/arm.opt (mpure-code): New.
>         * config/arm/arm.h (SECTION_ARM_PURECODE): New.
>         * config/arm/arm.c (arm_asm_init_sections): Add section
>         attribute to default text section if -mpure-code.
>         (arm_option_check_internal): Diagnose use of option with
>         non supported targets and/or options.
>         (arm_asm_elf_flags_numeric): New.
>         (arm_function_section): New.
>         (arm_elf_section_type_flags): New.
>         * config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Disable
>         for -mpure-code.
>         * config/arm/arm.md (casesi): Disable pattern for
>         -mpure-code.
>         * gcc/doc/texi (TARGET_ASM_ELF_FLAGS_NUMERIC): New.
>         * gcc/doc/texi.in (TARGET_ASM_ELF_FLAGS_NUMERIC): Likewise.
> 
> 
> 
> gcc/testsuite/ChangeLog:
> 2016-07-11  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>             Terry Guo  <terry.guo@arm.com>
> 
>         * gcc.target/arm/pure-code/ffunction-sections.c: New.
>         * gcc.target/arm/pure-code/no-literal-pool.c: New.
>         * gcc.target/arm/pure-code/no-casesi.c: New.
>         * gcc.target/arm/pure-code/pure-code.exp: New.
> 
> 
> 0001-mpure-code-for-ARM.patch
> 
> 
> diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
> index f0cdd669191689bc5dcf3a7c2b60da5a2d201e3f..d10605cee0e6e0e07bbb4e1910d30c91443f8d17 100644
> --- a/gcc/config/arm/arm.h
> +++ b/gcc/config/arm/arm.h
> @@ -2263,4 +2263,8 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
>  /* For switching between functions with different target attributes.  */
>  #define SWITCHABLE_TARGET 1
>  
> +/* Define SECTION_ARM_PURECODE as the ARM specific section attribute
> +   representation for SHF_ARM_PURECODE in GCC.  */
> +#define SECTION_ARM_PURECODE SECTION_MACH_DEP
> +
>  #endif /* ! GCC_ARM_H */
> From b35a27e363a6123c6c50bd29e284c89f6ae434a5 Mon Sep 17 00:00:00 2001
> From: Andre Simoes Dias Vieira <andsim01@arm.com>
> Date: Tue, 14 Jun 2016 11:17:12 +0100
> Subject: [PATCH] -mpure-code for ARM
> 
> ---
>  gcc/config/arm/arm.c                               | 150 ++++++++++++++++++++-
>  gcc/config/arm/arm.h                               |   4 +
>  gcc/config/arm/arm.md                              |   2 +-
>  gcc/config/arm/arm.opt                             |   6 +
>  gcc/config/arm/elf.h                               |   3 +-
>  gcc/doc/invoke.texi                                |  11 +-
>  gcc/doc/tm.texi                                    |   9 ++
>  gcc/doc/tm.texi.in                                 |   2 +
>  gcc/hooks.c                                        |  10 ++
>  gcc/target.def                                     |  13 ++
>  gcc/targhooks.h                                    |   1 -
>  .../gcc.target/arm/pure-code/ffunction-sections.c  |  17 +++
>  gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c |  29 ++++
>  .../gcc.target/arm/pure-code/no-literal-pool.c     |  68 ++++++++++
>  .../gcc.target/arm/pure-code/pure-code.exp         |  54 ++++++++
>  gcc/varasm.c                                       |  50 ++++---
>  16 files changed, 398 insertions(+), 31 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c
>  create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c
>  create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c
>  create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp
> 
> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
> index f60955438d6f1cc5d996e7eacd4b453213044181..9b5013a069235d18eebc10a312e364de9f756906 100644
> --- a/gcc/config/arm/arm.c
> +++ b/gcc/config/arm/arm.c
> @@ -214,8 +214,8 @@ static bool arm_return_in_memory (const_tree, const_tree);
>  static void arm_unwind_emit (FILE *, rtx_insn *);
>  static bool arm_output_ttype (rtx);
>  static void arm_asm_emit_except_personality (rtx);
> -static void arm_asm_init_sections (void);
>  #endif
> +static void arm_asm_init_sections (void);
>  static rtx arm_dwarf_register_span (rtx);
>  
>  static tree arm_cxx_guard_type (void);
> @@ -299,7 +299,10 @@ static unsigned HOST_WIDE_INT arm_asan_shadow_offset (void);
>  static void arm_sched_fusion_priority (rtx_insn *, int, int *, int*);
>  static bool arm_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT,
>  				     const_tree);
> -
> +static section *arm_function_section (tree, enum node_frequency, bool, bool);
> +static bool arm_asm_elf_flags_numeric (unsigned int flags, unsigned int *num);
> +static unsigned int arm_elf_section_type_flags (tree decl, const char *name,
> +						int reloc);
>  \f
>  /* Table of machine attributes.  */
>  static const struct attribute_spec arm_attribute_table[] =
> @@ -587,8 +590,8 @@ static const struct attribute_spec arm_attribute_table[] =
>  #define TARGET_ASM_EMIT_EXCEPT_PERSONALITY arm_asm_emit_except_personality
>  
>  #undef TARGET_ASM_INIT_SECTIONS
> -#define TARGET_ASM_INIT_SECTIONS arm_asm_init_sections
>  #endif /* ARM_UNWIND_INFO */
> +#define TARGET_ASM_INIT_SECTIONS arm_asm_init_sections
>  
>  #undef TARGET_DWARF_REGISTER_SPAN
>  #define TARGET_DWARF_REGISTER_SPAN arm_dwarf_register_span
> @@ -729,6 +732,15 @@ static const struct attribute_spec arm_attribute_table[] =
>  #undef TARGET_SCHED_FUSION_PRIORITY
>  #define TARGET_SCHED_FUSION_PRIORITY arm_sched_fusion_priority
>  
> +#undef  TARGET_ASM_FUNCTION_SECTION
> +#define TARGET_ASM_FUNCTION_SECTION arm_function_section
> +
> +#undef TARGET_ASM_ELF_FLAGS_NUMERIC
> +#define TARGET_ASM_ELF_FLAGS_NUMERIC arm_asm_elf_flags_numeric
> +
> +#undef TARGET_SECTION_TYPE_FLAGS
> +#define TARGET_SECTION_TYPE_FLAGS arm_elf_section_type_flags
> +
>  struct gcc_target targetm = TARGET_INITIALIZER;
>  \f
>  /* Obstack for minipool constant handling.  */
> @@ -2815,6 +2827,17 @@ arm_option_check_internal (struct gcc_options *opts)
>        && ((!(arm_arch7 && !arm_arch_notm) && !arm_arch7em)
>  	  || (TARGET_THUMB1_P (flags) || flag_pic || TARGET_NEON)))
>      error ("-mslow-flash-data only supports non-pic code on armv7-m targets");
> +
> +#ifdef OBJECT_FORMAT_ELF
> +  /* We only support -mpure-code on Thumb-2 M-profile targets.  */
> +  if (target_pure_code
> +      && (!arm_arch_thumb2 || arm_arch_notm || flag_pic || TARGET_NEON))
> +    error ("-mpure-code only supports non-pic code on armv7-m targets");
> +#else
> +  if (target_pure_code)
> +    error ("-mpure-code is only available for the ELF object format.");
> +#endif

It looks to me as though the only reason for restricting this to ELF is
that only that object format supports a PURECODE section flag.  However,
that's not a reason to restrict the behaviour to ELF-only.  Please can
we change this to be enabled for all object formats, even if they don't
have a special marker flag.

> +
>  }
>  
>  /* Recompute the global settings depending on target attribute options.  */
> @@ -3453,8 +3476,9 @@ arm_option_override (void)
>  			 global_options.x_param_values,
>  			 global_options_set.x_param_values);
>  
> -  /* Currently, for slow flash data, we just disable literal pools.  */
> -  if (target_slow_flash_data)
> +  /* Currently, for slow flash data, we just disable literal pools.  We also
> +     disable it for -mpure-code.  */

Better to just refer to 'pure code' and not directly to the option name.
 This applies elsewhere, too.

> +  if (target_slow_flash_data || target_pure_code)
>      arm_disable_literal_pool = true;
>  
>    /* Disable scheduling fusion by default if it's not armv7 processor
> @@ -27208,17 +27232,22 @@ arm_asm_emit_except_personality (rtx personality)
>    output_addr_const (asm_out_file, personality);
>    fputc ('\n', asm_out_file);
>  }
> +#endif /* ARM_UNWIND_INFO */
>  
>  /* Implement TARGET_ASM_INITIALIZE_SECTIONS.  */
>  
>  static void
>  arm_asm_init_sections (void)
>  {
> +#if ARM_UNWIND_INFO
>    exception_section = get_unnamed_section (0, output_section_asm_op,
>  					   "\t.handlerdata");
> -}
>  #endif /* ARM_UNWIND_INFO */
>  
> +  if (target_pure_code)
> +    text_section->unnamed.data = "\t.section .text,\"0x20000006\",%progbits";
> +}
> +
>  /* Output unwind directives for the start/end of a function.  */
>  
>  void
> @@ -30529,4 +30558,113 @@ arm_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT vcall_offset,
>    return true;
>  }
>  
> +/* Implement the TARGET_ASM_ELF_FLAGS_NUMERIC hook.
> +
> +   For sections with SECTION_ARM_PURECODE flag set, make sure you pass the
> +   machine specific flag attribute when printing the numeric value.  */

The comment is confusing.  Perhaps it's better to write:

For pure-code sections there is no letter code for this attribute, so
output all the section flags numerically when this is needed.

> +
> +static bool
> +arm_asm_elf_flags_numeric (unsigned int flags, unsigned int *num)
> +{
> +
> +  if (flags & SECTION_ARM_PURECODE)
> +    {
> +      *num = 0x20000000;
> +
> +      if (!(flags & SECTION_DEBUG))
> +	*num |= 0x2;
> +#if defined (HAVE_GAS_SECTION_EXCLUDE) && HAVE_GAS_SECTION_EXCLUDE == 1
> +      if (flags & SECTION_EXCLUDE)
> +	*num |= 0x80000000;
> +#endif

Do we really need this ifdef?  Can't we assume that if our assembler
supports pure-code then it also supports the exclude attribute?

> +      if (flags & SECTION_WRITE)
> +	*num |= 0x1;
> +      if (flags & SECTION_CODE)
> +	*num |= 0x4;
> +      if (flags & SECTION_MERGE)
> +	*num |= 0x10;
> +      if (flags & SECTION_STRINGS)
> +	*num |= 0x20;
> +      if (flags & SECTION_TLS)
> +	*num |= 0x400;
> +      if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
> +	*num |= 0x200;
> +
> +	return true;
> +    }
> +
> +  return false;
> +}
> +
> +/* Implement the TARGET_ASM_FUNCTION_SECTION hook.
> +
> +   If -mpure_code is passed as an option, make sure all functions are in
> +   sections that have the SHF_ARM_PURECODE attribute.  */
> +
> +static section *
> +arm_function_section (tree decl, enum node_frequency freq,
> +		      bool startup, bool exit)
> +{
> +  const char * section_name;
> +  section * sec;
> +
> +  if (!decl || TREE_CODE (decl) != FUNCTION_DECL)
> +    return default_function_section (decl, freq, startup, exit);
> +
> +  if (!target_pure_code)
> +    return default_function_section (decl, freq, startup, exit);
> +
> +
> +  section_name = DECL_SECTION_NAME (decl);
> +
> +  /* If a function is not in a named section then it falls under the 'default'
> +     text section, also known as '.text'. We can preserve previous behavior as

Two spaces after a full stop.  There are other instances of this as well.


> +     the default text section already has the SHF_ARM_PURECODE section
> +     attribute.  */
> +  if (!section_name)
> +    {
> +      section *default_sec = default_function_section (decl, freq, startup,
> +						       exit);
> +
> +      /* If default_sec is not null, then it must be a special section like for
> +	 example .text.startup. We set the pure-code attribute and return the

Like here.

> +	 same section to preserve behavior.  */

Preserve what behaviour?  Existing?  Or some other?

> +      if (default_sec)
> +	  default_sec->common.flags |= SECTION_ARM_PURECODE;
> +      return default_sec;
> +    }
> +
> +  /* Otherwise look whether a section has already been created with
> +     'section_name'.  */
> +  sec = get_named_section (decl, section_name, 0);
> +  if (!sec)
> +    /* If that is not the case passing NULL as the name section to

s/name section/section name/ ?

> +       'get_named_section' will create a section with the declarations
> +       section name.  */
> +    sec = get_named_section (decl, NULL, 0);
> +
> +  /* Set the SHF_ARM_PURECODE attribute.  */
> +  sec->common.flags |= SECTION_ARM_PURECODE;
> +
> +  return sec;
> +}
> +
> +/* Implements the TARGET_SECTION_FLAGS hook.
> +
> +   If DECL is a function declaration and -mpure-code is passed as an option
> +   then add the SFH_ARM_PURECODE attribute to the section flags.  NAME is the
> +   sections name and RELOC indicates whether the declarations initializer may

section's

> +   contain runtime relocations.  */
> +
> +static unsigned int
> +arm_elf_section_type_flags (tree decl, const char *name, int reloc)
> +{
> +  unsigned int flags = default_section_type_flags (decl, name, reloc);
> +
> +  if (decl && TREE_CODE (decl) == FUNCTION_DECL && target_pure_code)
> +    flags |= SECTION_ARM_PURECODE;
> +
> +  return flags;
> +}
> +
>  #include "gt-arm.h"
> diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
> index 16498316bee9f19baff414885efe1e78191da047..9f49ab6014e61e7b49972f29c96ad03c11101aa1 100644
> --- a/gcc/config/arm/arm.md
> +++ b/gcc/config/arm/arm.md
> @@ -8180,7 +8180,7 @@
>     (match_operand:SI 2 "const_int_operand" "")	; total range
>     (match_operand:SI 3 "" "")			; table label
>     (match_operand:SI 4 "" "")]			; Out of range label
> -  "TARGET_32BIT || optimize_size || flag_pic"
> +  "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
>    "
>    {
>      enum insn_code code;
> diff --git a/gcc/config/arm/arm.opt b/gcc/config/arm/arm.opt
> index 0ebe0174390167b79a64583c35a3f8fb018f6538..6c142d9fc6bee9d5ec30f7a25bd017e8bc02b801 100644
> --- a/gcc/config/arm/arm.opt
> +++ b/gcc/config/arm/arm.opt
> @@ -281,3 +281,9 @@ Assume loading data from flash is slower than fetching instructions.
>  masm-syntax-unified
>  Target Report Var(inline_asm_unified) Init(0) Save
>  Assume unified syntax for inline assembly code.
> +
> +mpure-code
> +Target Report Var(target_pure_code) Init(0)
> +Generate assembly which places functions in sections that contain only code.
> +This requires that no literal pools are generated for such
> +functions and that jump tables are not put in the same section.

I think this should read something like:

  Do not allow constant data to placed in code sections.

For the short help from the compiler that's more than enough to remind a
user what the option does.

> diff --git a/gcc/config/arm/elf.h b/gcc/config/arm/elf.h
> index 77f30554d5286bd83aeab0c8dc308cfd44e732dc..395a22282be0cd2edc9459e1ba14d7848073fa5d 100644
> --- a/gcc/config/arm/elf.h
> +++ b/gcc/config/arm/elf.h
> @@ -104,7 +104,8 @@
>     the code more efficient, but for Thumb-1 it's better to put them out of
>     band unless we are generating compressed tables.  */
>  #define JUMP_TABLES_IN_TEXT_SECTION					\
> -   (TARGET_32BIT || (TARGET_THUMB && (optimize_size || flag_pic)))
> +   ((TARGET_32BIT || (TARGET_THUMB && (optimize_size || flag_pic))) \
> +    && !target_pure_code)
>  
>  #ifndef LINK_SPEC
>  #define LINK_SPEC "%{mbig-endian:-EB} %{mlittle-endian:-EL} -X"
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 4f24daebc01f0fd006540df8d863014aa864d060..faeb4299acc1f0859eafa3e13cf4b24c4d0224d6 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -639,7 +639,8 @@ Objective-C and Objective-C++ Dialects}.
>  -mneon-for-64bits @gol
>  -mslow-flash-data @gol
>  -masm-syntax-unified @gol
> --mrestrict-it}
> +-mrestrict-it @gol
> +-mpure-code}
>  
>  @emph{AVR Options}
>  @gccoptlist{-mmcu=@var{mcu} -maccumulate-args -mbranch-cost=@var{cost} @gol
> @@ -14498,6 +14499,14 @@ Print CPU tuning information as comment in assembler file.  This is
>  an option used only for regression testing of the compiler and not
>  intended for ordinary use in compiling code.  This option is disabled
>  by default.
> +
> +@item -mpure-code
> +@opindex mpure-code
> +Generate assembly where instructions and data are in separate sections.

This should probably be the same text as the help option.

> +Additionally, give all text sections the ELF processor-specific section
> +attribute SHF_ARM_PURECODE.  This option is only available when generating
> +non-pic code in ELF object format for ARMv7-M targets.

And this bit will need re-wording for the other changes.

> +
>  @end table
>  
>  @node AVR Options
> diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
> index b318615b7b35ab93ad13e5e535a1d4e6d02cb7f7..c9e1489a0453845a2bffb2df514cc3b5b73933dc 100644
> --- a/gcc/doc/tm.texi
> +++ b/gcc/doc/tm.texi
> @@ -7543,6 +7543,15 @@ is non-NULL, it is the @code{VAR_DECL} or @code{FUNCTION_DECL} with which
>  this section is associated.
>  @end deftypefn
>  
> +@deftypefn {Target Hook} bool TARGET_ASM_ELF_FLAGS_NUMERIC (unsigned int @var{flags}, unsigned int *@var{num})
> +If the target needs to represent ELF section attributes using their
> +numerical value, then this hook should be implemented to return true and
> +write the numerical value of @var{flags} in @var{num}.  This function is
> +called by @code{default_elf_asm_named_section}, which prints @var{num}
> +as the value representing the ELF section attributes if this function
> +returns true.
> +@end deftypefn
> +
>  @deftypefn {Target Hook} {section *} TARGET_ASM_FUNCTION_SECTION (tree @var{decl}, enum node_frequency @var{freq}, bool @var{startup}, bool @var{exit})
>  Return preferred text (sub)section for function @var{decl}.
>  Main purpose of this function is to separate cold, normal and hot
> diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
> index 1e8423cb4e255acd8144e4b105186cee3d1d04fd..17a2ca73f07516526543253c77c088c73326af2c 100644
> --- a/gcc/doc/tm.texi.in
> +++ b/gcc/doc/tm.texi.in
> @@ -5229,6 +5229,8 @@ of the filename using this macro.
>  
>  @hook TARGET_ASM_NAMED_SECTION
>  
> +@hook TARGET_ASM_ELF_FLAGS_NUMERIC
> +
>  @hook TARGET_ASM_FUNCTION_SECTION
>  
>  @hook TARGET_ASM_FUNCTION_SWITCHED_TEXT_SECTIONS
> diff --git a/gcc/hooks.c b/gcc/hooks.c
> index 99ec4014adb6fcbb073bf538dd00fe8695ee6cb2..1e925645c3173f8d97e104b9b2f480fca2ede438 100644
> --- a/gcc/hooks.c
> +++ b/gcc/hooks.c
> @@ -481,3 +481,13 @@ void
>  hook_void_gcc_optionsp (struct gcc_options *opts ATTRIBUTE_UNUSED)
>  {
>  }
> +
> +/* Generic hook that takes an unsigned int, an unsigned int pointer and
> +   returns false.  */
> +
> +bool
> +hook_uint_uintp_false (unsigned int, unsigned int *)
> +{
> +  return false;
> +}
> +
> diff --git a/gcc/target.def b/gcc/target.def
> index a4df363698ce776b51d11c187baed2069ba88a52..a3d46fa48d919a16699c33b2b78236e62a33e025 100644
> --- a/gcc/target.def
> +++ b/gcc/target.def
> @@ -432,6 +432,19 @@ this section is associated.",
>   void, (const char *name, unsigned int flags, tree decl),
>   default_no_named_section)
>  
> +/* Tell assembler what section attributes to assign this elf section
> +   declaration, using their numerical value.  */
> +DEFHOOK
> +(elf_flags_numeric,
> + "If the target needs to represent ELF section attributes using their\n\
> +numerical value, then this hook should be implemented to return true and\n\
> +write the numerical value of @var{flags} in @var{num}.  This function is\n\
> +called by @code{default_elf_asm_named_section}, which prints @var{num}\n\
> +as the value representing the ELF section attributes if this function\n\
> +returns true.",


I think this should read something like.

This hook can be used to encode ELF section flags for which no letter
code has been defined in the assembler.  It is called by
@code{default_asm_named_section} whenever the section flags need to be
emitted in the assembler output.  If the hook returns true, then the
numerical value for ELF section flags should be calculated from
@var{flags} and saved in @var{*num}; the value will be printed out
instead of the normal sequence of letter codes.  If the hook is not
defined, or if it returns false, then @var{num} will be ignored and the
traditional letter sequence will be emitted.


> + bool, (unsigned int flags, unsigned int *num),
> + hook_uint_uintp_false)
> +
>  /* Return preferred text (sub)section for function DECL.
>     Main purpose of this function is to separate cold, normal and hot
>     functions. STARTUP is true when function is known to be used only 
> diff --git a/gcc/targhooks.h b/gcc/targhooks.h
> index d6581cfab893e0da619c6bc0f98ff722a7ab4404..19ad97fa453cf6102b1502f97d8b66fe413284ee 100644
> --- a/gcc/targhooks.h
> +++ b/gcc/targhooks.h
> @@ -254,5 +254,4 @@ extern void default_setup_incoming_vararg_bounds (cumulative_args_t ca ATTRIBUTE
>  						  int second_time ATTRIBUTE_UNUSED);
>  extern bool default_optab_supported_p (int, machine_mode, machine_mode,
>  				       optimization_type);
> -
>  #endif /* GCC_TARGHOOKS_H */
> diff --git a/gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c b/gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..26fe38c05295b70ccc35ed900d41b34aae2c87a8
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-fpic" "-fPIC" } { "" } } */
> +/* { dg-options "-ffunction-sections -mpure-code" } */
> +#include <limits.h>
> +
> +char * foo (void)
> +{
> +  return "foo";
> +}
> +
> +unsigned int bar (unsigned int b)
> +{
> +  return UINT_MAX - b;
> +}
> +
> +/* { dg-final { scan-assembler {\.section\t\.text\.foo[^\n]*\"0x20000006\"} } } */
> +/* { dg-final { scan-assembler {\.section\t\.text\.bar[^\n]*\"0x20000006\"} } } */
> diff --git a/gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c b/gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..ba116a8261b16610e6af47d26a6e1a07b0127561
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c
> @@ -0,0 +1,29 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mpure-code" } */
> +/* { dg-skip-if "" { *-*-* } { "-g" "-fpic" "-fPIC" } { "" } } */
> +
> +extern int foo (void);
> +extern int bar (void);
> +extern int baz (void);
> +extern int fooz (void);
> +
> +int caller (unsigned int reg_type)
> +{
> +  switch (reg_type)
> +    {
> +    case 0x80000000:
> +      return (int) foo ();
> +
> +    case 0x80000003:
> +      return (int) bar ();
> +
> +    case 0x80000001:
> +      return (int) baz ();
> +
> +    case 0x80000004:
> +      return (int) fooz ();
> +    }
> +}
> +
> +/* { dg-final { scan-assembler-not "\\.(float|l\\?double|\d?byte|short|int|long|quad|word)\\s+\[^.\]" } } */
> +/* { dg-final { scan-assembler "text,\"0x20000006\"" } } */
> diff --git a/gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c b/gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..4b893fd32f722e6cd7dfde5c8542ab98327ba375
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mpure-code" } */
> +/* { dg-skip-if "" { *-*-* } { "-g" "-fpic" "-fPIC" } { "" } } */
> +
> +float sf;
> +double df;
> +long long l;
> +static char *p = "Hello World";
> +
> +float
> +testsf (float *p)
> +{
> +  if (*p > 1.1234f)
> +    return 2.1234f;
> +  else
> +    return 3.1234f;
> +}
> +
> +double
> +testdf (double *p)
> +{
> +  if (*p > 4.1234)
> +    return 2.1234;
> +  else
> +    return 3.1234;
> +}
> +
> +long long
> +testll (long long *p)
> +{
> +  if (*p > 0x123456789ABCDEFll)
> +    return 0x111111111ll;
> +  else
> +    return 0x222222222ll;
> +}
> +
> +char *
> +testchar ()
> +{
> +  return p + 4;
> +}
> +
> +int
> +foo (int a, int b)
> +{
> +  int i;
> +  volatile int *labelref = &&label1;
> +
> +  if (a > b)
> +    {
> +      while (i < b)
> +	{
> +	  a += *labelref;
> +	  i += 1;
> +	}
> +      goto *labelref;
> +    }
> +  else
> +    b = b + 3;
> +
> +  a = a * b;
> +
> +label1:
> +  return a + b;
> +}
> +
> +/* { dg-final { scan-assembler-not "\\.(float|l\\?double|\d?byte|short|int|long|quad|word)\\s+\[^.\]" } } */
> +/* { dg-final { scan-assembler "text,\"0x20000006\"" } } */
> diff --git a/gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp b/gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp
> new file mode 100644
> index 0000000000000000000000000000000000000000..1abe7782c0e5dbb6e2deef25f4bea9415664f942
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp
> @@ -0,0 +1,54 @@
> +#   Copyright (C) 1997-2016 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
> +# <http://www.gnu.org/licenses/>.
> +
> +# GCC testsuite for ARM's -mpure-code option, using the `dg.exp' driver.
> +
> +# 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"
> +}
> +
> +# The -mpure-code option is only available for M-profile targets that support
> +# thumb2.
> +if {[check_effective_target_arm_thumb2_ok]
> +    && ![check_effective_target_arm_arm_ok]} then {
> +# Initialize `dg'.
> +dg-init
> +
> +set saved-dg-do-what-default ${dg-do-what-default}
> +set dg-do-what-default "assemble"
> +
> +set saved-lto_torture_options ${LTO_TORTURE_OPTIONS}
> +
> +# Add -ffat-lto-objects option to all LTO options such that we can do assembly
> +# scans.
> +proc add_fat_objects { list } {
> +    set res {}
> +    foreach el $list {set res [lappend res [concat $el " -ffat-lto-objects"]]}
> +    return $res
> +};
> +set LTO_TORTURE_OPTIONS [add_fat_objects ${LTO_TORTURE_OPTIONS}]
> +
> +gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] \
> +	"" $DEFAULT_CFLAGS
> +
> +# All done.
> +dg-finish
> +}
> diff --git a/gcc/varasm.c b/gcc/varasm.c
> index de8bcd6f20c823acd03991f813da3521b80547ff..13007d8c1ce2d094633422abeb01d91b1e986ac4 100644
> --- a/gcc/varasm.c
> +++ b/gcc/varasm.c
> @@ -6244,6 +6244,7 @@ default_elf_asm_named_section (const char *name, unsigned int flags,
>  			       tree decl)
>  {
>    char flagchars[11], *f = flagchars;
> +  unsigned int numeric_value;

I think this should be initialized to zero, rather than assuming the
hook caller will do that for you.

>  
>    /* If we have already declared this section, we can use an
>       abbreviated form to switch back to it -- unless this section is
> @@ -6256,31 +6257,38 @@ default_elf_asm_named_section (const char *name, unsigned int flags,
>        return;
>      }
>  
> -  if (!(flags & SECTION_DEBUG))
> -    *f++ = 'a';
> +  /* If we have a machine specific flag, then use the numeric value to pass
> +     this on to GAS.  */
> +  if (targetm.asm_out.elf_flags_numeric (flags, &numeric_value))
> +      snprintf (f, sizeof (flagchars), "0x%08x", numeric_value);
> +  else
> +    {
> +      if (!(flags & SECTION_DEBUG))
> +	*f++ = 'a';
>  #if defined (HAVE_GAS_SECTION_EXCLUDE) && HAVE_GAS_SECTION_EXCLUDE == 1
> -  if (flags & SECTION_EXCLUDE)
> -    *f++ = 'e';
> +      if (flags & SECTION_EXCLUDE)
> +	*f++ = 'e';
>  #endif
> -  if (flags & SECTION_WRITE)
> -    *f++ = 'w';
> -  if (flags & SECTION_CODE)
> -    *f++ = 'x';
> -  if (flags & SECTION_SMALL)
> -    *f++ = 's';
> -  if (flags & SECTION_MERGE)
> -    *f++ = 'M';
> -  if (flags & SECTION_STRINGS)
> -    *f++ = 'S';
> -  if (flags & SECTION_TLS)
> -    *f++ = TLS_SECTION_ASM_FLAG;
> -  if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
> -    *f++ = 'G';
> +      if (flags & SECTION_WRITE)
> +	*f++ = 'w';
> +      if (flags & SECTION_CODE)
> +	*f++ = 'x';
> +      if (flags & SECTION_SMALL)
> +	*f++ = 's';
> +      if (flags & SECTION_MERGE)
> +	*f++ = 'M';
> +      if (flags & SECTION_STRINGS)
> +	*f++ = 'S';
> +      if (flags & SECTION_TLS)
> +	*f++ = TLS_SECTION_ASM_FLAG;
> +      if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
> +	*f++ = 'G';
>  #ifdef MACH_DEP_SECTION_ASM_FLAG
> -  if (flags & SECTION_MACH_DEP)
> -    *f++ = MACH_DEP_SECTION_ASM_FLAG;
> +      if (flags & SECTION_MACH_DEP)
> +	*f++ = MACH_DEP_SECTION_ASM_FLAG;
>  #endif
> -  *f = '\0';
> +      *f = '\0';
> +    }
>  
>    fprintf (asm_out_file, "\t.section\t%s,\"%s\"", name, flagchars);
>  
> 

R.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCHv3][ARM] -mpure-code option for ARM
  2016-09-22 14:22     ` [PATCHv2][ARM] " Richard Earnshaw (lists)
@ 2016-09-22 15:10       ` Andre Vieira (lists)
  2016-09-22 15:47         ` Richard Earnshaw (lists)
  2016-09-23 13:47         ` [PATCH, arm-embedded] " Andre Vieira (lists)
  2016-09-23  6:31       ` [PATCHv2][ARM] " Sandra Loosemore
  1 sibling, 2 replies; 24+ messages in thread
From: Andre Vieira (lists) @ 2016-09-22 15:10 UTC (permalink / raw)
  To: gcc-patches; +Cc: Richard Earnshaw

[-- Attachment #1: Type: text/plain, Size: 35172 bytes --]

On 22/09/16 14:52, Richard Earnshaw (lists) wrote:
> On 11/07/16 17:56, Andre Vieira (lists) wrote:
>> On 07/07/16 13:30, mickael guene wrote:
>>> Hi Andre,
>>>
>>>  Another feedback on your purecode patch.
>>>  You have to disable casesi pattern since then it will
>>> generate wrong code with -mpure-code option.
>>>  Indeed it will generate an 'adr rx, .Lx' (aka
>>> 'subs rx, PC, #offset') which will not work in our
>>> case since 'Lx' label is put in an .rodata section.
>>> So offset value is unknown and can be impossible
>>> to encode correctly.
>>>
>>> Regards
>>> Mickael
>>>
>>> On 06/30/2016 04:32 PM, Andre Vieira (lists) wrote:
>>>> Hello,
>>>>
>>>> This patch adds the -mpure-code option for ARM. This option ensures
>>>> functions are put into sections that contain only code and no data. To
>>>> ensure this throughout compilation we give these sections the ARM
>>>> processor-specific ELF section attribute "SHF_ARM_PURECODE". This option
>>>> is only supported for non-pic code for armv7-m targets.
>>>>
>>>> This patch introduces a new target hook 'TARGET_ASM_ELF_FLAGS_NUMERIC'.
>>>> This target hook enables a target to use the numeric value for elf
>>>> section attributes rather than their alphabetical representation. If
>>>> TARGET_ASM_ELF_FLAGS_NUMERIC returns TRUE, the existing
>>>> 'default_elf_asm_named_section', will print the numeric value of the
>>>> section attributes for the current section. This target hook has two
>>>> parameters:
>>>> unsigned int FLAGS, the input parameter that tells the function the
>>>> current section's attributes;
>>>> unsigned int *NUM, used to pass down the numerical representation of the
>>>> section's attributes.
>>>>
>>>> The default implementation for TARGET_ASM_ELF_FLAGS_NUMERIC will return
>>>> false, so existing behavior is not changed.
>>>>
>>>> Bootstrapped and tested for arm-none-linux-gnueabihf. Further tested for
>>>> arm-none-eabi with a Cortex-M3 target.
>>>>
>>>>
>>>> gcc/ChangeLog:
>>>> 2016-06-30  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>>>             Terry Guo  <terry.guo@arm.com>
>>>>
>>>>         * target.def (elf_flags_numeric): New target hook.
>>>>         * targhooks.h (default_asm_elf_flags_numeric): New.
>>>>         * varasm.c (default_asm_elf_flags_numeric): New.
>>>>           (default_elf_asm_named_section): Use new target hook.
>>>>         * config/arm/arm.opt (mpure-code): New.
>>>>         * config/arm/arm.h (SECTION_ARM_PURECODE): New.
>>>>         * config/arm/arm.c (arm_asm_init_sections): Add section
>>>>           attribute to default text section if -mpure-code.
>>>>           (arm_option_check_internal): Diagnose use of option with
>>>>           non supported targets and/or options.
>>>>           (arm_asm_elf_flags_numeric): New.
>>>>           (arm_function_section): New.
>>>>           (arm_elf_section_type_flags): New.
>>>>         * config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Disable
>>>>           for -mpure-code.
>>>>         * gcc/doc/texi (TARGET_ASM_ELF_FLAGS_NUMERIC): New.
>>>>         * gcc/doc/texi.in (TARGET_ASM_ELF_FLAGS_NUMERIC): Likewise.
>>>>
>>>>
>>>>
>>>> gcc/testsuite/ChangeLog:
>>>> 2016-06-30  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>>>             Terry Guo  <terry.guo@arm.com>
>>>>
>>>>         * gcc.target/arm/pure-code/ffunction-sections.c: New.
>>>>         * gcc.target/arm/pure-code/no-literal-pool.c: New.
>>>>         * gcc.target/arm/pure-code/pure-code.exp: New.
>>>>
>>>
>> Hi Sandra, Mickael,
>>
>> Thank you for your comments. I changed the description of -mpure-code in
>> invoke.texi to better reflect the error message you get wrt supported
>> targets.
>>
>> As for the target hook description, I hope the text is clearer now. Let
>> me know if you think it needs further explanation.
>>
>> I also fixed the double '%' in the text string for unnamed text sections
>> and disabled the casesi pattern.
>>
>> I duplicated the original casesi test
>> 'gcc/testsuite/gcc.c-torture/compile/pr46934.c' for pure-code to make
>> sure the casesi was disabled and other patterns were selected instead.
>>
>> Reran regressions for pure-code.exp for Cortex-M3.
>>
>> Cheers,
>> Andre
>>
>>
>> gcc/ChangeLog:
>> 2016-07-11  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>             Terry Guo  <terry.guo@arm.com>
>>
>>         * target.def (elf_flags_numeric): New target hook.
>>         * hooks.c (hook_uint_uintp_false): New generic hook.
>>         * varasm.c (default_elf_asm_named_section): Use new target hook.
>>         * config/arm/arm.opt (mpure-code): New.
>>         * config/arm/arm.h (SECTION_ARM_PURECODE): New.
>>         * config/arm/arm.c (arm_asm_init_sections): Add section
>>         attribute to default text section if -mpure-code.
>>         (arm_option_check_internal): Diagnose use of option with
>>         non supported targets and/or options.
>>         (arm_asm_elf_flags_numeric): New.
>>         (arm_function_section): New.
>>         (arm_elf_section_type_flags): New.
>>         * config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Disable
>>         for -mpure-code.
>>         * config/arm/arm.md (casesi): Disable pattern for
>>         -mpure-code.
>>         * gcc/doc/texi (TARGET_ASM_ELF_FLAGS_NUMERIC): New.
>>         * gcc/doc/texi.in (TARGET_ASM_ELF_FLAGS_NUMERIC): Likewise.
>>
>>
>>
>> gcc/testsuite/ChangeLog:
>> 2016-07-11  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>             Terry Guo  <terry.guo@arm.com>
>>
>>         * gcc.target/arm/pure-code/ffunction-sections.c: New.
>>         * gcc.target/arm/pure-code/no-literal-pool.c: New.
>>         * gcc.target/arm/pure-code/no-casesi.c: New.
>>         * gcc.target/arm/pure-code/pure-code.exp: New.
>>
>>
>> 0001-mpure-code-for-ARM.patch
>>
>>
>> diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
>> index f0cdd669191689bc5dcf3a7c2b60da5a2d201e3f..d10605cee0e6e0e07bbb4e1910d30c91443f8d17 100644
>> --- a/gcc/config/arm/arm.h
>> +++ b/gcc/config/arm/arm.h
>> @@ -2263,4 +2263,8 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
>>  /* For switching between functions with different target attributes.  */
>>  #define SWITCHABLE_TARGET 1
>>  
>> +/* Define SECTION_ARM_PURECODE as the ARM specific section attribute
>> +   representation for SHF_ARM_PURECODE in GCC.  */
>> +#define SECTION_ARM_PURECODE SECTION_MACH_DEP
>> +
>>  #endif /* ! GCC_ARM_H */
>> From b35a27e363a6123c6c50bd29e284c89f6ae434a5 Mon Sep 17 00:00:00 2001
>> From: Andre Simoes Dias Vieira <andsim01@arm.com>
>> Date: Tue, 14 Jun 2016 11:17:12 +0100
>> Subject: [PATCH] -mpure-code for ARM
>>
>> ---
>>  gcc/config/arm/arm.c                               | 150 ++++++++++++++++++++-
>>  gcc/config/arm/arm.h                               |   4 +
>>  gcc/config/arm/arm.md                              |   2 +-
>>  gcc/config/arm/arm.opt                             |   6 +
>>  gcc/config/arm/elf.h                               |   3 +-
>>  gcc/doc/invoke.texi                                |  11 +-
>>  gcc/doc/tm.texi                                    |   9 ++
>>  gcc/doc/tm.texi.in                                 |   2 +
>>  gcc/hooks.c                                        |  10 ++
>>  gcc/target.def                                     |  13 ++
>>  gcc/targhooks.h                                    |   1 -
>>  .../gcc.target/arm/pure-code/ffunction-sections.c  |  17 +++
>>  gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c |  29 ++++
>>  .../gcc.target/arm/pure-code/no-literal-pool.c     |  68 ++++++++++
>>  .../gcc.target/arm/pure-code/pure-code.exp         |  54 ++++++++
>>  gcc/varasm.c                                       |  50 ++++---
>>  16 files changed, 398 insertions(+), 31 deletions(-)
>>  create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c
>>  create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c
>>  create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c
>>  create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp
>>
>> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
>> index f60955438d6f1cc5d996e7eacd4b453213044181..9b5013a069235d18eebc10a312e364de9f756906 100644
>> --- a/gcc/config/arm/arm.c
>> +++ b/gcc/config/arm/arm.c
>> @@ -214,8 +214,8 @@ static bool arm_return_in_memory (const_tree, const_tree);
>>  static void arm_unwind_emit (FILE *, rtx_insn *);
>>  static bool arm_output_ttype (rtx);
>>  static void arm_asm_emit_except_personality (rtx);
>> -static void arm_asm_init_sections (void);
>>  #endif
>> +static void arm_asm_init_sections (void);
>>  static rtx arm_dwarf_register_span (rtx);
>>  
>>  static tree arm_cxx_guard_type (void);
>> @@ -299,7 +299,10 @@ static unsigned HOST_WIDE_INT arm_asan_shadow_offset (void);
>>  static void arm_sched_fusion_priority (rtx_insn *, int, int *, int*);
>>  static bool arm_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT,
>>  				     const_tree);
>> -
>> +static section *arm_function_section (tree, enum node_frequency, bool, bool);
>> +static bool arm_asm_elf_flags_numeric (unsigned int flags, unsigned int *num);
>> +static unsigned int arm_elf_section_type_flags (tree decl, const char *name,
>> +						int reloc);
>>  \f
>>  /* Table of machine attributes.  */
>>  static const struct attribute_spec arm_attribute_table[] =
>> @@ -587,8 +590,8 @@ static const struct attribute_spec arm_attribute_table[] =
>>  #define TARGET_ASM_EMIT_EXCEPT_PERSONALITY arm_asm_emit_except_personality
>>  
>>  #undef TARGET_ASM_INIT_SECTIONS
>> -#define TARGET_ASM_INIT_SECTIONS arm_asm_init_sections
>>  #endif /* ARM_UNWIND_INFO */
>> +#define TARGET_ASM_INIT_SECTIONS arm_asm_init_sections
>>  
>>  #undef TARGET_DWARF_REGISTER_SPAN
>>  #define TARGET_DWARF_REGISTER_SPAN arm_dwarf_register_span
>> @@ -729,6 +732,15 @@ static const struct attribute_spec arm_attribute_table[] =
>>  #undef TARGET_SCHED_FUSION_PRIORITY
>>  #define TARGET_SCHED_FUSION_PRIORITY arm_sched_fusion_priority
>>  
>> +#undef  TARGET_ASM_FUNCTION_SECTION
>> +#define TARGET_ASM_FUNCTION_SECTION arm_function_section
>> +
>> +#undef TARGET_ASM_ELF_FLAGS_NUMERIC
>> +#define TARGET_ASM_ELF_FLAGS_NUMERIC arm_asm_elf_flags_numeric
>> +
>> +#undef TARGET_SECTION_TYPE_FLAGS
>> +#define TARGET_SECTION_TYPE_FLAGS arm_elf_section_type_flags
>> +
>>  struct gcc_target targetm = TARGET_INITIALIZER;
>>  \f
>>  /* Obstack for minipool constant handling.  */
>> @@ -2815,6 +2827,17 @@ arm_option_check_internal (struct gcc_options *opts)
>>        && ((!(arm_arch7 && !arm_arch_notm) && !arm_arch7em)
>>  	  || (TARGET_THUMB1_P (flags) || flag_pic || TARGET_NEON)))
>>      error ("-mslow-flash-data only supports non-pic code on armv7-m targets");
>> +
>> +#ifdef OBJECT_FORMAT_ELF
>> +  /* We only support -mpure-code on Thumb-2 M-profile targets.  */
>> +  if (target_pure_code
>> +      && (!arm_arch_thumb2 || arm_arch_notm || flag_pic || TARGET_NEON))
>> +    error ("-mpure-code only supports non-pic code on armv7-m targets");
>> +#else
>> +  if (target_pure_code)
>> +    error ("-mpure-code is only available for the ELF object format.");
>> +#endif
> 
> It looks to me as though the only reason for restricting this to ELF is
> that only that object format supports a PURECODE section flag.  However,
> that's not a reason to restrict the behaviour to ELF-only.  Please can
> we change this to be enabled for all object formats, even if they don't
> have a special marker flag.
> 
>> +
>>  }
>>  
>>  /* Recompute the global settings depending on target attribute options.  */
>> @@ -3453,8 +3476,9 @@ arm_option_override (void)
>>  			 global_options.x_param_values,
>>  			 global_options_set.x_param_values);
>>  
>> -  /* Currently, for slow flash data, we just disable literal pools.  */
>> -  if (target_slow_flash_data)
>> +  /* Currently, for slow flash data, we just disable literal pools.  We also
>> +     disable it for -mpure-code.  */
> 
> Better to just refer to 'pure code' and not directly to the option name.
>  This applies elsewhere, too.
> 
>> +  if (target_slow_flash_data || target_pure_code)
>>      arm_disable_literal_pool = true;
>>  
>>    /* Disable scheduling fusion by default if it's not armv7 processor
>> @@ -27208,17 +27232,22 @@ arm_asm_emit_except_personality (rtx personality)
>>    output_addr_const (asm_out_file, personality);
>>    fputc ('\n', asm_out_file);
>>  }
>> +#endif /* ARM_UNWIND_INFO */
>>  
>>  /* Implement TARGET_ASM_INITIALIZE_SECTIONS.  */
>>  
>>  static void
>>  arm_asm_init_sections (void)
>>  {
>> +#if ARM_UNWIND_INFO
>>    exception_section = get_unnamed_section (0, output_section_asm_op,
>>  					   "\t.handlerdata");
>> -}
>>  #endif /* ARM_UNWIND_INFO */
>>  
>> +  if (target_pure_code)
>> +    text_section->unnamed.data = "\t.section .text,\"0x20000006\",%progbits";
>> +}
>> +
>>  /* Output unwind directives for the start/end of a function.  */
>>  
>>  void
>> @@ -30529,4 +30558,113 @@ arm_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT vcall_offset,
>>    return true;
>>  }
>>  
>> +/* Implement the TARGET_ASM_ELF_FLAGS_NUMERIC hook.
>> +
>> +   For sections with SECTION_ARM_PURECODE flag set, make sure you pass the
>> +   machine specific flag attribute when printing the numeric value.  */
> 
> The comment is confusing.  Perhaps it's better to write:
> 
> For pure-code sections there is no letter code for this attribute, so
> output all the section flags numerically when this is needed.
> 
>> +
>> +static bool
>> +arm_asm_elf_flags_numeric (unsigned int flags, unsigned int *num)
>> +{
>> +
>> +  if (flags & SECTION_ARM_PURECODE)
>> +    {
>> +      *num = 0x20000000;
>> +
>> +      if (!(flags & SECTION_DEBUG))
>> +	*num |= 0x2;
>> +#if defined (HAVE_GAS_SECTION_EXCLUDE) && HAVE_GAS_SECTION_EXCLUDE == 1
>> +      if (flags & SECTION_EXCLUDE)
>> +	*num |= 0x80000000;
>> +#endif
> 
> Do we really need this ifdef?  Can't we assume that if our assembler
> supports pure-code then it also supports the exclude attribute?
> 
>> +      if (flags & SECTION_WRITE)
>> +	*num |= 0x1;
>> +      if (flags & SECTION_CODE)
>> +	*num |= 0x4;
>> +      if (flags & SECTION_MERGE)
>> +	*num |= 0x10;
>> +      if (flags & SECTION_STRINGS)
>> +	*num |= 0x20;
>> +      if (flags & SECTION_TLS)
>> +	*num |= 0x400;
>> +      if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
>> +	*num |= 0x200;
>> +
>> +	return true;
>> +    }
>> +
>> +  return false;
>> +}
>> +
>> +/* Implement the TARGET_ASM_FUNCTION_SECTION hook.
>> +
>> +   If -mpure_code is passed as an option, make sure all functions are in
>> +   sections that have the SHF_ARM_PURECODE attribute.  */
>> +
>> +static section *
>> +arm_function_section (tree decl, enum node_frequency freq,
>> +		      bool startup, bool exit)
>> +{
>> +  const char * section_name;
>> +  section * sec;
>> +
>> +  if (!decl || TREE_CODE (decl) != FUNCTION_DECL)
>> +    return default_function_section (decl, freq, startup, exit);
>> +
>> +  if (!target_pure_code)
>> +    return default_function_section (decl, freq, startup, exit);
>> +
>> +
>> +  section_name = DECL_SECTION_NAME (decl);
>> +
>> +  /* If a function is not in a named section then it falls under the 'default'
>> +     text section, also known as '.text'. We can preserve previous behavior as
> 
> Two spaces after a full stop.  There are other instances of this as well.
> 
> 
>> +     the default text section already has the SHF_ARM_PURECODE section
>> +     attribute.  */
>> +  if (!section_name)
>> +    {
>> +      section *default_sec = default_function_section (decl, freq, startup,
>> +						       exit);
>> +
>> +      /* If default_sec is not null, then it must be a special section like for
>> +	 example .text.startup. We set the pure-code attribute and return the
> 
> Like here.
> 
>> +	 same section to preserve behavior.  */
> 
> Preserve what behaviour?  Existing?  Or some other?
> 
>> +      if (default_sec)
>> +	  default_sec->common.flags |= SECTION_ARM_PURECODE;
>> +      return default_sec;
>> +    }
>> +
>> +  /* Otherwise look whether a section has already been created with
>> +     'section_name'.  */
>> +  sec = get_named_section (decl, section_name, 0);
>> +  if (!sec)
>> +    /* If that is not the case passing NULL as the name section to
> 
> s/name section/section name/ ?
> 
>> +       'get_named_section' will create a section with the declarations
>> +       section name.  */
>> +    sec = get_named_section (decl, NULL, 0);
>> +
>> +  /* Set the SHF_ARM_PURECODE attribute.  */
>> +  sec->common.flags |= SECTION_ARM_PURECODE;
>> +
>> +  return sec;
>> +}
>> +
>> +/* Implements the TARGET_SECTION_FLAGS hook.
>> +
>> +   If DECL is a function declaration and -mpure-code is passed as an option
>> +   then add the SFH_ARM_PURECODE attribute to the section flags.  NAME is the
>> +   sections name and RELOC indicates whether the declarations initializer may
> 
> section's
> 
>> +   contain runtime relocations.  */
>> +
>> +static unsigned int
>> +arm_elf_section_type_flags (tree decl, const char *name, int reloc)
>> +{
>> +  unsigned int flags = default_section_type_flags (decl, name, reloc);
>> +
>> +  if (decl && TREE_CODE (decl) == FUNCTION_DECL && target_pure_code)
>> +    flags |= SECTION_ARM_PURECODE;
>> +
>> +  return flags;
>> +}
>> +
>>  #include "gt-arm.h"
>> diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
>> index 16498316bee9f19baff414885efe1e78191da047..9f49ab6014e61e7b49972f29c96ad03c11101aa1 100644
>> --- a/gcc/config/arm/arm.md
>> +++ b/gcc/config/arm/arm.md
>> @@ -8180,7 +8180,7 @@
>>     (match_operand:SI 2 "const_int_operand" "")	; total range
>>     (match_operand:SI 3 "" "")			; table label
>>     (match_operand:SI 4 "" "")]			; Out of range label
>> -  "TARGET_32BIT || optimize_size || flag_pic"
>> +  "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
>>    "
>>    {
>>      enum insn_code code;
>> diff --git a/gcc/config/arm/arm.opt b/gcc/config/arm/arm.opt
>> index 0ebe0174390167b79a64583c35a3f8fb018f6538..6c142d9fc6bee9d5ec30f7a25bd017e8bc02b801 100644
>> --- a/gcc/config/arm/arm.opt
>> +++ b/gcc/config/arm/arm.opt
>> @@ -281,3 +281,9 @@ Assume loading data from flash is slower than fetching instructions.
>>  masm-syntax-unified
>>  Target Report Var(inline_asm_unified) Init(0) Save
>>  Assume unified syntax for inline assembly code.
>> +
>> +mpure-code
>> +Target Report Var(target_pure_code) Init(0)
>> +Generate assembly which places functions in sections that contain only code.
>> +This requires that no literal pools are generated for such
>> +functions and that jump tables are not put in the same section.
> 
> I think this should read something like:
> 
>   Do not allow constant data to placed in code sections.
> 
> For the short help from the compiler that's more than enough to remind a
> user what the option does.
> 
>> diff --git a/gcc/config/arm/elf.h b/gcc/config/arm/elf.h
>> index 77f30554d5286bd83aeab0c8dc308cfd44e732dc..395a22282be0cd2edc9459e1ba14d7848073fa5d 100644
>> --- a/gcc/config/arm/elf.h
>> +++ b/gcc/config/arm/elf.h
>> @@ -104,7 +104,8 @@
>>     the code more efficient, but for Thumb-1 it's better to put them out of
>>     band unless we are generating compressed tables.  */
>>  #define JUMP_TABLES_IN_TEXT_SECTION					\
>> -   (TARGET_32BIT || (TARGET_THUMB && (optimize_size || flag_pic)))
>> +   ((TARGET_32BIT || (TARGET_THUMB && (optimize_size || flag_pic))) \
>> +    && !target_pure_code)
>>  
>>  #ifndef LINK_SPEC
>>  #define LINK_SPEC "%{mbig-endian:-EB} %{mlittle-endian:-EL} -X"
>> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
>> index 4f24daebc01f0fd006540df8d863014aa864d060..faeb4299acc1f0859eafa3e13cf4b24c4d0224d6 100644
>> --- a/gcc/doc/invoke.texi
>> +++ b/gcc/doc/invoke.texi
>> @@ -639,7 +639,8 @@ Objective-C and Objective-C++ Dialects}.
>>  -mneon-for-64bits @gol
>>  -mslow-flash-data @gol
>>  -masm-syntax-unified @gol
>> --mrestrict-it}
>> +-mrestrict-it @gol
>> +-mpure-code}
>>  
>>  @emph{AVR Options}
>>  @gccoptlist{-mmcu=@var{mcu} -maccumulate-args -mbranch-cost=@var{cost} @gol
>> @@ -14498,6 +14499,14 @@ Print CPU tuning information as comment in assembler file.  This is
>>  an option used only for regression testing of the compiler and not
>>  intended for ordinary use in compiling code.  This option is disabled
>>  by default.
>> +
>> +@item -mpure-code
>> +@opindex mpure-code
>> +Generate assembly where instructions and data are in separate sections.
> 
> This should probably be the same text as the help option.
> 
>> +Additionally, give all text sections the ELF processor-specific section
>> +attribute SHF_ARM_PURECODE.  This option is only available when generating
>> +non-pic code in ELF object format for ARMv7-M targets.
> 
> And this bit will need re-wording for the other changes.
> 
>> +
>>  @end table
>>  
>>  @node AVR Options
>> diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
>> index b318615b7b35ab93ad13e5e535a1d4e6d02cb7f7..c9e1489a0453845a2bffb2df514cc3b5b73933dc 100644
>> --- a/gcc/doc/tm.texi
>> +++ b/gcc/doc/tm.texi
>> @@ -7543,6 +7543,15 @@ is non-NULL, it is the @code{VAR_DECL} or @code{FUNCTION_DECL} with which
>>  this section is associated.
>>  @end deftypefn
>>  
>> +@deftypefn {Target Hook} bool TARGET_ASM_ELF_FLAGS_NUMERIC (unsigned int @var{flags}, unsigned int *@var{num})
>> +If the target needs to represent ELF section attributes using their
>> +numerical value, then this hook should be implemented to return true and
>> +write the numerical value of @var{flags} in @var{num}.  This function is
>> +called by @code{default_elf_asm_named_section}, which prints @var{num}
>> +as the value representing the ELF section attributes if this function
>> +returns true.
>> +@end deftypefn
>> +
>>  @deftypefn {Target Hook} {section *} TARGET_ASM_FUNCTION_SECTION (tree @var{decl}, enum node_frequency @var{freq}, bool @var{startup}, bool @var{exit})
>>  Return preferred text (sub)section for function @var{decl}.
>>  Main purpose of this function is to separate cold, normal and hot
>> diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
>> index 1e8423cb4e255acd8144e4b105186cee3d1d04fd..17a2ca73f07516526543253c77c088c73326af2c 100644
>> --- a/gcc/doc/tm.texi.in
>> +++ b/gcc/doc/tm.texi.in
>> @@ -5229,6 +5229,8 @@ of the filename using this macro.
>>  
>>  @hook TARGET_ASM_NAMED_SECTION
>>  
>> +@hook TARGET_ASM_ELF_FLAGS_NUMERIC
>> +
>>  @hook TARGET_ASM_FUNCTION_SECTION
>>  
>>  @hook TARGET_ASM_FUNCTION_SWITCHED_TEXT_SECTIONS
>> diff --git a/gcc/hooks.c b/gcc/hooks.c
>> index 99ec4014adb6fcbb073bf538dd00fe8695ee6cb2..1e925645c3173f8d97e104b9b2f480fca2ede438 100644
>> --- a/gcc/hooks.c
>> +++ b/gcc/hooks.c
>> @@ -481,3 +481,13 @@ void
>>  hook_void_gcc_optionsp (struct gcc_options *opts ATTRIBUTE_UNUSED)
>>  {
>>  }
>> +
>> +/* Generic hook that takes an unsigned int, an unsigned int pointer and
>> +   returns false.  */
>> +
>> +bool
>> +hook_uint_uintp_false (unsigned int, unsigned int *)
>> +{
>> +  return false;
>> +}
>> +
>> diff --git a/gcc/target.def b/gcc/target.def
>> index a4df363698ce776b51d11c187baed2069ba88a52..a3d46fa48d919a16699c33b2b78236e62a33e025 100644
>> --- a/gcc/target.def
>> +++ b/gcc/target.def
>> @@ -432,6 +432,19 @@ this section is associated.",
>>   void, (const char *name, unsigned int flags, tree decl),
>>   default_no_named_section)
>>  
>> +/* Tell assembler what section attributes to assign this elf section
>> +   declaration, using their numerical value.  */
>> +DEFHOOK
>> +(elf_flags_numeric,
>> + "If the target needs to represent ELF section attributes using their\n\
>> +numerical value, then this hook should be implemented to return true and\n\
>> +write the numerical value of @var{flags} in @var{num}.  This function is\n\
>> +called by @code{default_elf_asm_named_section}, which prints @var{num}\n\
>> +as the value representing the ELF section attributes if this function\n\
>> +returns true.",
> 
> 
> I think this should read something like.
> 
> This hook can be used to encode ELF section flags for which no letter
> code has been defined in the assembler.  It is called by
> @code{default_asm_named_section} whenever the section flags need to be
> emitted in the assembler output.  If the hook returns true, then the
> numerical value for ELF section flags should be calculated from
> @var{flags} and saved in @var{*num}; the value will be printed out
> instead of the normal sequence of letter codes.  If the hook is not
> defined, or if it returns false, then @var{num} will be ignored and the
> traditional letter sequence will be emitted.
> 
> 
>> + bool, (unsigned int flags, unsigned int *num),
>> + hook_uint_uintp_false)
>> +
>>  /* Return preferred text (sub)section for function DECL.
>>     Main purpose of this function is to separate cold, normal and hot
>>     functions. STARTUP is true when function is known to be used only 
>> diff --git a/gcc/targhooks.h b/gcc/targhooks.h
>> index d6581cfab893e0da619c6bc0f98ff722a7ab4404..19ad97fa453cf6102b1502f97d8b66fe413284ee 100644
>> --- a/gcc/targhooks.h
>> +++ b/gcc/targhooks.h
>> @@ -254,5 +254,4 @@ extern void default_setup_incoming_vararg_bounds (cumulative_args_t ca ATTRIBUTE
>>  						  int second_time ATTRIBUTE_UNUSED);
>>  extern bool default_optab_supported_p (int, machine_mode, machine_mode,
>>  				       optimization_type);
>> -
>>  #endif /* GCC_TARGHOOKS_H */
>> diff --git a/gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c b/gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c
>> new file mode 100644
>> index 0000000000000000000000000000000000000000..26fe38c05295b70ccc35ed900d41b34aae2c87a8
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c
>> @@ -0,0 +1,17 @@
>> +/* { dg-do compile } */
>> +/* { dg-skip-if "" { *-*-* } { "-fpic" "-fPIC" } { "" } } */
>> +/* { dg-options "-ffunction-sections -mpure-code" } */
>> +#include <limits.h>
>> +
>> +char * foo (void)
>> +{
>> +  return "foo";
>> +}
>> +
>> +unsigned int bar (unsigned int b)
>> +{
>> +  return UINT_MAX - b;
>> +}
>> +
>> +/* { dg-final { scan-assembler {\.section\t\.text\.foo[^\n]*\"0x20000006\"} } } */
>> +/* { dg-final { scan-assembler {\.section\t\.text\.bar[^\n]*\"0x20000006\"} } } */
>> diff --git a/gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c b/gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c
>> new file mode 100644
>> index 0000000000000000000000000000000000000000..ba116a8261b16610e6af47d26a6e1a07b0127561
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c
>> @@ -0,0 +1,29 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-mpure-code" } */
>> +/* { dg-skip-if "" { *-*-* } { "-g" "-fpic" "-fPIC" } { "" } } */
>> +
>> +extern int foo (void);
>> +extern int bar (void);
>> +extern int baz (void);
>> +extern int fooz (void);
>> +
>> +int caller (unsigned int reg_type)
>> +{
>> +  switch (reg_type)
>> +    {
>> +    case 0x80000000:
>> +      return (int) foo ();
>> +
>> +    case 0x80000003:
>> +      return (int) bar ();
>> +
>> +    case 0x80000001:
>> +      return (int) baz ();
>> +
>> +    case 0x80000004:
>> +      return (int) fooz ();
>> +    }
>> +}
>> +
>> +/* { dg-final { scan-assembler-not "\\.(float|l\\?double|\d?byte|short|int|long|quad|word)\\s+\[^.\]" } } */
>> +/* { dg-final { scan-assembler "text,\"0x20000006\"" } } */
>> diff --git a/gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c b/gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c
>> new file mode 100644
>> index 0000000000000000000000000000000000000000..4b893fd32f722e6cd7dfde5c8542ab98327ba375
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c
>> @@ -0,0 +1,68 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-mpure-code" } */
>> +/* { dg-skip-if "" { *-*-* } { "-g" "-fpic" "-fPIC" } { "" } } */
>> +
>> +float sf;
>> +double df;
>> +long long l;
>> +static char *p = "Hello World";
>> +
>> +float
>> +testsf (float *p)
>> +{
>> +  if (*p > 1.1234f)
>> +    return 2.1234f;
>> +  else
>> +    return 3.1234f;
>> +}
>> +
>> +double
>> +testdf (double *p)
>> +{
>> +  if (*p > 4.1234)
>> +    return 2.1234;
>> +  else
>> +    return 3.1234;
>> +}
>> +
>> +long long
>> +testll (long long *p)
>> +{
>> +  if (*p > 0x123456789ABCDEFll)
>> +    return 0x111111111ll;
>> +  else
>> +    return 0x222222222ll;
>> +}
>> +
>> +char *
>> +testchar ()
>> +{
>> +  return p + 4;
>> +}
>> +
>> +int
>> +foo (int a, int b)
>> +{
>> +  int i;
>> +  volatile int *labelref = &&label1;
>> +
>> +  if (a > b)
>> +    {
>> +      while (i < b)
>> +	{
>> +	  a += *labelref;
>> +	  i += 1;
>> +	}
>> +      goto *labelref;
>> +    }
>> +  else
>> +    b = b + 3;
>> +
>> +  a = a * b;
>> +
>> +label1:
>> +  return a + b;
>> +}
>> +
>> +/* { dg-final { scan-assembler-not "\\.(float|l\\?double|\d?byte|short|int|long|quad|word)\\s+\[^.\]" } } */
>> +/* { dg-final { scan-assembler "text,\"0x20000006\"" } } */
>> diff --git a/gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp b/gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp
>> new file mode 100644
>> index 0000000000000000000000000000000000000000..1abe7782c0e5dbb6e2deef25f4bea9415664f942
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp
>> @@ -0,0 +1,54 @@
>> +#   Copyright (C) 1997-2016 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
>> +# <http://www.gnu.org/licenses/>.
>> +
>> +# GCC testsuite for ARM's -mpure-code option, using the `dg.exp' driver.
>> +
>> +# 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"
>> +}
>> +
>> +# The -mpure-code option is only available for M-profile targets that support
>> +# thumb2.
>> +if {[check_effective_target_arm_thumb2_ok]
>> +    && ![check_effective_target_arm_arm_ok]} then {
>> +# Initialize `dg'.
>> +dg-init
>> +
>> +set saved-dg-do-what-default ${dg-do-what-default}
>> +set dg-do-what-default "assemble"
>> +
>> +set saved-lto_torture_options ${LTO_TORTURE_OPTIONS}
>> +
>> +# Add -ffat-lto-objects option to all LTO options such that we can do assembly
>> +# scans.
>> +proc add_fat_objects { list } {
>> +    set res {}
>> +    foreach el $list {set res [lappend res [concat $el " -ffat-lto-objects"]]}
>> +    return $res
>> +};
>> +set LTO_TORTURE_OPTIONS [add_fat_objects ${LTO_TORTURE_OPTIONS}]
>> +
>> +gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] \
>> +	"" $DEFAULT_CFLAGS
>> +
>> +# All done.
>> +dg-finish
>> +}
>> diff --git a/gcc/varasm.c b/gcc/varasm.c
>> index de8bcd6f20c823acd03991f813da3521b80547ff..13007d8c1ce2d094633422abeb01d91b1e986ac4 100644
>> --- a/gcc/varasm.c
>> +++ b/gcc/varasm.c
>> @@ -6244,6 +6244,7 @@ default_elf_asm_named_section (const char *name, unsigned int flags,
>>  			       tree decl)
>>  {
>>    char flagchars[11], *f = flagchars;
>> +  unsigned int numeric_value;
> 
> I think this should be initialized to zero, rather than assuming the
> hook caller will do that for you.
> 
>>  
>>    /* If we have already declared this section, we can use an
>>       abbreviated form to switch back to it -- unless this section is
>> @@ -6256,31 +6257,38 @@ default_elf_asm_named_section (const char *name, unsigned int flags,
>>        return;
>>      }
>>  
>> -  if (!(flags & SECTION_DEBUG))
>> -    *f++ = 'a';
>> +  /* If we have a machine specific flag, then use the numeric value to pass
>> +     this on to GAS.  */
>> +  if (targetm.asm_out.elf_flags_numeric (flags, &numeric_value))
>> +      snprintf (f, sizeof (flagchars), "0x%08x", numeric_value);
>> +  else
>> +    {
>> +      if (!(flags & SECTION_DEBUG))
>> +	*f++ = 'a';
>>  #if defined (HAVE_GAS_SECTION_EXCLUDE) && HAVE_GAS_SECTION_EXCLUDE == 1
>> -  if (flags & SECTION_EXCLUDE)
>> -    *f++ = 'e';
>> +      if (flags & SECTION_EXCLUDE)
>> +	*f++ = 'e';
>>  #endif
>> -  if (flags & SECTION_WRITE)
>> -    *f++ = 'w';
>> -  if (flags & SECTION_CODE)
>> -    *f++ = 'x';
>> -  if (flags & SECTION_SMALL)
>> -    *f++ = 's';
>> -  if (flags & SECTION_MERGE)
>> -    *f++ = 'M';
>> -  if (flags & SECTION_STRINGS)
>> -    *f++ = 'S';
>> -  if (flags & SECTION_TLS)
>> -    *f++ = TLS_SECTION_ASM_FLAG;
>> -  if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
>> -    *f++ = 'G';
>> +      if (flags & SECTION_WRITE)
>> +	*f++ = 'w';
>> +      if (flags & SECTION_CODE)
>> +	*f++ = 'x';
>> +      if (flags & SECTION_SMALL)
>> +	*f++ = 's';
>> +      if (flags & SECTION_MERGE)
>> +	*f++ = 'M';
>> +      if (flags & SECTION_STRINGS)
>> +	*f++ = 'S';
>> +      if (flags & SECTION_TLS)
>> +	*f++ = TLS_SECTION_ASM_FLAG;
>> +      if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
>> +	*f++ = 'G';
>>  #ifdef MACH_DEP_SECTION_ASM_FLAG
>> -  if (flags & SECTION_MACH_DEP)
>> -    *f++ = MACH_DEP_SECTION_ASM_FLAG;
>> +      if (flags & SECTION_MACH_DEP)
>> +	*f++ = MACH_DEP_SECTION_ASM_FLAG;
>>  #endif
>> -  *f = '\0';
>> +      *f = '\0';
>> +    }
>>  
>>    fprintf (asm_out_file, "\t.section\t%s,\"%s\"", name, flagchars);
>>  
>>
> 
> R.
> 

I reworked the patch according to the comments above.

Is this OK?

gcc/ChangeLog:
2016-09-22  Andre Vieira  <andre.simoesdiasvieira@arm.com>
            Terry Guo  <terry.guo@arm.com>

        * target.def (elf_flags_numeric): New target hook.
        * targhooks.h (default_asm_elf_flags_numeric): New.
        * varasm.c (default_asm_elf_flags_numeric): New.
          (default_elf_asm_named_section): Use new target hook.
        * config/arm/arm.opt (mpure-code): New.
        * config/arm/arm.h (SECTION_ARM_PURECODE): New.
        * config/arm/arm.c (arm_asm_init_sections): Add section
          attribute to default text section if -mpure-code.
          (arm_option_check_internal): Diagnose use of option with
          non supported targets and/or options.
          (arm_asm_elf_flags_numeric): New.
          (arm_function_section): New.
          (arm_elf_section_type_flags): New.
        * config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Disable
          for -mpure-code.
        * gcc/doc/texi (TARGET_ASM_ELF_FLAGS_NUMERIC): New.
        * gcc/doc/texi.in (TARGET_ASM_ELF_FLAGS_NUMERIC): Likewise.



gcc/testsuite/ChangeLog:
2016-09-22  Andre Vieira  <andre.simoesdiasvieira@arm.com>
            Terry Guo  <terry.guo@arm.com>

        * gcc.target/arm/pure-code/ffunction-sections.c: New.
        * gcc.target/arm/pure-code/no-literal-pool.c: New.
        * gcc.target/arm/pure-code/pure-code.exp: New.

[-- Attachment #2: 0001-mpure-code-for-ARM.patch --]
[-- Type: text/x-patch, Size: 23947 bytes --]

diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index f0cdd669191689bc5dcf3a7c2b60da5a2d201e3f..d10605cee0e6e0e07bbb4e1910d30c91443f8d17 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -2263,4 +2263,8 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
 /* For switching between functions with different target attributes.  */
 #define SWITCHABLE_TARGET 1
 
+/* Define SECTION_ARM_PURECODE as the ARM specific section attribute
+   representation for SHF_ARM_PURECODE in GCC.  */
+#define SECTION_ARM_PURECODE SECTION_MACH_DEP
+
 #endif /* ! GCC_ARM_H */
From d0e5894dbe59ea87a3dfc9f681d5616f178ce3a7 Mon Sep 17 00:00:00 2001
From: Andre Simoes Dias Vieira <andsim01@arm.com>
Date: Tue, 14 Jun 2016 11:17:12 +0100
Subject: [PATCH] mpure-code for ARM

---
 gcc/config/arm/arm.c                               | 145 ++++++++++++++++++++-
 gcc/config/arm/arm.h                               |   4 +
 gcc/config/arm/arm.md                              |   2 +-
 gcc/config/arm/arm.opt                             |   4 +
 gcc/config/arm/elf.h                               |   3 +-
 gcc/doc/invoke.texi                                |  11 +-
 gcc/doc/tm.texi                                    |  12 ++
 gcc/doc/tm.texi.in                                 |   2 +
 gcc/hooks.c                                        |  10 ++
 gcc/target.def                                     |  16 +++
 gcc/targhooks.h                                    |   1 -
 .../gcc.target/arm/pure-code/ffunction-sections.c  |  17 +++
 gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c |  29 +++++
 .../gcc.target/arm/pure-code/no-literal-pool.c     |  68 ++++++++++
 .../gcc.target/arm/pure-code/pure-code.exp         |  54 ++++++++
 gcc/varasm.c                                       |  50 ++++---
 16 files changed, 397 insertions(+), 31 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c
 create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c
 create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c
 create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index f60955438d6f1cc5d996e7eacd4b453213044181..59dc2d3392bf375e26507041309e219215198d62 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -214,8 +214,8 @@ static bool arm_return_in_memory (const_tree, const_tree);
 static void arm_unwind_emit (FILE *, rtx_insn *);
 static bool arm_output_ttype (rtx);
 static void arm_asm_emit_except_personality (rtx);
-static void arm_asm_init_sections (void);
 #endif
+static void arm_asm_init_sections (void);
 static rtx arm_dwarf_register_span (rtx);
 
 static tree arm_cxx_guard_type (void);
@@ -299,7 +299,10 @@ static unsigned HOST_WIDE_INT arm_asan_shadow_offset (void);
 static void arm_sched_fusion_priority (rtx_insn *, int, int *, int*);
 static bool arm_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT,
 				     const_tree);
-
+static section *arm_function_section (tree, enum node_frequency, bool, bool);
+static bool arm_asm_elf_flags_numeric (unsigned int flags, unsigned int *num);
+static unsigned int arm_elf_section_type_flags (tree decl, const char *name,
+						int reloc);
 \f
 /* Table of machine attributes.  */
 static const struct attribute_spec arm_attribute_table[] =
@@ -587,8 +590,8 @@ static const struct attribute_spec arm_attribute_table[] =
 #define TARGET_ASM_EMIT_EXCEPT_PERSONALITY arm_asm_emit_except_personality
 
 #undef TARGET_ASM_INIT_SECTIONS
-#define TARGET_ASM_INIT_SECTIONS arm_asm_init_sections
 #endif /* ARM_UNWIND_INFO */
+#define TARGET_ASM_INIT_SECTIONS arm_asm_init_sections
 
 #undef TARGET_DWARF_REGISTER_SPAN
 #define TARGET_DWARF_REGISTER_SPAN arm_dwarf_register_span
@@ -729,6 +732,15 @@ static const struct attribute_spec arm_attribute_table[] =
 #undef TARGET_SCHED_FUSION_PRIORITY
 #define TARGET_SCHED_FUSION_PRIORITY arm_sched_fusion_priority
 
+#undef  TARGET_ASM_FUNCTION_SECTION
+#define TARGET_ASM_FUNCTION_SECTION arm_function_section
+
+#undef TARGET_ASM_ELF_FLAGS_NUMERIC
+#define TARGET_ASM_ELF_FLAGS_NUMERIC arm_asm_elf_flags_numeric
+
+#undef TARGET_SECTION_TYPE_FLAGS
+#define TARGET_SECTION_TYPE_FLAGS arm_elf_section_type_flags
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
 /* Obstack for minipool constant handling.  */
@@ -2815,6 +2827,12 @@ arm_option_check_internal (struct gcc_options *opts)
       && ((!(arm_arch7 && !arm_arch_notm) && !arm_arch7em)
 	  || (TARGET_THUMB1_P (flags) || flag_pic || TARGET_NEON)))
     error ("-mslow-flash-data only supports non-pic code on armv7-m targets");
+
+  /* We only support pure-code on Thumb-2 M-profile targets.  */
+  if (target_pure_code
+      && (!arm_arch_thumb2 || arm_arch_notm || flag_pic || TARGET_NEON))
+    error ("-mpure-code only supports non-pic code on armv7-m targets");
+
 }
 
 /* Recompute the global settings depending on target attribute options.  */
@@ -3453,8 +3471,9 @@ arm_option_override (void)
 			 global_options.x_param_values,
 			 global_options_set.x_param_values);
 
-  /* Currently, for slow flash data, we just disable literal pools.  */
-  if (target_slow_flash_data)
+  /* Currently, for slow flash data, we just disable literal pools.  We also
+     disable it for pure-code.  */
+  if (target_slow_flash_data || target_pure_code)
     arm_disable_literal_pool = true;
 
   /* Disable scheduling fusion by default if it's not armv7 processor
@@ -27208,17 +27227,24 @@ arm_asm_emit_except_personality (rtx personality)
   output_addr_const (asm_out_file, personality);
   fputc ('\n', asm_out_file);
 }
+#endif /* ARM_UNWIND_INFO */
 
 /* Implement TARGET_ASM_INITIALIZE_SECTIONS.  */
 
 static void
 arm_asm_init_sections (void)
 {
+#if ARM_UNWIND_INFO
   exception_section = get_unnamed_section (0, output_section_asm_op,
 					   "\t.handlerdata");
-}
 #endif /* ARM_UNWIND_INFO */
 
+#ifdef OBJECT_FORMAT_ELF
+  if (target_pure_code)
+    text_section->unnamed.data = "\t.section .text,\"0x20000006\",%progbits";
+#endif
+}
+
 /* Output unwind directives for the start/end of a function.  */
 
 void
@@ -30529,4 +30555,111 @@ arm_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT vcall_offset,
   return true;
 }
 
+/* Implement the TARGET_ASM_ELF_FLAGS_NUMERIC hook.
+
+   For pure-code sections there is no letter code for this attribute, so
+   output all the section flags numerically when this is needed.  */
+
+static bool
+arm_asm_elf_flags_numeric (unsigned int flags, unsigned int *num)
+{
+
+  if (flags & SECTION_ARM_PURECODE)
+    {
+      *num = 0x20000000;
+
+      if (!(flags & SECTION_DEBUG))
+	*num |= 0x2;
+      if (flags & SECTION_EXCLUDE)
+	*num |= 0x80000000;
+      if (flags & SECTION_WRITE)
+	*num |= 0x1;
+      if (flags & SECTION_CODE)
+	*num |= 0x4;
+      if (flags & SECTION_MERGE)
+	*num |= 0x10;
+      if (flags & SECTION_STRINGS)
+	*num |= 0x20;
+      if (flags & SECTION_TLS)
+	*num |= 0x400;
+      if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
+	*num |= 0x200;
+
+	return true;
+    }
+
+  return false;
+}
+
+/* Implement the TARGET_ASM_FUNCTION_SECTION hook.
+
+   If -mpure_code is passed as an option, make sure all functions are in
+   sections that have the SHF_ARM_PURECODE attribute.  */
+
+static section *
+arm_function_section (tree decl, enum node_frequency freq,
+		      bool startup, bool exit)
+{
+  const char * section_name;
+  section * sec;
+
+  if (!decl || TREE_CODE (decl) != FUNCTION_DECL)
+    return default_function_section (decl, freq, startup, exit);
+
+  if (!target_pure_code)
+    return default_function_section (decl, freq, startup, exit);
+
+
+  section_name = DECL_SECTION_NAME (decl);
+
+  /* If a function is not in a named section then it falls under the 'default'
+     text section, also known as '.text'.  We can preserve previous behavior as
+     the default text section already has the SHF_ARM_PURECODE section
+     attribute.  */
+  if (!section_name)
+    {
+      section *default_sec = default_function_section (decl, freq, startup,
+						       exit);
+
+      /* If default_sec is not null, then it must be a special section like for
+	 example .text.startup.  We set the pure-code attribute and return the
+	 same section to preserve existing behavior.  */
+      if (default_sec)
+	  default_sec->common.flags |= SECTION_ARM_PURECODE;
+      return default_sec;
+    }
+
+  /* Otherwise look whether a section has already been created with
+     'section_name'.  */
+  sec = get_named_section (decl, section_name, 0);
+  if (!sec)
+    /* If that is not the case passing NULL as the section's name to
+       'get_named_section' will create a section with the declaration's
+       section name.  */
+    sec = get_named_section (decl, NULL, 0);
+
+  /* Set the SHF_ARM_PURECODE attribute.  */
+  sec->common.flags |= SECTION_ARM_PURECODE;
+
+  return sec;
+}
+
+/* Implements the TARGET_SECTION_FLAGS hook.
+
+   If DECL is a function declaration and pure-code is passed as an option
+   then add the SFH_ARM_PURECODE attribute to the section flags.  NAME is the
+   section's name and RELOC indicates whether the declarations initializer may
+   contain runtime relocations.  */
+
+static unsigned int
+arm_elf_section_type_flags (tree decl, const char *name, int reloc)
+{
+  unsigned int flags = default_section_type_flags (decl, name, reloc);
+
+  if (decl && TREE_CODE (decl) == FUNCTION_DECL && target_pure_code)
+    flags |= SECTION_ARM_PURECODE;
+
+  return flags;
+}
+
 #include "gt-arm.h"
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 16498316bee9f19baff414885efe1e78191da047..9f49ab6014e61e7b49972f29c96ad03c11101aa1 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -8180,7 +8180,7 @@
    (match_operand:SI 2 "const_int_operand" "")	; total range
    (match_operand:SI 3 "" "")			; table label
    (match_operand:SI 4 "" "")]			; Out of range label
-  "TARGET_32BIT || optimize_size || flag_pic"
+  "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
   "
   {
     enum insn_code code;
diff --git a/gcc/config/arm/arm.opt b/gcc/config/arm/arm.opt
index 0ebe0174390167b79a64583c35a3f8fb018f6538..35f047e2de1659c2b426cf42dbbdae5be62cbfef 100644
--- a/gcc/config/arm/arm.opt
+++ b/gcc/config/arm/arm.opt
@@ -281,3 +281,7 @@ Assume loading data from flash is slower than fetching instructions.
 masm-syntax-unified
 Target Report Var(inline_asm_unified) Init(0) Save
 Assume unified syntax for inline assembly code.
+
+mpure-code
+Target Report Var(target_pure_code) Init(0)
+Do not allow constant data to be placed in code sections.
diff --git a/gcc/config/arm/elf.h b/gcc/config/arm/elf.h
index 77f30554d5286bd83aeab0c8dc308cfd44e732dc..395a22282be0cd2edc9459e1ba14d7848073fa5d 100644
--- a/gcc/config/arm/elf.h
+++ b/gcc/config/arm/elf.h
@@ -104,7 +104,8 @@
    the code more efficient, but for Thumb-1 it's better to put them out of
    band unless we are generating compressed tables.  */
 #define JUMP_TABLES_IN_TEXT_SECTION					\
-   (TARGET_32BIT || (TARGET_THUMB && (optimize_size || flag_pic)))
+   ((TARGET_32BIT || (TARGET_THUMB && (optimize_size || flag_pic))) \
+    && !target_pure_code)
 
 #ifndef LINK_SPEC
 #define LINK_SPEC "%{mbig-endian:-EB} %{mlittle-endian:-EL} -X"
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 4f24daebc01f0fd006540df8d863014aa864d060..f673d7d2172d53422e56457c0039b96a08a526b4 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -639,7 +639,8 @@ Objective-C and Objective-C++ Dialects}.
 -mneon-for-64bits @gol
 -mslow-flash-data @gol
 -masm-syntax-unified @gol
--mrestrict-it}
+-mrestrict-it @gol
+-mpure-code}
 
 @emph{AVR Options}
 @gccoptlist{-mmcu=@var{mcu} -maccumulate-args -mbranch-cost=@var{cost} @gol
@@ -14498,6 +14499,14 @@ Print CPU tuning information as comment in assembler file.  This is
 an option used only for regression testing of the compiler and not
 intended for ordinary use in compiling code.  This option is disabled
 by default.
+
+@item -mpure-code
+@opindex mpure-code
+Do not allow constant data to be placed in code sections.
+Additionally, when compiling for ELF object format give all text sections the
+ELF processor-specific section attribute SHF_ARM_PURECODE.  This option is only
+available when generating non-pic code for ARMv7-M targets.
+
 @end table
 
 @node AVR Options
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index b318615b7b35ab93ad13e5e535a1d4e6d02cb7f7..2c717960d8cea72a93da6e23abcd01aed3b37d6e 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -7543,6 +7543,18 @@ is non-NULL, it is the @code{VAR_DECL} or @code{FUNCTION_DECL} with which
 this section is associated.
 @end deftypefn
 
+@deftypefn {Target Hook} bool TARGET_ASM_ELF_FLAGS_NUMERIC (unsigned int @var{flags}, unsigned int *@var{num})
+This hook can be used to encode ELF section flags for which no letter
+code has been defined in the assembler.  It is called by
+@code{default_asm_named_section} whenever the section flags need to be
+emitted in the assembler output.  If the hook returns true, then the
+numerical value for ELF section flags should be calculated from
+@var{flags} and saved in @var{*num}; the value will be printed out
+instead of the normal sequence of letter codes.  If the hook is not
+defined, or if it returns false, then @var{num} will be ignored and the
+traditional letter sequence will be emitted.
+@end deftypefn
+
 @deftypefn {Target Hook} {section *} TARGET_ASM_FUNCTION_SECTION (tree @var{decl}, enum node_frequency @var{freq}, bool @var{startup}, bool @var{exit})
 Return preferred text (sub)section for function @var{decl}.
 Main purpose of this function is to separate cold, normal and hot
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 1e8423cb4e255acd8144e4b105186cee3d1d04fd..17a2ca73f07516526543253c77c088c73326af2c 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -5229,6 +5229,8 @@ of the filename using this macro.
 
 @hook TARGET_ASM_NAMED_SECTION
 
+@hook TARGET_ASM_ELF_FLAGS_NUMERIC
+
 @hook TARGET_ASM_FUNCTION_SECTION
 
 @hook TARGET_ASM_FUNCTION_SWITCHED_TEXT_SECTIONS
diff --git a/gcc/hooks.c b/gcc/hooks.c
index 99ec4014adb6fcbb073bf538dd00fe8695ee6cb2..1e925645c3173f8d97e104b9b2f480fca2ede438 100644
--- a/gcc/hooks.c
+++ b/gcc/hooks.c
@@ -481,3 +481,13 @@ void
 hook_void_gcc_optionsp (struct gcc_options *opts ATTRIBUTE_UNUSED)
 {
 }
+
+/* Generic hook that takes an unsigned int, an unsigned int pointer and
+   returns false.  */
+
+bool
+hook_uint_uintp_false (unsigned int, unsigned int *)
+{
+  return false;
+}
+
diff --git a/gcc/target.def b/gcc/target.def
index a4df363698ce776b51d11c187baed2069ba88a52..dc5a39aa724b05a3adb06c3af1b24fdff0d428c1 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -432,6 +432,22 @@ this section is associated.",
  void, (const char *name, unsigned int flags, tree decl),
  default_no_named_section)
 
+/* Tell assembler what section attributes to assign this elf section
+   declaration, using their numerical value.  */
+DEFHOOK
+(elf_flags_numeric,
+ "This hook can be used to encode ELF section flags for which no letter\n\
+code has been defined in the assembler.  It is called by\n\
+@code{default_asm_named_section} whenever the section flags need to be\n\
+emitted in the assembler output.  If the hook returns true, then the\n\
+numerical value for ELF section flags should be calculated from\n\
+@var{flags} and saved in @var{*num}; the value will be printed out\n\
+instead of the normal sequence of letter codes.  If the hook is not\n\
+defined, or if it returns false, then @var{num} will be ignored and the\n\
+traditional letter sequence will be emitted.",
+ bool, (unsigned int flags, unsigned int *num),
+ hook_uint_uintp_false)
+
 /* Return preferred text (sub)section for function DECL.
    Main purpose of this function is to separate cold, normal and hot
    functions. STARTUP is true when function is known to be used only 
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index d6581cfab893e0da619c6bc0f98ff722a7ab4404..19ad97fa453cf6102b1502f97d8b66fe413284ee 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -254,5 +254,4 @@ extern void default_setup_incoming_vararg_bounds (cumulative_args_t ca ATTRIBUTE
 						  int second_time ATTRIBUTE_UNUSED);
 extern bool default_optab_supported_p (int, machine_mode, machine_mode,
 				       optimization_type);
-
 #endif /* GCC_TARGHOOKS_H */
diff --git a/gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c b/gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c
new file mode 100644
index 0000000000000000000000000000000000000000..26fe38c05295b70ccc35ed900d41b34aae2c87a8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-fpic" "-fPIC" } { "" } } */
+/* { dg-options "-ffunction-sections -mpure-code" } */
+#include <limits.h>
+
+char * foo (void)
+{
+  return "foo";
+}
+
+unsigned int bar (unsigned int b)
+{
+  return UINT_MAX - b;
+}
+
+/* { dg-final { scan-assembler {\.section\t\.text\.foo[^\n]*\"0x20000006\"} } } */
+/* { dg-final { scan-assembler {\.section\t\.text\.bar[^\n]*\"0x20000006\"} } } */
diff --git a/gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c b/gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c
new file mode 100644
index 0000000000000000000000000000000000000000..ba116a8261b16610e6af47d26a6e1a07b0127561
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-mpure-code" } */
+/* { dg-skip-if "" { *-*-* } { "-g" "-fpic" "-fPIC" } { "" } } */
+
+extern int foo (void);
+extern int bar (void);
+extern int baz (void);
+extern int fooz (void);
+
+int caller (unsigned int reg_type)
+{
+  switch (reg_type)
+    {
+    case 0x80000000:
+      return (int) foo ();
+
+    case 0x80000003:
+      return (int) bar ();
+
+    case 0x80000001:
+      return (int) baz ();
+
+    case 0x80000004:
+      return (int) fooz ();
+    }
+}
+
+/* { dg-final { scan-assembler-not "\\.(float|l\\?double|\d?byte|short|int|long|quad|word)\\s+\[^.\]" } } */
+/* { dg-final { scan-assembler "text,\"0x20000006\"" } } */
diff --git a/gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c b/gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c
new file mode 100644
index 0000000000000000000000000000000000000000..4b893fd32f722e6cd7dfde5c8542ab98327ba375
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-mpure-code" } */
+/* { dg-skip-if "" { *-*-* } { "-g" "-fpic" "-fPIC" } { "" } } */
+
+float sf;
+double df;
+long long l;
+static char *p = "Hello World";
+
+float
+testsf (float *p)
+{
+  if (*p > 1.1234f)
+    return 2.1234f;
+  else
+    return 3.1234f;
+}
+
+double
+testdf (double *p)
+{
+  if (*p > 4.1234)
+    return 2.1234;
+  else
+    return 3.1234;
+}
+
+long long
+testll (long long *p)
+{
+  if (*p > 0x123456789ABCDEFll)
+    return 0x111111111ll;
+  else
+    return 0x222222222ll;
+}
+
+char *
+testchar ()
+{
+  return p + 4;
+}
+
+int
+foo (int a, int b)
+{
+  int i;
+  volatile int *labelref = &&label1;
+
+  if (a > b)
+    {
+      while (i < b)
+	{
+	  a += *labelref;
+	  i += 1;
+	}
+      goto *labelref;
+    }
+  else
+    b = b + 3;
+
+  a = a * b;
+
+label1:
+  return a + b;
+}
+
+/* { dg-final { scan-assembler-not "\\.(float|l\\?double|\d?byte|short|int|long|quad|word)\\s+\[^.\]" } } */
+/* { dg-final { scan-assembler "text,\"0x20000006\"" } } */
diff --git a/gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp b/gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp
new file mode 100644
index 0000000000000000000000000000000000000000..1abe7782c0e5dbb6e2deef25f4bea9415664f942
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp
@@ -0,0 +1,54 @@
+#   Copyright (C) 1997-2016 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
+# <http://www.gnu.org/licenses/>.
+
+# GCC testsuite for ARM's -mpure-code option, using the `dg.exp' driver.
+
+# 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"
+}
+
+# The -mpure-code option is only available for M-profile targets that support
+# thumb2.
+if {[check_effective_target_arm_thumb2_ok]
+    && ![check_effective_target_arm_arm_ok]} then {
+# Initialize `dg'.
+dg-init
+
+set saved-dg-do-what-default ${dg-do-what-default}
+set dg-do-what-default "assemble"
+
+set saved-lto_torture_options ${LTO_TORTURE_OPTIONS}
+
+# Add -ffat-lto-objects option to all LTO options such that we can do assembly
+# scans.
+proc add_fat_objects { list } {
+    set res {}
+    foreach el $list {set res [lappend res [concat $el " -ffat-lto-objects"]]}
+    return $res
+};
+set LTO_TORTURE_OPTIONS [add_fat_objects ${LTO_TORTURE_OPTIONS}]
+
+gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] \
+	"" $DEFAULT_CFLAGS
+
+# All done.
+dg-finish
+}
diff --git a/gcc/varasm.c b/gcc/varasm.c
index de8bcd6f20c823acd03991f813da3521b80547ff..c72c779484fd2ba7bdc58285437ef89ec9effbad 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6244,6 +6244,7 @@ default_elf_asm_named_section (const char *name, unsigned int flags,
 			       tree decl)
 {
   char flagchars[11], *f = flagchars;
+  unsigned int numeric_value = 0;
 
   /* If we have already declared this section, we can use an
      abbreviated form to switch back to it -- unless this section is
@@ -6256,31 +6257,38 @@ default_elf_asm_named_section (const char *name, unsigned int flags,
       return;
     }
 
-  if (!(flags & SECTION_DEBUG))
-    *f++ = 'a';
+  /* If we have a machine specific flag, then use the numeric value to pass
+     this on to GAS.  */
+  if (targetm.asm_out.elf_flags_numeric (flags, &numeric_value))
+      snprintf (f, sizeof (flagchars), "0x%08x", numeric_value);
+  else
+    {
+      if (!(flags & SECTION_DEBUG))
+	*f++ = 'a';
 #if defined (HAVE_GAS_SECTION_EXCLUDE) && HAVE_GAS_SECTION_EXCLUDE == 1
-  if (flags & SECTION_EXCLUDE)
-    *f++ = 'e';
+      if (flags & SECTION_EXCLUDE)
+	*f++ = 'e';
 #endif
-  if (flags & SECTION_WRITE)
-    *f++ = 'w';
-  if (flags & SECTION_CODE)
-    *f++ = 'x';
-  if (flags & SECTION_SMALL)
-    *f++ = 's';
-  if (flags & SECTION_MERGE)
-    *f++ = 'M';
-  if (flags & SECTION_STRINGS)
-    *f++ = 'S';
-  if (flags & SECTION_TLS)
-    *f++ = TLS_SECTION_ASM_FLAG;
-  if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
-    *f++ = 'G';
+      if (flags & SECTION_WRITE)
+	*f++ = 'w';
+      if (flags & SECTION_CODE)
+	*f++ = 'x';
+      if (flags & SECTION_SMALL)
+	*f++ = 's';
+      if (flags & SECTION_MERGE)
+	*f++ = 'M';
+      if (flags & SECTION_STRINGS)
+	*f++ = 'S';
+      if (flags & SECTION_TLS)
+	*f++ = TLS_SECTION_ASM_FLAG;
+      if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
+	*f++ = 'G';
 #ifdef MACH_DEP_SECTION_ASM_FLAG
-  if (flags & SECTION_MACH_DEP)
-    *f++ = MACH_DEP_SECTION_ASM_FLAG;
+      if (flags & SECTION_MACH_DEP)
+	*f++ = MACH_DEP_SECTION_ASM_FLAG;
 #endif
-  *f = '\0';
+      *f = '\0';
+    }
 
   fprintf (asm_out_file, "\t.section\t%s,\"%s\"", name, flagchars);
 
-- 
1.9.1


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCHv3][ARM] -mpure-code option for ARM
  2016-09-22 15:10       ` [PATCHv3][ARM] " Andre Vieira (lists)
@ 2016-09-22 15:47         ` Richard Earnshaw (lists)
  2016-09-22 17:24           ` Andre Vieira (lists)
  2016-09-23 13:47         ` [PATCH, arm-embedded] " Andre Vieira (lists)
  1 sibling, 1 reply; 24+ messages in thread
From: Richard Earnshaw (lists) @ 2016-09-22 15:47 UTC (permalink / raw)
  To: Andre Vieira (lists), gcc-patches

On 22/09/16 16:04, Andre Vieira (lists) wrote:
> 
> I reworked the patch according to the comments above.
> 
> Is this OK?
> 
> gcc/ChangeLog:
> 2016-09-22  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>             Terry Guo  <terry.guo@arm.com>
> 
>         * target.def (elf_flags_numeric): New target hook.
>         * targhooks.h (default_asm_elf_flags_numeric): New.
>         * varasm.c (default_asm_elf_flags_numeric): New.
>           (default_elf_asm_named_section): Use new target hook.
>         * config/arm/arm.opt (mpure-code): New.
>         * config/arm/arm.h (SECTION_ARM_PURECODE): New.
>         * config/arm/arm.c (arm_asm_init_sections): Add section
>           attribute to default text section if -mpure-code.
>           (arm_option_check_internal): Diagnose use of option with
>           non supported targets and/or options.
>           (arm_asm_elf_flags_numeric): New.
>           (arm_function_section): New.
>           (arm_elf_section_type_flags): New.
>         * config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Disable
>           for -mpure-code.
>         * gcc/doc/texi (TARGET_ASM_ELF_FLAGS_NUMERIC): New.
>         * gcc/doc/texi.in (TARGET_ASM_ELF_FLAGS_NUMERIC): Likewise.
> 
> 
> 
> gcc/testsuite/ChangeLog:
> 2016-09-22  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>             Terry Guo  <terry.guo@arm.com>
> 
>         * gcc.target/arm/pure-code/ffunction-sections.c: New.
>         * gcc.target/arm/pure-code/no-literal-pool.c: New.
>         * gcc.target/arm/pure-code/pure-code.exp: New.
> 
> 

I missed this last time around, but please can you wrap references to
SHF_ARM_PURECODE in the documentation with @code{...}.

OK with that change.

R.

> 0001-mpure-code-for-ARM.patch
> 
> 
> diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
> index f0cdd669191689bc5dcf3a7c2b60da5a2d201e3f..d10605cee0e6e0e07bbb4e1910d30c91443f8d17 100644
> --- a/gcc/config/arm/arm.h
> +++ b/gcc/config/arm/arm.h
> @@ -2263,4 +2263,8 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
>  /* For switching between functions with different target attributes.  */
>  #define SWITCHABLE_TARGET 1
>  
> +/* Define SECTION_ARM_PURECODE as the ARM specific section attribute
> +   representation for SHF_ARM_PURECODE in GCC.  */
> +#define SECTION_ARM_PURECODE SECTION_MACH_DEP
> +
>  #endif /* ! GCC_ARM_H */
> From d0e5894dbe59ea87a3dfc9f681d5616f178ce3a7 Mon Sep 17 00:00:00 2001
> From: Andre Simoes Dias Vieira <andsim01@arm.com>
> Date: Tue, 14 Jun 2016 11:17:12 +0100
> Subject: [PATCH] mpure-code for ARM
> 
> ---
>  gcc/config/arm/arm.c                               | 145 ++++++++++++++++++++-
>  gcc/config/arm/arm.h                               |   4 +
>  gcc/config/arm/arm.md                              |   2 +-
>  gcc/config/arm/arm.opt                             |   4 +
>  gcc/config/arm/elf.h                               |   3 +-
>  gcc/doc/invoke.texi                                |  11 +-
>  gcc/doc/tm.texi                                    |  12 ++
>  gcc/doc/tm.texi.in                                 |   2 +
>  gcc/hooks.c                                        |  10 ++
>  gcc/target.def                                     |  16 +++
>  gcc/targhooks.h                                    |   1 -
>  .../gcc.target/arm/pure-code/ffunction-sections.c  |  17 +++
>  gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c |  29 +++++
>  .../gcc.target/arm/pure-code/no-literal-pool.c     |  68 ++++++++++
>  .../gcc.target/arm/pure-code/pure-code.exp         |  54 ++++++++
>  gcc/varasm.c                                       |  50 ++++---
>  16 files changed, 397 insertions(+), 31 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c
>  create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c
>  create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c
>  create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp
> 
> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
> index f60955438d6f1cc5d996e7eacd4b453213044181..59dc2d3392bf375e26507041309e219215198d62 100644
> --- a/gcc/config/arm/arm.c
> +++ b/gcc/config/arm/arm.c
> @@ -214,8 +214,8 @@ static bool arm_return_in_memory (const_tree, const_tree);
>  static void arm_unwind_emit (FILE *, rtx_insn *);
>  static bool arm_output_ttype (rtx);
>  static void arm_asm_emit_except_personality (rtx);
> -static void arm_asm_init_sections (void);
>  #endif
> +static void arm_asm_init_sections (void);
>  static rtx arm_dwarf_register_span (rtx);
>  
>  static tree arm_cxx_guard_type (void);
> @@ -299,7 +299,10 @@ static unsigned HOST_WIDE_INT arm_asan_shadow_offset (void);
>  static void arm_sched_fusion_priority (rtx_insn *, int, int *, int*);
>  static bool arm_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT,
>  				     const_tree);
> -
> +static section *arm_function_section (tree, enum node_frequency, bool, bool);
> +static bool arm_asm_elf_flags_numeric (unsigned int flags, unsigned int *num);
> +static unsigned int arm_elf_section_type_flags (tree decl, const char *name,
> +						int reloc);
>  \f
>  /* Table of machine attributes.  */
>  static const struct attribute_spec arm_attribute_table[] =
> @@ -587,8 +590,8 @@ static const struct attribute_spec arm_attribute_table[] =
>  #define TARGET_ASM_EMIT_EXCEPT_PERSONALITY arm_asm_emit_except_personality
>  
>  #undef TARGET_ASM_INIT_SECTIONS
> -#define TARGET_ASM_INIT_SECTIONS arm_asm_init_sections
>  #endif /* ARM_UNWIND_INFO */
> +#define TARGET_ASM_INIT_SECTIONS arm_asm_init_sections
>  
>  #undef TARGET_DWARF_REGISTER_SPAN
>  #define TARGET_DWARF_REGISTER_SPAN arm_dwarf_register_span
> @@ -729,6 +732,15 @@ static const struct attribute_spec arm_attribute_table[] =
>  #undef TARGET_SCHED_FUSION_PRIORITY
>  #define TARGET_SCHED_FUSION_PRIORITY arm_sched_fusion_priority
>  
> +#undef  TARGET_ASM_FUNCTION_SECTION
> +#define TARGET_ASM_FUNCTION_SECTION arm_function_section
> +
> +#undef TARGET_ASM_ELF_FLAGS_NUMERIC
> +#define TARGET_ASM_ELF_FLAGS_NUMERIC arm_asm_elf_flags_numeric
> +
> +#undef TARGET_SECTION_TYPE_FLAGS
> +#define TARGET_SECTION_TYPE_FLAGS arm_elf_section_type_flags
> +
>  struct gcc_target targetm = TARGET_INITIALIZER;
>  \f
>  /* Obstack for minipool constant handling.  */
> @@ -2815,6 +2827,12 @@ arm_option_check_internal (struct gcc_options *opts)
>        && ((!(arm_arch7 && !arm_arch_notm) && !arm_arch7em)
>  	  || (TARGET_THUMB1_P (flags) || flag_pic || TARGET_NEON)))
>      error ("-mslow-flash-data only supports non-pic code on armv7-m targets");
> +
> +  /* We only support pure-code on Thumb-2 M-profile targets.  */
> +  if (target_pure_code
> +      && (!arm_arch_thumb2 || arm_arch_notm || flag_pic || TARGET_NEON))
> +    error ("-mpure-code only supports non-pic code on armv7-m targets");
> +
>  }
>  
>  /* Recompute the global settings depending on target attribute options.  */
> @@ -3453,8 +3471,9 @@ arm_option_override (void)
>  			 global_options.x_param_values,
>  			 global_options_set.x_param_values);
>  
> -  /* Currently, for slow flash data, we just disable literal pools.  */
> -  if (target_slow_flash_data)
> +  /* Currently, for slow flash data, we just disable literal pools.  We also
> +     disable it for pure-code.  */
> +  if (target_slow_flash_data || target_pure_code)
>      arm_disable_literal_pool = true;
>  
>    /* Disable scheduling fusion by default if it's not armv7 processor
> @@ -27208,17 +27227,24 @@ arm_asm_emit_except_personality (rtx personality)
>    output_addr_const (asm_out_file, personality);
>    fputc ('\n', asm_out_file);
>  }
> +#endif /* ARM_UNWIND_INFO */
>  
>  /* Implement TARGET_ASM_INITIALIZE_SECTIONS.  */
>  
>  static void
>  arm_asm_init_sections (void)
>  {
> +#if ARM_UNWIND_INFO
>    exception_section = get_unnamed_section (0, output_section_asm_op,
>  					   "\t.handlerdata");
> -}
>  #endif /* ARM_UNWIND_INFO */
>  
> +#ifdef OBJECT_FORMAT_ELF
> +  if (target_pure_code)
> +    text_section->unnamed.data = "\t.section .text,\"0x20000006\",%progbits";
> +#endif
> +}
> +
>  /* Output unwind directives for the start/end of a function.  */
>  
>  void
> @@ -30529,4 +30555,111 @@ arm_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT vcall_offset,
>    return true;
>  }
>  
> +/* Implement the TARGET_ASM_ELF_FLAGS_NUMERIC hook.
> +
> +   For pure-code sections there is no letter code for this attribute, so
> +   output all the section flags numerically when this is needed.  */
> +
> +static bool
> +arm_asm_elf_flags_numeric (unsigned int flags, unsigned int *num)
> +{
> +
> +  if (flags & SECTION_ARM_PURECODE)
> +    {
> +      *num = 0x20000000;
> +
> +      if (!(flags & SECTION_DEBUG))
> +	*num |= 0x2;
> +      if (flags & SECTION_EXCLUDE)
> +	*num |= 0x80000000;
> +      if (flags & SECTION_WRITE)
> +	*num |= 0x1;
> +      if (flags & SECTION_CODE)
> +	*num |= 0x4;
> +      if (flags & SECTION_MERGE)
> +	*num |= 0x10;
> +      if (flags & SECTION_STRINGS)
> +	*num |= 0x20;
> +      if (flags & SECTION_TLS)
> +	*num |= 0x400;
> +      if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
> +	*num |= 0x200;
> +
> +	return true;
> +    }
> +
> +  return false;
> +}
> +
> +/* Implement the TARGET_ASM_FUNCTION_SECTION hook.
> +
> +   If -mpure_code is passed as an option, make sure all functions are in
> +   sections that have the SHF_ARM_PURECODE attribute.  */
> +
> +static section *
> +arm_function_section (tree decl, enum node_frequency freq,
> +		      bool startup, bool exit)
> +{
> +  const char * section_name;
> +  section * sec;
> +
> +  if (!decl || TREE_CODE (decl) != FUNCTION_DECL)
> +    return default_function_section (decl, freq, startup, exit);
> +
> +  if (!target_pure_code)
> +    return default_function_section (decl, freq, startup, exit);
> +
> +
> +  section_name = DECL_SECTION_NAME (decl);
> +
> +  /* If a function is not in a named section then it falls under the 'default'
> +     text section, also known as '.text'.  We can preserve previous behavior as
> +     the default text section already has the SHF_ARM_PURECODE section
> +     attribute.  */
> +  if (!section_name)
> +    {
> +      section *default_sec = default_function_section (decl, freq, startup,
> +						       exit);
> +
> +      /* If default_sec is not null, then it must be a special section like for
> +	 example .text.startup.  We set the pure-code attribute and return the
> +	 same section to preserve existing behavior.  */
> +      if (default_sec)
> +	  default_sec->common.flags |= SECTION_ARM_PURECODE;
> +      return default_sec;
> +    }
> +
> +  /* Otherwise look whether a section has already been created with
> +     'section_name'.  */
> +  sec = get_named_section (decl, section_name, 0);
> +  if (!sec)
> +    /* If that is not the case passing NULL as the section's name to
> +       'get_named_section' will create a section with the declaration's
> +       section name.  */
> +    sec = get_named_section (decl, NULL, 0);
> +
> +  /* Set the SHF_ARM_PURECODE attribute.  */
> +  sec->common.flags |= SECTION_ARM_PURECODE;
> +
> +  return sec;
> +}
> +
> +/* Implements the TARGET_SECTION_FLAGS hook.
> +
> +   If DECL is a function declaration and pure-code is passed as an option
> +   then add the SFH_ARM_PURECODE attribute to the section flags.  NAME is the
> +   section's name and RELOC indicates whether the declarations initializer may
> +   contain runtime relocations.  */
> +
> +static unsigned int
> +arm_elf_section_type_flags (tree decl, const char *name, int reloc)
> +{
> +  unsigned int flags = default_section_type_flags (decl, name, reloc);
> +
> +  if (decl && TREE_CODE (decl) == FUNCTION_DECL && target_pure_code)
> +    flags |= SECTION_ARM_PURECODE;
> +
> +  return flags;
> +}
> +
>  #include "gt-arm.h"
> diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
> index 16498316bee9f19baff414885efe1e78191da047..9f49ab6014e61e7b49972f29c96ad03c11101aa1 100644
> --- a/gcc/config/arm/arm.md
> +++ b/gcc/config/arm/arm.md
> @@ -8180,7 +8180,7 @@
>     (match_operand:SI 2 "const_int_operand" "")	; total range
>     (match_operand:SI 3 "" "")			; table label
>     (match_operand:SI 4 "" "")]			; Out of range label
> -  "TARGET_32BIT || optimize_size || flag_pic"
> +  "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
>    "
>    {
>      enum insn_code code;
> diff --git a/gcc/config/arm/arm.opt b/gcc/config/arm/arm.opt
> index 0ebe0174390167b79a64583c35a3f8fb018f6538..35f047e2de1659c2b426cf42dbbdae5be62cbfef 100644
> --- a/gcc/config/arm/arm.opt
> +++ b/gcc/config/arm/arm.opt
> @@ -281,3 +281,7 @@ Assume loading data from flash is slower than fetching instructions.
>  masm-syntax-unified
>  Target Report Var(inline_asm_unified) Init(0) Save
>  Assume unified syntax for inline assembly code.
> +
> +mpure-code
> +Target Report Var(target_pure_code) Init(0)
> +Do not allow constant data to be placed in code sections.
> diff --git a/gcc/config/arm/elf.h b/gcc/config/arm/elf.h
> index 77f30554d5286bd83aeab0c8dc308cfd44e732dc..395a22282be0cd2edc9459e1ba14d7848073fa5d 100644
> --- a/gcc/config/arm/elf.h
> +++ b/gcc/config/arm/elf.h
> @@ -104,7 +104,8 @@
>     the code more efficient, but for Thumb-1 it's better to put them out of
>     band unless we are generating compressed tables.  */
>  #define JUMP_TABLES_IN_TEXT_SECTION					\
> -   (TARGET_32BIT || (TARGET_THUMB && (optimize_size || flag_pic)))
> +   ((TARGET_32BIT || (TARGET_THUMB && (optimize_size || flag_pic))) \
> +    && !target_pure_code)
>  
>  #ifndef LINK_SPEC
>  #define LINK_SPEC "%{mbig-endian:-EB} %{mlittle-endian:-EL} -X"
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 4f24daebc01f0fd006540df8d863014aa864d060..f673d7d2172d53422e56457c0039b96a08a526b4 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -639,7 +639,8 @@ Objective-C and Objective-C++ Dialects}.
>  -mneon-for-64bits @gol
>  -mslow-flash-data @gol
>  -masm-syntax-unified @gol
> --mrestrict-it}
> +-mrestrict-it @gol
> +-mpure-code}
>  
>  @emph{AVR Options}
>  @gccoptlist{-mmcu=@var{mcu} -maccumulate-args -mbranch-cost=@var{cost} @gol
> @@ -14498,6 +14499,14 @@ Print CPU tuning information as comment in assembler file.  This is
>  an option used only for regression testing of the compiler and not
>  intended for ordinary use in compiling code.  This option is disabled
>  by default.
> +
> +@item -mpure-code
> +@opindex mpure-code
> +Do not allow constant data to be placed in code sections.
> +Additionally, when compiling for ELF object format give all text sections the
> +ELF processor-specific section attribute SHF_ARM_PURECODE.  This option is only
> +available when generating non-pic code for ARMv7-M targets.
> +
>  @end table
>  
>  @node AVR Options
> diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
> index b318615b7b35ab93ad13e5e535a1d4e6d02cb7f7..2c717960d8cea72a93da6e23abcd01aed3b37d6e 100644
> --- a/gcc/doc/tm.texi
> +++ b/gcc/doc/tm.texi
> @@ -7543,6 +7543,18 @@ is non-NULL, it is the @code{VAR_DECL} or @code{FUNCTION_DECL} with which
>  this section is associated.
>  @end deftypefn
>  
> +@deftypefn {Target Hook} bool TARGET_ASM_ELF_FLAGS_NUMERIC (unsigned int @var{flags}, unsigned int *@var{num})
> +This hook can be used to encode ELF section flags for which no letter
> +code has been defined in the assembler.  It is called by
> +@code{default_asm_named_section} whenever the section flags need to be
> +emitted in the assembler output.  If the hook returns true, then the
> +numerical value for ELF section flags should be calculated from
> +@var{flags} and saved in @var{*num}; the value will be printed out
> +instead of the normal sequence of letter codes.  If the hook is not
> +defined, or if it returns false, then @var{num} will be ignored and the
> +traditional letter sequence will be emitted.
> +@end deftypefn
> +
>  @deftypefn {Target Hook} {section *} TARGET_ASM_FUNCTION_SECTION (tree @var{decl}, enum node_frequency @var{freq}, bool @var{startup}, bool @var{exit})
>  Return preferred text (sub)section for function @var{decl}.
>  Main purpose of this function is to separate cold, normal and hot
> diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
> index 1e8423cb4e255acd8144e4b105186cee3d1d04fd..17a2ca73f07516526543253c77c088c73326af2c 100644
> --- a/gcc/doc/tm.texi.in
> +++ b/gcc/doc/tm.texi.in
> @@ -5229,6 +5229,8 @@ of the filename using this macro.
>  
>  @hook TARGET_ASM_NAMED_SECTION
>  
> +@hook TARGET_ASM_ELF_FLAGS_NUMERIC
> +
>  @hook TARGET_ASM_FUNCTION_SECTION
>  
>  @hook TARGET_ASM_FUNCTION_SWITCHED_TEXT_SECTIONS
> diff --git a/gcc/hooks.c b/gcc/hooks.c
> index 99ec4014adb6fcbb073bf538dd00fe8695ee6cb2..1e925645c3173f8d97e104b9b2f480fca2ede438 100644
> --- a/gcc/hooks.c
> +++ b/gcc/hooks.c
> @@ -481,3 +481,13 @@ void
>  hook_void_gcc_optionsp (struct gcc_options *opts ATTRIBUTE_UNUSED)
>  {
>  }
> +
> +/* Generic hook that takes an unsigned int, an unsigned int pointer and
> +   returns false.  */
> +
> +bool
> +hook_uint_uintp_false (unsigned int, unsigned int *)
> +{
> +  return false;
> +}
> +
> diff --git a/gcc/target.def b/gcc/target.def
> index a4df363698ce776b51d11c187baed2069ba88a52..dc5a39aa724b05a3adb06c3af1b24fdff0d428c1 100644
> --- a/gcc/target.def
> +++ b/gcc/target.def
> @@ -432,6 +432,22 @@ this section is associated.",
>   void, (const char *name, unsigned int flags, tree decl),
>   default_no_named_section)
>  
> +/* Tell assembler what section attributes to assign this elf section
> +   declaration, using their numerical value.  */
> +DEFHOOK
> +(elf_flags_numeric,
> + "This hook can be used to encode ELF section flags for which no letter\n\
> +code has been defined in the assembler.  It is called by\n\
> +@code{default_asm_named_section} whenever the section flags need to be\n\
> +emitted in the assembler output.  If the hook returns true, then the\n\
> +numerical value for ELF section flags should be calculated from\n\
> +@var{flags} and saved in @var{*num}; the value will be printed out\n\
> +instead of the normal sequence of letter codes.  If the hook is not\n\
> +defined, or if it returns false, then @var{num} will be ignored and the\n\
> +traditional letter sequence will be emitted.",
> + bool, (unsigned int flags, unsigned int *num),
> + hook_uint_uintp_false)
> +
>  /* Return preferred text (sub)section for function DECL.
>     Main purpose of this function is to separate cold, normal and hot
>     functions. STARTUP is true when function is known to be used only 
> diff --git a/gcc/targhooks.h b/gcc/targhooks.h
> index d6581cfab893e0da619c6bc0f98ff722a7ab4404..19ad97fa453cf6102b1502f97d8b66fe413284ee 100644
> --- a/gcc/targhooks.h
> +++ b/gcc/targhooks.h
> @@ -254,5 +254,4 @@ extern void default_setup_incoming_vararg_bounds (cumulative_args_t ca ATTRIBUTE
>  						  int second_time ATTRIBUTE_UNUSED);
>  extern bool default_optab_supported_p (int, machine_mode, machine_mode,
>  				       optimization_type);
> -
>  #endif /* GCC_TARGHOOKS_H */
> diff --git a/gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c b/gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..26fe38c05295b70ccc35ed900d41b34aae2c87a8
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { *-*-* } { "-fpic" "-fPIC" } { "" } } */
> +/* { dg-options "-ffunction-sections -mpure-code" } */
> +#include <limits.h>
> +
> +char * foo (void)
> +{
> +  return "foo";
> +}
> +
> +unsigned int bar (unsigned int b)
> +{
> +  return UINT_MAX - b;
> +}
> +
> +/* { dg-final { scan-assembler {\.section\t\.text\.foo[^\n]*\"0x20000006\"} } } */
> +/* { dg-final { scan-assembler {\.section\t\.text\.bar[^\n]*\"0x20000006\"} } } */
> diff --git a/gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c b/gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..ba116a8261b16610e6af47d26a6e1a07b0127561
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c
> @@ -0,0 +1,29 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mpure-code" } */
> +/* { dg-skip-if "" { *-*-* } { "-g" "-fpic" "-fPIC" } { "" } } */
> +
> +extern int foo (void);
> +extern int bar (void);
> +extern int baz (void);
> +extern int fooz (void);
> +
> +int caller (unsigned int reg_type)
> +{
> +  switch (reg_type)
> +    {
> +    case 0x80000000:
> +      return (int) foo ();
> +
> +    case 0x80000003:
> +      return (int) bar ();
> +
> +    case 0x80000001:
> +      return (int) baz ();
> +
> +    case 0x80000004:
> +      return (int) fooz ();
> +    }
> +}
> +
> +/* { dg-final { scan-assembler-not "\\.(float|l\\?double|\d?byte|short|int|long|quad|word)\\s+\[^.\]" } } */
> +/* { dg-final { scan-assembler "text,\"0x20000006\"" } } */
> diff --git a/gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c b/gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..4b893fd32f722e6cd7dfde5c8542ab98327ba375
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mpure-code" } */
> +/* { dg-skip-if "" { *-*-* } { "-g" "-fpic" "-fPIC" } { "" } } */
> +
> +float sf;
> +double df;
> +long long l;
> +static char *p = "Hello World";
> +
> +float
> +testsf (float *p)
> +{
> +  if (*p > 1.1234f)
> +    return 2.1234f;
> +  else
> +    return 3.1234f;
> +}
> +
> +double
> +testdf (double *p)
> +{
> +  if (*p > 4.1234)
> +    return 2.1234;
> +  else
> +    return 3.1234;
> +}
> +
> +long long
> +testll (long long *p)
> +{
> +  if (*p > 0x123456789ABCDEFll)
> +    return 0x111111111ll;
> +  else
> +    return 0x222222222ll;
> +}
> +
> +char *
> +testchar ()
> +{
> +  return p + 4;
> +}
> +
> +int
> +foo (int a, int b)
> +{
> +  int i;
> +  volatile int *labelref = &&label1;
> +
> +  if (a > b)
> +    {
> +      while (i < b)
> +	{
> +	  a += *labelref;
> +	  i += 1;
> +	}
> +      goto *labelref;
> +    }
> +  else
> +    b = b + 3;
> +
> +  a = a * b;
> +
> +label1:
> +  return a + b;
> +}
> +
> +/* { dg-final { scan-assembler-not "\\.(float|l\\?double|\d?byte|short|int|long|quad|word)\\s+\[^.\]" } } */
> +/* { dg-final { scan-assembler "text,\"0x20000006\"" } } */
> diff --git a/gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp b/gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp
> new file mode 100644
> index 0000000000000000000000000000000000000000..1abe7782c0e5dbb6e2deef25f4bea9415664f942
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp
> @@ -0,0 +1,54 @@
> +#   Copyright (C) 1997-2016 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
> +# <http://www.gnu.org/licenses/>.
> +
> +# GCC testsuite for ARM's -mpure-code option, using the `dg.exp' driver.
> +
> +# 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"
> +}
> +
> +# The -mpure-code option is only available for M-profile targets that support
> +# thumb2.
> +if {[check_effective_target_arm_thumb2_ok]
> +    && ![check_effective_target_arm_arm_ok]} then {
> +# Initialize `dg'.
> +dg-init
> +
> +set saved-dg-do-what-default ${dg-do-what-default}
> +set dg-do-what-default "assemble"
> +
> +set saved-lto_torture_options ${LTO_TORTURE_OPTIONS}
> +
> +# Add -ffat-lto-objects option to all LTO options such that we can do assembly
> +# scans.
> +proc add_fat_objects { list } {
> +    set res {}
> +    foreach el $list {set res [lappend res [concat $el " -ffat-lto-objects"]]}
> +    return $res
> +};
> +set LTO_TORTURE_OPTIONS [add_fat_objects ${LTO_TORTURE_OPTIONS}]
> +
> +gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] \
> +	"" $DEFAULT_CFLAGS
> +
> +# All done.
> +dg-finish
> +}
> diff --git a/gcc/varasm.c b/gcc/varasm.c
> index de8bcd6f20c823acd03991f813da3521b80547ff..c72c779484fd2ba7bdc58285437ef89ec9effbad 100644
> --- a/gcc/varasm.c
> +++ b/gcc/varasm.c
> @@ -6244,6 +6244,7 @@ default_elf_asm_named_section (const char *name, unsigned int flags,
>  			       tree decl)
>  {
>    char flagchars[11], *f = flagchars;
> +  unsigned int numeric_value = 0;
>  
>    /* If we have already declared this section, we can use an
>       abbreviated form to switch back to it -- unless this section is
> @@ -6256,31 +6257,38 @@ default_elf_asm_named_section (const char *name, unsigned int flags,
>        return;
>      }
>  
> -  if (!(flags & SECTION_DEBUG))
> -    *f++ = 'a';
> +  /* If we have a machine specific flag, then use the numeric value to pass
> +     this on to GAS.  */
> +  if (targetm.asm_out.elf_flags_numeric (flags, &numeric_value))
> +      snprintf (f, sizeof (flagchars), "0x%08x", numeric_value);
> +  else
> +    {
> +      if (!(flags & SECTION_DEBUG))
> +	*f++ = 'a';
>  #if defined (HAVE_GAS_SECTION_EXCLUDE) && HAVE_GAS_SECTION_EXCLUDE == 1
> -  if (flags & SECTION_EXCLUDE)
> -    *f++ = 'e';
> +      if (flags & SECTION_EXCLUDE)
> +	*f++ = 'e';
>  #endif
> -  if (flags & SECTION_WRITE)
> -    *f++ = 'w';
> -  if (flags & SECTION_CODE)
> -    *f++ = 'x';
> -  if (flags & SECTION_SMALL)
> -    *f++ = 's';
> -  if (flags & SECTION_MERGE)
> -    *f++ = 'M';
> -  if (flags & SECTION_STRINGS)
> -    *f++ = 'S';
> -  if (flags & SECTION_TLS)
> -    *f++ = TLS_SECTION_ASM_FLAG;
> -  if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
> -    *f++ = 'G';
> +      if (flags & SECTION_WRITE)
> +	*f++ = 'w';
> +      if (flags & SECTION_CODE)
> +	*f++ = 'x';
> +      if (flags & SECTION_SMALL)
> +	*f++ = 's';
> +      if (flags & SECTION_MERGE)
> +	*f++ = 'M';
> +      if (flags & SECTION_STRINGS)
> +	*f++ = 'S';
> +      if (flags & SECTION_TLS)
> +	*f++ = TLS_SECTION_ASM_FLAG;
> +      if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
> +	*f++ = 'G';
>  #ifdef MACH_DEP_SECTION_ASM_FLAG
> -  if (flags & SECTION_MACH_DEP)
> -    *f++ = MACH_DEP_SECTION_ASM_FLAG;
> +      if (flags & SECTION_MACH_DEP)
> +	*f++ = MACH_DEP_SECTION_ASM_FLAG;
>  #endif
> -  *f = '\0';
> +      *f = '\0';
> +    }
>  
>    fprintf (asm_out_file, "\t.section\t%s,\"%s\"", name, flagchars);
>  
> 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCHv3][ARM] -mpure-code option for ARM
  2016-09-22 15:47         ` Richard Earnshaw (lists)
@ 2016-09-22 17:24           ` Andre Vieira (lists)
  2016-09-22 19:34             ` Christophe Lyon
                               ` (2 more replies)
  0 siblings, 3 replies; 24+ messages in thread
From: Andre Vieira (lists) @ 2016-09-22 17:24 UTC (permalink / raw)
  To: Richard Earnshaw (lists), gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1837 bytes --]

On 22/09/16 16:28, Richard Earnshaw (lists) wrote:
> On 22/09/16 16:04, Andre Vieira (lists) wrote:
>>
>> I reworked the patch according to the comments above.
>>
>> Is this OK?
>>
>> gcc/ChangeLog:
>> 2016-09-22  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>             Terry Guo  <terry.guo@arm.com>
>>
>>         * target.def (elf_flags_numeric): New target hook.
>>         * targhooks.h (default_asm_elf_flags_numeric): New.
>>         * varasm.c (default_asm_elf_flags_numeric): New.
>>           (default_elf_asm_named_section): Use new target hook.
>>         * config/arm/arm.opt (mpure-code): New.
>>         * config/arm/arm.h (SECTION_ARM_PURECODE): New.
>>         * config/arm/arm.c (arm_asm_init_sections): Add section
>>           attribute to default text section if -mpure-code.
>>           (arm_option_check_internal): Diagnose use of option with
>>           non supported targets and/or options.
>>           (arm_asm_elf_flags_numeric): New.
>>           (arm_function_section): New.
>>           (arm_elf_section_type_flags): New.
>>         * config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Disable
>>           for -mpure-code.
>>         * gcc/doc/texi (TARGET_ASM_ELF_FLAGS_NUMERIC): New.
>>         * gcc/doc/texi.in (TARGET_ASM_ELF_FLAGS_NUMERIC): Likewise.
>>
>>
>>
>> gcc/testsuite/ChangeLog:
>> 2016-09-22  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>             Terry Guo  <terry.guo@arm.com>
>>
>>         * gcc.target/arm/pure-code/ffunction-sections.c: New.
>>         * gcc.target/arm/pure-code/no-literal-pool.c: New.
>>         * gcc.target/arm/pure-code/pure-code.exp: New.
>>
>>
> 
> I missed this last time around, but please can you wrap references to
> SHF_ARM_PURECODE in the documentation with @code{...}.
> 
> OK with that change.
> 
> R.

Done. Committed as revision r240379.


[-- Attachment #2: 0001-mpure-code-for-ARM.patch --]
[-- Type: text/x-patch, Size: 23423 bytes --]

diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index f0cdd669191689bc5dcf3a7c2b60da5a2d201e3f..d10605cee0e6e0e07bbb4e1910d30c91443f8d17 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -2263,4 +2263,8 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
 /* For switching between functions with different target attributes.  */
 #define SWITCHABLE_TARGET 1
 
+/* Define SECTION_ARM_PURECODE as the ARM specific section attribute
+   representation for SHF_ARM_PURECODE in GCC.  */
+#define SECTION_ARM_PURECODE SECTION_MACH_DEP
+
 #endif /* ! GCC_ARM_H */
From f1d08002e245776ff131fcdf498cc3a9acc87ca3 Mon Sep 17 00:00:00 2001
From: Andre Simoes Dias Vieira <andsim01@arm.com>
Date: Tue, 14 Jun 2016 11:17:12 +0100
Subject: [PATCH] mpure-code for ARM

---
 gcc/config/arm/arm.c                               | 145 ++++++++++++++++++++-
 gcc/config/arm/arm.h                               |   4 +
 gcc/config/arm/arm.md                              |   2 +-
 gcc/config/arm/arm.opt                             |   4 +
 gcc/config/arm/elf.h                               |   3 +-
 gcc/doc/invoke.texi                                |  11 +-
 gcc/doc/tm.texi                                    |  12 ++
 gcc/doc/tm.texi.in                                 |   2 +
 gcc/hooks.c                                        |  10 ++
 gcc/target.def                                     |  16 +++
 .../gcc.target/arm/pure-code/ffunction-sections.c  |  17 +++
 gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c |  29 +++++
 .../gcc.target/arm/pure-code/no-literal-pool.c     |  68 ++++++++++
 .../gcc.target/arm/pure-code/pure-code.exp         |  54 ++++++++
 gcc/varasm.c                                       |  50 ++++---
 15 files changed, 397 insertions(+), 30 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c
 create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c
 create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c
 create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index f60955438d6f1cc5d996e7eacd4b453213044181..4d3f3d5b169dba636276093f1567b248e3035812 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -214,8 +214,8 @@ static bool arm_return_in_memory (const_tree, const_tree);
 static void arm_unwind_emit (FILE *, rtx_insn *);
 static bool arm_output_ttype (rtx);
 static void arm_asm_emit_except_personality (rtx);
-static void arm_asm_init_sections (void);
 #endif
+static void arm_asm_init_sections (void);
 static rtx arm_dwarf_register_span (rtx);
 
 static tree arm_cxx_guard_type (void);
@@ -299,7 +299,10 @@ static unsigned HOST_WIDE_INT arm_asan_shadow_offset (void);
 static void arm_sched_fusion_priority (rtx_insn *, int, int *, int*);
 static bool arm_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT,
 				     const_tree);
-
+static section *arm_function_section (tree, enum node_frequency, bool, bool);
+static bool arm_asm_elf_flags_numeric (unsigned int flags, unsigned int *num);
+static unsigned int arm_elf_section_type_flags (tree decl, const char *name,
+						int reloc);
 \f
 /* Table of machine attributes.  */
 static const struct attribute_spec arm_attribute_table[] =
@@ -587,8 +590,8 @@ static const struct attribute_spec arm_attribute_table[] =
 #define TARGET_ASM_EMIT_EXCEPT_PERSONALITY arm_asm_emit_except_personality
 
 #undef TARGET_ASM_INIT_SECTIONS
-#define TARGET_ASM_INIT_SECTIONS arm_asm_init_sections
 #endif /* ARM_UNWIND_INFO */
+#define TARGET_ASM_INIT_SECTIONS arm_asm_init_sections
 
 #undef TARGET_DWARF_REGISTER_SPAN
 #define TARGET_DWARF_REGISTER_SPAN arm_dwarf_register_span
@@ -729,6 +732,15 @@ static const struct attribute_spec arm_attribute_table[] =
 #undef TARGET_SCHED_FUSION_PRIORITY
 #define TARGET_SCHED_FUSION_PRIORITY arm_sched_fusion_priority
 
+#undef  TARGET_ASM_FUNCTION_SECTION
+#define TARGET_ASM_FUNCTION_SECTION arm_function_section
+
+#undef TARGET_ASM_ELF_FLAGS_NUMERIC
+#define TARGET_ASM_ELF_FLAGS_NUMERIC arm_asm_elf_flags_numeric
+
+#undef TARGET_SECTION_TYPE_FLAGS
+#define TARGET_SECTION_TYPE_FLAGS arm_elf_section_type_flags
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
 /* Obstack for minipool constant handling.  */
@@ -2815,6 +2827,12 @@ arm_option_check_internal (struct gcc_options *opts)
       && ((!(arm_arch7 && !arm_arch_notm) && !arm_arch7em)
 	  || (TARGET_THUMB1_P (flags) || flag_pic || TARGET_NEON)))
     error ("-mslow-flash-data only supports non-pic code on armv7-m targets");
+
+  /* We only support pure-code on Thumb-2 M-profile targets.  */
+  if (target_pure_code
+      && (!arm_arch_thumb2 || arm_arch_notm || flag_pic || TARGET_NEON))
+    error ("-mpure-code only supports non-pic code on armv7-m targets");
+
 }
 
 /* Recompute the global settings depending on target attribute options.  */
@@ -3453,8 +3471,9 @@ arm_option_override (void)
 			 global_options.x_param_values,
 			 global_options_set.x_param_values);
 
-  /* Currently, for slow flash data, we just disable literal pools.  */
-  if (target_slow_flash_data)
+  /* Currently, for slow flash data, we just disable literal pools.  We also
+     disable it for pure-code.  */
+  if (target_slow_flash_data || target_pure_code)
     arm_disable_literal_pool = true;
 
   /* Disable scheduling fusion by default if it's not armv7 processor
@@ -27208,17 +27227,24 @@ arm_asm_emit_except_personality (rtx personality)
   output_addr_const (asm_out_file, personality);
   fputc ('\n', asm_out_file);
 }
+#endif /* ARM_UNWIND_INFO */
 
 /* Implement TARGET_ASM_INITIALIZE_SECTIONS.  */
 
 static void
 arm_asm_init_sections (void)
 {
+#if ARM_UNWIND_INFO
   exception_section = get_unnamed_section (0, output_section_asm_op,
 					   "\t.handlerdata");
-}
 #endif /* ARM_UNWIND_INFO */
 
+#ifdef OBJECT_FORMAT_ELF
+  if (target_pure_code)
+    text_section->unnamed.data = "\t.section .text,\"0x20000006\",%progbits";
+#endif
+}
+
 /* Output unwind directives for the start/end of a function.  */
 
 void
@@ -30529,4 +30555,111 @@ arm_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT vcall_offset,
   return true;
 }
 
+/* Implement the TARGET_ASM_ELF_FLAGS_NUMERIC hook.
+
+   For pure-code sections there is no letter code for this attribute, so
+   output all the section flags numerically when this is needed.  */
+
+static bool
+arm_asm_elf_flags_numeric (unsigned int flags, unsigned int *num)
+{
+
+  if (flags & SECTION_ARM_PURECODE)
+    {
+      *num = 0x20000000;
+
+      if (!(flags & SECTION_DEBUG))
+	*num |= 0x2;
+      if (flags & SECTION_EXCLUDE)
+	*num |= 0x80000000;
+      if (flags & SECTION_WRITE)
+	*num |= 0x1;
+      if (flags & SECTION_CODE)
+	*num |= 0x4;
+      if (flags & SECTION_MERGE)
+	*num |= 0x10;
+      if (flags & SECTION_STRINGS)
+	*num |= 0x20;
+      if (flags & SECTION_TLS)
+	*num |= 0x400;
+      if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
+	*num |= 0x200;
+
+	return true;
+    }
+
+  return false;
+}
+
+/* Implement the TARGET_ASM_FUNCTION_SECTION hook.
+
+   If pure-code is passed as an option, make sure all functions are in
+   sections that have the SHF_ARM_PURECODE attribute.  */
+
+static section *
+arm_function_section (tree decl, enum node_frequency freq,
+		      bool startup, bool exit)
+{
+  const char * section_name;
+  section * sec;
+
+  if (!decl || TREE_CODE (decl) != FUNCTION_DECL)
+    return default_function_section (decl, freq, startup, exit);
+
+  if (!target_pure_code)
+    return default_function_section (decl, freq, startup, exit);
+
+
+  section_name = DECL_SECTION_NAME (decl);
+
+  /* If a function is not in a named section then it falls under the 'default'
+     text section, also known as '.text'.  We can preserve previous behavior as
+     the default text section already has the SHF_ARM_PURECODE section
+     attribute.  */
+  if (!section_name)
+    {
+      section *default_sec = default_function_section (decl, freq, startup,
+						       exit);
+
+      /* If default_sec is not null, then it must be a special section like for
+	 example .text.startup.  We set the pure-code attribute and return the
+	 same section to preserve existing behavior.  */
+      if (default_sec)
+	  default_sec->common.flags |= SECTION_ARM_PURECODE;
+      return default_sec;
+    }
+
+  /* Otherwise look whether a section has already been created with
+     'section_name'.  */
+  sec = get_named_section (decl, section_name, 0);
+  if (!sec)
+    /* If that is not the case passing NULL as the section's name to
+       'get_named_section' will create a section with the declaration's
+       section name.  */
+    sec = get_named_section (decl, NULL, 0);
+
+  /* Set the SHF_ARM_PURECODE attribute.  */
+  sec->common.flags |= SECTION_ARM_PURECODE;
+
+  return sec;
+}
+
+/* Implements the TARGET_SECTION_FLAGS hook.
+
+   If DECL is a function declaration and pure-code is passed as an option
+   then add the SFH_ARM_PURECODE attribute to the section flags.  NAME is the
+   section's name and RELOC indicates whether the declarations initializer may
+   contain runtime relocations.  */
+
+static unsigned int
+arm_elf_section_type_flags (tree decl, const char *name, int reloc)
+{
+  unsigned int flags = default_section_type_flags (decl, name, reloc);
+
+  if (decl && TREE_CODE (decl) == FUNCTION_DECL && target_pure_code)
+    flags |= SECTION_ARM_PURECODE;
+
+  return flags;
+}
+
 #include "gt-arm.h"
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 16498316bee9f19baff414885efe1e78191da047..9f49ab6014e61e7b49972f29c96ad03c11101aa1 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -8180,7 +8180,7 @@
    (match_operand:SI 2 "const_int_operand" "")	; total range
    (match_operand:SI 3 "" "")			; table label
    (match_operand:SI 4 "" "")]			; Out of range label
-  "TARGET_32BIT || optimize_size || flag_pic"
+  "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
   "
   {
     enum insn_code code;
diff --git a/gcc/config/arm/arm.opt b/gcc/config/arm/arm.opt
index 0ebe0174390167b79a64583c35a3f8fb018f6538..35f047e2de1659c2b426cf42dbbdae5be62cbfef 100644
--- a/gcc/config/arm/arm.opt
+++ b/gcc/config/arm/arm.opt
@@ -281,3 +281,7 @@ Assume loading data from flash is slower than fetching instructions.
 masm-syntax-unified
 Target Report Var(inline_asm_unified) Init(0) Save
 Assume unified syntax for inline assembly code.
+
+mpure-code
+Target Report Var(target_pure_code) Init(0)
+Do not allow constant data to be placed in code sections.
diff --git a/gcc/config/arm/elf.h b/gcc/config/arm/elf.h
index 77f30554d5286bd83aeab0c8dc308cfd44e732dc..395a22282be0cd2edc9459e1ba14d7848073fa5d 100644
--- a/gcc/config/arm/elf.h
+++ b/gcc/config/arm/elf.h
@@ -104,7 +104,8 @@
    the code more efficient, but for Thumb-1 it's better to put them out of
    band unless we are generating compressed tables.  */
 #define JUMP_TABLES_IN_TEXT_SECTION					\
-   (TARGET_32BIT || (TARGET_THUMB && (optimize_size || flag_pic)))
+   ((TARGET_32BIT || (TARGET_THUMB && (optimize_size || flag_pic))) \
+    && !target_pure_code)
 
 #ifndef LINK_SPEC
 #define LINK_SPEC "%{mbig-endian:-EB} %{mlittle-endian:-EL} -X"
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 4f24daebc01f0fd006540df8d863014aa864d060..7bb81ce49e4d1b45b1e1b7892ac3152a53eb3237 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -639,7 +639,8 @@ Objective-C and Objective-C++ Dialects}.
 -mneon-for-64bits @gol
 -mslow-flash-data @gol
 -masm-syntax-unified @gol
--mrestrict-it}
+-mrestrict-it @gol
+-mpure-code}
 
 @emph{AVR Options}
 @gccoptlist{-mmcu=@var{mcu} -maccumulate-args -mbranch-cost=@var{cost} @gol
@@ -14498,6 +14499,14 @@ Print CPU tuning information as comment in assembler file.  This is
 an option used only for regression testing of the compiler and not
 intended for ordinary use in compiling code.  This option is disabled
 by default.
+
+@item -mpure-code
+@opindex mpure-code
+Do not allow constant data to be placed in code sections.
+Additionally, when compiling for ELF object format give all text sections the
+ELF processor-specific section attribute @code{SHF_ARM_PURECODE}.  This option
+is only available when generating non-pic code for ARMv7-M targets.
+
 @end table
 
 @node AVR Options
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index b318615b7b35ab93ad13e5e535a1d4e6d02cb7f7..2c717960d8cea72a93da6e23abcd01aed3b37d6e 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -7543,6 +7543,18 @@ is non-NULL, it is the @code{VAR_DECL} or @code{FUNCTION_DECL} with which
 this section is associated.
 @end deftypefn
 
+@deftypefn {Target Hook} bool TARGET_ASM_ELF_FLAGS_NUMERIC (unsigned int @var{flags}, unsigned int *@var{num})
+This hook can be used to encode ELF section flags for which no letter
+code has been defined in the assembler.  It is called by
+@code{default_asm_named_section} whenever the section flags need to be
+emitted in the assembler output.  If the hook returns true, then the
+numerical value for ELF section flags should be calculated from
+@var{flags} and saved in @var{*num}; the value will be printed out
+instead of the normal sequence of letter codes.  If the hook is not
+defined, or if it returns false, then @var{num} will be ignored and the
+traditional letter sequence will be emitted.
+@end deftypefn
+
 @deftypefn {Target Hook} {section *} TARGET_ASM_FUNCTION_SECTION (tree @var{decl}, enum node_frequency @var{freq}, bool @var{startup}, bool @var{exit})
 Return preferred text (sub)section for function @var{decl}.
 Main purpose of this function is to separate cold, normal and hot
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 1e8423cb4e255acd8144e4b105186cee3d1d04fd..17a2ca73f07516526543253c77c088c73326af2c 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -5229,6 +5229,8 @@ of the filename using this macro.
 
 @hook TARGET_ASM_NAMED_SECTION
 
+@hook TARGET_ASM_ELF_FLAGS_NUMERIC
+
 @hook TARGET_ASM_FUNCTION_SECTION
 
 @hook TARGET_ASM_FUNCTION_SWITCHED_TEXT_SECTIONS
diff --git a/gcc/hooks.c b/gcc/hooks.c
index 99ec4014adb6fcbb073bf538dd00fe8695ee6cb2..1e925645c3173f8d97e104b9b2f480fca2ede438 100644
--- a/gcc/hooks.c
+++ b/gcc/hooks.c
@@ -481,3 +481,13 @@ void
 hook_void_gcc_optionsp (struct gcc_options *opts ATTRIBUTE_UNUSED)
 {
 }
+
+/* Generic hook that takes an unsigned int, an unsigned int pointer and
+   returns false.  */
+
+bool
+hook_uint_uintp_false (unsigned int, unsigned int *)
+{
+  return false;
+}
+
diff --git a/gcc/target.def b/gcc/target.def
index a4df363698ce776b51d11c187baed2069ba88a52..dc5a39aa724b05a3adb06c3af1b24fdff0d428c1 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -432,6 +432,22 @@ this section is associated.",
  void, (const char *name, unsigned int flags, tree decl),
  default_no_named_section)
 
+/* Tell assembler what section attributes to assign this elf section
+   declaration, using their numerical value.  */
+DEFHOOK
+(elf_flags_numeric,
+ "This hook can be used to encode ELF section flags for which no letter\n\
+code has been defined in the assembler.  It is called by\n\
+@code{default_asm_named_section} whenever the section flags need to be\n\
+emitted in the assembler output.  If the hook returns true, then the\n\
+numerical value for ELF section flags should be calculated from\n\
+@var{flags} and saved in @var{*num}; the value will be printed out\n\
+instead of the normal sequence of letter codes.  If the hook is not\n\
+defined, or if it returns false, then @var{num} will be ignored and the\n\
+traditional letter sequence will be emitted.",
+ bool, (unsigned int flags, unsigned int *num),
+ hook_uint_uintp_false)
+
 /* Return preferred text (sub)section for function DECL.
    Main purpose of this function is to separate cold, normal and hot
    functions. STARTUP is true when function is known to be used only 
diff --git a/gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c b/gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c
new file mode 100644
index 0000000000000000000000000000000000000000..26fe38c05295b70ccc35ed900d41b34aae2c87a8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-fpic" "-fPIC" } { "" } } */
+/* { dg-options "-ffunction-sections -mpure-code" } */
+#include <limits.h>
+
+char * foo (void)
+{
+  return "foo";
+}
+
+unsigned int bar (unsigned int b)
+{
+  return UINT_MAX - b;
+}
+
+/* { dg-final { scan-assembler {\.section\t\.text\.foo[^\n]*\"0x20000006\"} } } */
+/* { dg-final { scan-assembler {\.section\t\.text\.bar[^\n]*\"0x20000006\"} } } */
diff --git a/gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c b/gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c
new file mode 100644
index 0000000000000000000000000000000000000000..ba116a8261b16610e6af47d26a6e1a07b0127561
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-mpure-code" } */
+/* { dg-skip-if "" { *-*-* } { "-g" "-fpic" "-fPIC" } { "" } } */
+
+extern int foo (void);
+extern int bar (void);
+extern int baz (void);
+extern int fooz (void);
+
+int caller (unsigned int reg_type)
+{
+  switch (reg_type)
+    {
+    case 0x80000000:
+      return (int) foo ();
+
+    case 0x80000003:
+      return (int) bar ();
+
+    case 0x80000001:
+      return (int) baz ();
+
+    case 0x80000004:
+      return (int) fooz ();
+    }
+}
+
+/* { dg-final { scan-assembler-not "\\.(float|l\\?double|\d?byte|short|int|long|quad|word)\\s+\[^.\]" } } */
+/* { dg-final { scan-assembler "text,\"0x20000006\"" } } */
diff --git a/gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c b/gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c
new file mode 100644
index 0000000000000000000000000000000000000000..4b893fd32f722e6cd7dfde5c8542ab98327ba375
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-mpure-code" } */
+/* { dg-skip-if "" { *-*-* } { "-g" "-fpic" "-fPIC" } { "" } } */
+
+float sf;
+double df;
+long long l;
+static char *p = "Hello World";
+
+float
+testsf (float *p)
+{
+  if (*p > 1.1234f)
+    return 2.1234f;
+  else
+    return 3.1234f;
+}
+
+double
+testdf (double *p)
+{
+  if (*p > 4.1234)
+    return 2.1234;
+  else
+    return 3.1234;
+}
+
+long long
+testll (long long *p)
+{
+  if (*p > 0x123456789ABCDEFll)
+    return 0x111111111ll;
+  else
+    return 0x222222222ll;
+}
+
+char *
+testchar ()
+{
+  return p + 4;
+}
+
+int
+foo (int a, int b)
+{
+  int i;
+  volatile int *labelref = &&label1;
+
+  if (a > b)
+    {
+      while (i < b)
+	{
+	  a += *labelref;
+	  i += 1;
+	}
+      goto *labelref;
+    }
+  else
+    b = b + 3;
+
+  a = a * b;
+
+label1:
+  return a + b;
+}
+
+/* { dg-final { scan-assembler-not "\\.(float|l\\?double|\d?byte|short|int|long|quad|word)\\s+\[^.\]" } } */
+/* { dg-final { scan-assembler "text,\"0x20000006\"" } } */
diff --git a/gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp b/gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp
new file mode 100644
index 0000000000000000000000000000000000000000..1abe7782c0e5dbb6e2deef25f4bea9415664f942
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp
@@ -0,0 +1,54 @@
+#   Copyright (C) 1997-2016 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
+# <http://www.gnu.org/licenses/>.
+
+# GCC testsuite for ARM's -mpure-code option, using the `dg.exp' driver.
+
+# 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"
+}
+
+# The -mpure-code option is only available for M-profile targets that support
+# thumb2.
+if {[check_effective_target_arm_thumb2_ok]
+    && ![check_effective_target_arm_arm_ok]} then {
+# Initialize `dg'.
+dg-init
+
+set saved-dg-do-what-default ${dg-do-what-default}
+set dg-do-what-default "assemble"
+
+set saved-lto_torture_options ${LTO_TORTURE_OPTIONS}
+
+# Add -ffat-lto-objects option to all LTO options such that we can do assembly
+# scans.
+proc add_fat_objects { list } {
+    set res {}
+    foreach el $list {set res [lappend res [concat $el " -ffat-lto-objects"]]}
+    return $res
+};
+set LTO_TORTURE_OPTIONS [add_fat_objects ${LTO_TORTURE_OPTIONS}]
+
+gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] \
+	"" $DEFAULT_CFLAGS
+
+# All done.
+dg-finish
+}
diff --git a/gcc/varasm.c b/gcc/varasm.c
index de8bcd6f20c823acd03991f813da3521b80547ff..c72c779484fd2ba7bdc58285437ef89ec9effbad 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6244,6 +6244,7 @@ default_elf_asm_named_section (const char *name, unsigned int flags,
 			       tree decl)
 {
   char flagchars[11], *f = flagchars;
+  unsigned int numeric_value = 0;
 
   /* If we have already declared this section, we can use an
      abbreviated form to switch back to it -- unless this section is
@@ -6256,31 +6257,38 @@ default_elf_asm_named_section (const char *name, unsigned int flags,
       return;
     }
 
-  if (!(flags & SECTION_DEBUG))
-    *f++ = 'a';
+  /* If we have a machine specific flag, then use the numeric value to pass
+     this on to GAS.  */
+  if (targetm.asm_out.elf_flags_numeric (flags, &numeric_value))
+      snprintf (f, sizeof (flagchars), "0x%08x", numeric_value);
+  else
+    {
+      if (!(flags & SECTION_DEBUG))
+	*f++ = 'a';
 #if defined (HAVE_GAS_SECTION_EXCLUDE) && HAVE_GAS_SECTION_EXCLUDE == 1
-  if (flags & SECTION_EXCLUDE)
-    *f++ = 'e';
+      if (flags & SECTION_EXCLUDE)
+	*f++ = 'e';
 #endif
-  if (flags & SECTION_WRITE)
-    *f++ = 'w';
-  if (flags & SECTION_CODE)
-    *f++ = 'x';
-  if (flags & SECTION_SMALL)
-    *f++ = 's';
-  if (flags & SECTION_MERGE)
-    *f++ = 'M';
-  if (flags & SECTION_STRINGS)
-    *f++ = 'S';
-  if (flags & SECTION_TLS)
-    *f++ = TLS_SECTION_ASM_FLAG;
-  if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
-    *f++ = 'G';
+      if (flags & SECTION_WRITE)
+	*f++ = 'w';
+      if (flags & SECTION_CODE)
+	*f++ = 'x';
+      if (flags & SECTION_SMALL)
+	*f++ = 's';
+      if (flags & SECTION_MERGE)
+	*f++ = 'M';
+      if (flags & SECTION_STRINGS)
+	*f++ = 'S';
+      if (flags & SECTION_TLS)
+	*f++ = TLS_SECTION_ASM_FLAG;
+      if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
+	*f++ = 'G';
 #ifdef MACH_DEP_SECTION_ASM_FLAG
-  if (flags & SECTION_MACH_DEP)
-    *f++ = MACH_DEP_SECTION_ASM_FLAG;
+      if (flags & SECTION_MACH_DEP)
+	*f++ = MACH_DEP_SECTION_ASM_FLAG;
 #endif
-  *f = '\0';
+      *f = '\0';
+    }
 
   fprintf (asm_out_file, "\t.section\t%s,\"%s\"", name, flagchars);
 
-- 
1.9.1


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCHv3][ARM] -mpure-code option for ARM
  2016-09-22 17:24           ` Andre Vieira (lists)
@ 2016-09-22 19:34             ` Christophe Lyon
  2016-09-22 20:05             ` Bill Seurer
  2016-09-22 20:20             ` Paolo Carlini
  2 siblings, 0 replies; 24+ messages in thread
From: Christophe Lyon @ 2016-09-22 19:34 UTC (permalink / raw)
  To: Andre Vieira (lists); +Cc: Richard Earnshaw (lists), gcc-patches

Hi Andre,


On 22 September 2016 at 19:04, Andre Vieira (lists)
<Andre.SimoesDiasVieira@arm.com> wrote:
> On 22/09/16 16:28, Richard Earnshaw (lists) wrote:
>> On 22/09/16 16:04, Andre Vieira (lists) wrote:
>>>
>>> I reworked the patch according to the comments above.
>>>
>>> Is this OK?
>>>
>>> gcc/ChangeLog:
>>> 2016-09-22  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>>             Terry Guo  <terry.guo@arm.com>
>>>
>>>         * target.def (elf_flags_numeric): New target hook.
>>>         * targhooks.h (default_asm_elf_flags_numeric): New.
>>>         * varasm.c (default_asm_elf_flags_numeric): New.
>>>           (default_elf_asm_named_section): Use new target hook.
>>>         * config/arm/arm.opt (mpure-code): New.
>>>         * config/arm/arm.h (SECTION_ARM_PURECODE): New.
>>>         * config/arm/arm.c (arm_asm_init_sections): Add section
>>>           attribute to default text section if -mpure-code.
>>>           (arm_option_check_internal): Diagnose use of option with
>>>           non supported targets and/or options.
>>>           (arm_asm_elf_flags_numeric): New.
>>>           (arm_function_section): New.
>>>           (arm_elf_section_type_flags): New.
>>>         * config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Disable
>>>           for -mpure-code.
>>>         * gcc/doc/texi (TARGET_ASM_ELF_FLAGS_NUMERIC): New.
>>>         * gcc/doc/texi.in (TARGET_ASM_ELF_FLAGS_NUMERIC): Likewise.
>>>
>>>
>>>
>>> gcc/testsuite/ChangeLog:
>>> 2016-09-22  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>>             Terry Guo  <terry.guo@arm.com>
>>>
>>>         * gcc.target/arm/pure-code/ffunction-sections.c: New.
>>>         * gcc.target/arm/pure-code/no-literal-pool.c: New.
>>>         * gcc.target/arm/pure-code/pure-code.exp: New.
>>>
>>>
>>
>> I missed this last time around, but please can you wrap references to
>> SHF_ARM_PURECODE in the documentation with @code{...}.
>>
>> OK with that change.
>>
>> R.
>
> Done. Committed as revision r240379.
>
This patch broke the aarch64 builds:
/tmp/9380062_6.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/config/aarch64/aarch64.c:14391:
error: ‘hook_uint_uintp_false’ was not declared in this s
cope
/tmp/9380062_6.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/config/aarch64/aarch64.c:14391:
error: too many initializers for ‘gcc_target::asm_out’
make[2]: *** [aarch64.o] Error 1
make[2]: Leaving directory
`/tmp/9380062_6.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-aarch64-none-linux-gnu/gcc1/gcc'
make[1]: *** [all-gcc] Error 2
make[1]: Leaving directory
`/tmp/9380062_6.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-aarch64-none-linux-gnu/gcc1'
make: *** [all] Error 2

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCHv3][ARM] -mpure-code option for ARM
  2016-09-22 17:24           ` Andre Vieira (lists)
  2016-09-22 19:34             ` Christophe Lyon
@ 2016-09-22 20:05             ` Bill Seurer
  2016-09-22 20:30               ` Martin Sebor
  2016-09-22 20:20             ` Paolo Carlini
  2 siblings, 1 reply; 24+ messages in thread
From: Bill Seurer @ 2016-09-22 20:05 UTC (permalink / raw)
  To: Andre Vieira (lists), Richard Earnshaw (lists), gcc-patches

This patch breaks compilation on power:

g++ -fno-PIE -c   -g -O2 -DIN_GCC     -fno-exceptions -fno-rtti 
-fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings 
-Wcast-qual -Wmissing-format-attribute -Woverloaded-virtual -pedantic 
-Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -fno-common 
-DHAVE_CONFIG_H -I. -I. -I/home/seurer/gcc/gcc-test2/gcc 
-I/home/seurer/gcc/gcc-test2/gcc/. 
-I/home/seurer/gcc/gcc-test2/gcc/../include 
-I/home/seurer/gcc/gcc-test2/gcc/../libcpp/include 
-I/home/seurer/gcc/gcc-test2/gcc/../libdecnumber 
-I/home/seurer/gcc/gcc-test2/gcc/../libdecnumber/dpd -I../libdecnumber 
-I/home/seurer/gcc/gcc-test2/gcc/../libbacktrace   -o rs6000.o -MT 
rs6000.o -MMD -MP -MF ./.deps/rs6000.TPo 
/home/seurer/gcc/gcc-test2/gcc/config/rs6000/rs6000.c
In file included from /home/seurer/gcc/gcc-test2/gcc/target-def.h:106:0,
                  from 
/home/seurer/gcc/gcc-test2/gcc/config/rs6000/rs6000.c:77:
./target-hooks-def.h:92:38: error: 'hook_uint_uintp_false' was not 
declared in this scope
  #define TARGET_ASM_ELF_FLAGS_NUMERIC hook_uint_uintp_false
                                       ^
./target-hooks-def.h:2205:5: note: in expansion of macro 
'TARGET_ASM_ELF_FLAGS_NUMERIC'
      TARGET_ASM_ELF_FLAGS_NUMERIC, \
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
./target-hooks-def.h:1792:5: note: in expansion of macro 'TARGET_ASM_OUT'
      TARGET_ASM_OUT, \
      ^~~~~~~~~~~~~~
/home/seurer/gcc/gcc-test2/gcc/config/rs6000/rs6000.c:40709:29: note: in 
expansion of macro 'TARGET_INITIALIZER'
  struct gcc_target targetm = TARGET_INITIALIZER;
                              ^~~~~~~~~~~~~~~~~~
make[2]: *** [rs6000.o] Error 1


On 09/22/16 12:04, Andre Vieira (lists) wrote:
> On 22/09/16 16:28, Richard Earnshaw (lists) wrote:
>> On 22/09/16 16:04, Andre Vieira (lists) wrote:
>>>
>>> I reworked the patch according to the comments above.
>>>
>>> Is this OK?
>>>
>>> gcc/ChangeLog:
>>> 2016-09-22  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>>             Terry Guo  <terry.guo@arm.com>
>>>
>>>         * target.def (elf_flags_numeric): New target hook.
>>>         * targhooks.h (default_asm_elf_flags_numeric): New.
>>>         * varasm.c (default_asm_elf_flags_numeric): New.
>>>           (default_elf_asm_named_section): Use new target hook.
>>>         * config/arm/arm.opt (mpure-code): New.
>>>         * config/arm/arm.h (SECTION_ARM_PURECODE): New.
>>>         * config/arm/arm.c (arm_asm_init_sections): Add section
>>>           attribute to default text section if -mpure-code.
>>>           (arm_option_check_internal): Diagnose use of option with
>>>           non supported targets and/or options.
>>>           (arm_asm_elf_flags_numeric): New.
>>>           (arm_function_section): New.
>>>           (arm_elf_section_type_flags): New.
>>>         * config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Disable
>>>           for -mpure-code.
>>>         * gcc/doc/texi (TARGET_ASM_ELF_FLAGS_NUMERIC): New.
>>>         * gcc/doc/texi.in (TARGET_ASM_ELF_FLAGS_NUMERIC): Likewise.
>>>
>>>
>>>
>>> gcc/testsuite/ChangeLog:
>>> 2016-09-22  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>>             Terry Guo  <terry.guo@arm.com>
>>>
>>>         * gcc.target/arm/pure-code/ffunction-sections.c: New.
>>>         * gcc.target/arm/pure-code/no-literal-pool.c: New.
>>>         * gcc.target/arm/pure-code/pure-code.exp: New.
>>>
>>>
>>
>> I missed this last time around, but please can you wrap references to
>> SHF_ARM_PURECODE in the documentation with @code{...}.
>>
>> OK with that change.
>>
>> R.
>
> Done. Committed as revision r240379.
>


-- 

-Bill Seurer

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCHv3][ARM] -mpure-code option for ARM
  2016-09-22 17:24           ` Andre Vieira (lists)
  2016-09-22 19:34             ` Christophe Lyon
  2016-09-22 20:05             ` Bill Seurer
@ 2016-09-22 20:20             ` Paolo Carlini
  2 siblings, 0 replies; 24+ messages in thread
From: Paolo Carlini @ 2016-09-22 20:20 UTC (permalink / raw)
  To: Andre Vieira (lists), Richard Earnshaw (lists),
	gcc-patches, Jakub Jelinek

[-- Attachment #1: Type: text/plain, Size: 779 bytes --]

Hi,

On 22/09/2016 19:04, Andre Vieira (lists) wrote:
> diff --git a/gcc/hooks.c b/gcc/hooks.c
> index 99ec4014adb6fcbb073bf538dd00fe8695ee6cb2..1e925645c3173f8d97e104b9b2f480fca2ede438 100644
> --- a/gcc/hooks.c
> +++ b/gcc/hooks.c
> @@ -481,3 +481,13 @@ void
>   hook_void_gcc_optionsp (struct gcc_options *opts ATTRIBUTE_UNUSED)
>   {
>   }
> +
> +/* Generic hook that takes an unsigned int, an unsigned int pointer and
> +   returns false.  */
> +
> +bool
> +hook_uint_uintp_false (unsigned int, unsigned int *)
> +{
> +  return false;
> +}
> +

I don't see this change in the committed ChangeLog and, as is, it 
doesn't have a counterpart in hooks.h. Something as trivial as the below 
fixes the bootstrap error for me on x86_64-linux.

Thanks,
Paolo.

////////////////////

[-- Attachment #2: p --]
[-- Type: text/plain, Size: 528 bytes --]

Index: hooks.h
===================================================================
--- hooks.h	(revision 240379)
+++ hooks.h	(working copy)
@@ -76,6 +76,7 @@ extern void hook_void_tree (tree);
 extern void hook_void_tree_treeptr (tree, tree *);
 extern void hook_void_int_int (int, int);
 extern void hook_void_gcc_optionsp (struct gcc_options *);
+extern bool hook_uint_uintp_false (unsigned int, unsigned int *);
 
 extern int hook_int_uint_mode_1 (unsigned int, machine_mode);
 extern int hook_int_const_tree_0 (const_tree);

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCHv3][ARM] -mpure-code option for ARM
  2016-09-22 20:05             ` Bill Seurer
@ 2016-09-22 20:30               ` Martin Sebor
  0 siblings, 0 replies; 24+ messages in thread
From: Martin Sebor @ 2016-09-22 20:30 UTC (permalink / raw)
  To: Bill Seurer, Andre Vieira (lists), Richard Earnshaw (lists), gcc-patches

FYI (to help avoid raising duplicate bugs), I opened bug 77695
for the bootstrap failure.

Martin

On 09/22/2016 01:33 PM, Bill Seurer wrote:
> This patch breaks compilation on power:
>
> g++ -fno-PIE -c   -g -O2 -DIN_GCC     -fno-exceptions -fno-rtti
> -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings
> -Wcast-qual -Wmissing-format-attribute -Woverloaded-virtual -pedantic
> -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -fno-common
> -DHAVE_CONFIG_H -I. -I. -I/home/seurer/gcc/gcc-test2/gcc
> -I/home/seurer/gcc/gcc-test2/gcc/.
> -I/home/seurer/gcc/gcc-test2/gcc/../include
> -I/home/seurer/gcc/gcc-test2/gcc/../libcpp/include
> -I/home/seurer/gcc/gcc-test2/gcc/../libdecnumber
> -I/home/seurer/gcc/gcc-test2/gcc/../libdecnumber/dpd -I../libdecnumber
> -I/home/seurer/gcc/gcc-test2/gcc/../libbacktrace   -o rs6000.o -MT
> rs6000.o -MMD -MP -MF ./.deps/rs6000.TPo
> /home/seurer/gcc/gcc-test2/gcc/config/rs6000/rs6000.c
> In file included from /home/seurer/gcc/gcc-test2/gcc/target-def.h:106:0,
>                  from
> /home/seurer/gcc/gcc-test2/gcc/config/rs6000/rs6000.c:77:
> ./target-hooks-def.h:92:38: error: 'hook_uint_uintp_false' was not
> declared in this scope
>  #define TARGET_ASM_ELF_FLAGS_NUMERIC hook_uint_uintp_false
>                                       ^
> ./target-hooks-def.h:2205:5: note: in expansion of macro
> 'TARGET_ASM_ELF_FLAGS_NUMERIC'
>      TARGET_ASM_ELF_FLAGS_NUMERIC, \
>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
> ./target-hooks-def.h:1792:5: note: in expansion of macro 'TARGET_ASM_OUT'
>      TARGET_ASM_OUT, \
>      ^~~~~~~~~~~~~~
> /home/seurer/gcc/gcc-test2/gcc/config/rs6000/rs6000.c:40709:29: note: in
> expansion of macro 'TARGET_INITIALIZER'
>  struct gcc_target targetm = TARGET_INITIALIZER;
>                              ^~~~~~~~~~~~~~~~~~
> make[2]: *** [rs6000.o] Error 1
>
>
> On 09/22/16 12:04, Andre Vieira (lists) wrote:
>> On 22/09/16 16:28, Richard Earnshaw (lists) wrote:
>>> On 22/09/16 16:04, Andre Vieira (lists) wrote:
>>>>
>>>> I reworked the patch according to the comments above.
>>>>
>>>> Is this OK?
>>>>
>>>> gcc/ChangeLog:
>>>> 2016-09-22  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>>>             Terry Guo  <terry.guo@arm.com>
>>>>
>>>>         * target.def (elf_flags_numeric): New target hook.
>>>>         * targhooks.h (default_asm_elf_flags_numeric): New.
>>>>         * varasm.c (default_asm_elf_flags_numeric): New.
>>>>           (default_elf_asm_named_section): Use new target hook.
>>>>         * config/arm/arm.opt (mpure-code): New.
>>>>         * config/arm/arm.h (SECTION_ARM_PURECODE): New.
>>>>         * config/arm/arm.c (arm_asm_init_sections): Add section
>>>>           attribute to default text section if -mpure-code.
>>>>           (arm_option_check_internal): Diagnose use of option with
>>>>           non supported targets and/or options.
>>>>           (arm_asm_elf_flags_numeric): New.
>>>>           (arm_function_section): New.
>>>>           (arm_elf_section_type_flags): New.
>>>>         * config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Disable
>>>>           for -mpure-code.
>>>>         * gcc/doc/texi (TARGET_ASM_ELF_FLAGS_NUMERIC): New.
>>>>         * gcc/doc/texi.in (TARGET_ASM_ELF_FLAGS_NUMERIC): Likewise.
>>>>
>>>>
>>>>
>>>> gcc/testsuite/ChangeLog:
>>>> 2016-09-22  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>>>             Terry Guo  <terry.guo@arm.com>
>>>>
>>>>         * gcc.target/arm/pure-code/ffunction-sections.c: New.
>>>>         * gcc.target/arm/pure-code/no-literal-pool.c: New.
>>>>         * gcc.target/arm/pure-code/pure-code.exp: New.
>>>>
>>>>
>>>
>>> I missed this last time around, but please can you wrap references to
>>> SHF_ARM_PURECODE in the documentation with @code{...}.
>>>
>>> OK with that change.
>>>
>>> R.
>>
>> Done. Committed as revision r240379.
>>
>
>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCHv2][ARM] -mpure-code option for ARM
  2016-09-22 14:22     ` [PATCHv2][ARM] " Richard Earnshaw (lists)
  2016-09-22 15:10       ` [PATCHv3][ARM] " Andre Vieira (lists)
@ 2016-09-23  6:31       ` Sandra Loosemore
  2016-09-23  8:51         ` Andre Vieira (lists)
  1 sibling, 1 reply; 24+ messages in thread
From: Sandra Loosemore @ 2016-09-23  6:31 UTC (permalink / raw)
  To: Richard Earnshaw (lists), Andre Vieira (lists), GCC Patches; +Cc: mickael guene

On 09/22/2016 07:52 AM, Richard Earnshaw (lists) wrote:
> On 11/07/16 17:56, Andre Vieira (lists) wrote:
>> +
>> diff --git a/gcc/target.def b/gcc/target.def
>> index a4df363698ce776b51d11c187baed2069ba88a52..a3d46fa48d919a16699c33b2b78236e62a33e025 100644
>> --- a/gcc/target.def
>> +++ b/gcc/target.def
>> @@ -432,6 +432,19 @@ this section is associated.",
>>    void, (const char *name, unsigned int flags, tree decl),
>>    default_no_named_section)
>>
>> +/* Tell assembler what section attributes to assign this elf section
>> +   declaration, using their numerical value.  */
>> +DEFHOOK
>> +(elf_flags_numeric,
>> + "If the target needs to represent ELF section attributes using their\n\
>> +numerical value, then this hook should be implemented to return true and\n\
>> +write the numerical value of @var{flags} in @var{num}.  This function is\n\
>> +called by @code{default_elf_asm_named_section}, which prints @var{num}\n\
>> +as the value representing the ELF section attributes if this function\n\
>> +returns true.",
>
>
> I think this should read something like.
>
> This hook can be used to encode ELF section flags for which no letter
> code has been defined in the assembler.  It is called by
> @code{default_asm_named_section} whenever the section flags need to be
> emitted in the assembler output.  If the hook returns true, then the
> numerical value for ELF section flags should be calculated from
> @var{flags} and saved in @var{*num}; the value will be printed out
> instead of the normal sequence of letter codes.  If the hook is not
> defined, or if it returns false, then @var{num} will be ignored and the
> traditional letter sequence will be emitted.

Can we please write this in the present tense instead of the future, 
assuming it describes current behavior (as modified by the patch)?

s/will be/is/g

-Sandra

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCHv2][ARM] -mpure-code option for ARM
  2016-09-23  6:31       ` [PATCHv2][ARM] " Sandra Loosemore
@ 2016-09-23  8:51         ` Andre Vieira (lists)
  2016-09-23 10:41           ` Andre Vieira (lists)
  0 siblings, 1 reply; 24+ messages in thread
From: Andre Vieira (lists) @ 2016-09-23  8:51 UTC (permalink / raw)
  To: gcc-patches, Sandra Loosemore

[-- Attachment #1: Type: text/plain, Size: 2172 bytes --]

On 23/09/16 02:21, Sandra Loosemore wrote:
> On 09/22/2016 07:52 AM, Richard Earnshaw (lists) wrote:
>> On 11/07/16 17:56, Andre Vieira (lists) wrote:
>>> +
>>> diff --git a/gcc/target.def b/gcc/target.def
>>> index
>>> a4df363698ce776b51d11c187baed2069ba88a52..a3d46fa48d919a16699c33b2b78236e62a33e025
>>> 100644
>>> --- a/gcc/target.def
>>> +++ b/gcc/target.def
>>> @@ -432,6 +432,19 @@ this section is associated.",
>>>    void, (const char *name, unsigned int flags, tree decl),
>>>    default_no_named_section)
>>>
>>> +/* Tell assembler what section attributes to assign this elf section
>>> +   declaration, using their numerical value.  */
>>> +DEFHOOK
>>> +(elf_flags_numeric,
>>> + "If the target needs to represent ELF section attributes using
>>> their\n\
>>> +numerical value, then this hook should be implemented to return true
>>> and\n\
>>> +write the numerical value of @var{flags} in @var{num}.  This
>>> function is\n\
>>> +called by @code{default_elf_asm_named_section}, which prints
>>> @var{num}\n\
>>> +as the value representing the ELF section attributes if this
>>> function\n\
>>> +returns true.",
>>
>>
>> I think this should read something like.
>>
>> This hook can be used to encode ELF section flags for which no letter
>> code has been defined in the assembler.  It is called by
>> @code{default_asm_named_section} whenever the section flags need to be
>> emitted in the assembler output.  If the hook returns true, then the
>> numerical value for ELF section flags should be calculated from
>> @var{flags} and saved in @var{*num}; the value will be printed out
>> instead of the normal sequence of letter codes.  If the hook is not
>> defined, or if it returns false, then @var{num} will be ignored and the
>> traditional letter sequence will be emitted.
> 
> Can we please write this in the present tense instead of the future,
> assuming it describes current behavior (as modified by the patch)?
> 
> s/will be/is/g
> 
> -Sandra
> 
Hi Sandra,

Is this better?

Cheers,
Andre

gcc/ChangeLog
2016-09-23  Andre Vieira  <andre.simoesdiasvieira@arm.com>

        * target.def(elf_flags_numeric): Change documentation to
        present tense.

[-- Attachment #2: 0001-Language-fix-for-elf_flags_numeric-doc.patch --]
[-- Type: text/x-patch, Size: 1400 bytes --]

From 459abfbbd836aa11e71dd90b9466c60b1155fba0 Mon Sep 17 00:00:00 2001
From: Andre Simoes Dias Vieira <andre.simoesdiasvieira@arm.com>
Date: Fri, 23 Sep 2016 09:16:17 +0100
Subject: [PATCH] Language fix for elf_flags_numeric doc

---
 gcc/target.def | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/gcc/target.def b/gcc/target.def
index ac693318adaaa230ea300f10bc37282881d9da6f..4adb8aabc6548889b717abc9310e98f0e6fc161b 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -441,10 +441,10 @@ code has been defined in the assembler.  It is called by\n\
 @code{default_asm_named_section} whenever the section flags need to be\n\
 emitted in the assembler output.  If the hook returns true, then the\n\
 numerical value for ELF section flags should be calculated from\n\
-@var{flags} and saved in @var{*num}; the value will be printed out\n\
-instead of the normal sequence of letter codes.  If the hook is not\n\
-defined, or if it returns false, then @var{num} will be ignored and the\n\
-traditional letter sequence will be emitted.",
+@var{flags} and saved in @var{*num}; the value is printed out instead of the\n\
+normal sequence of letter codes.  If the hook is not defined, or if it\n\
+returns false, then @var{num} is ignored and the traditional letter sequence\n\
+is emitted.",
  bool, (unsigned int flags, unsigned int *num),
  hook_uint_uintp_false)
 
-- 
1.9.1


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCHv2][ARM] -mpure-code option for ARM
  2016-09-23  8:51         ` Andre Vieira (lists)
@ 2016-09-23 10:41           ` Andre Vieira (lists)
  2016-09-23 15:12             ` Sandra Loosemore
  0 siblings, 1 reply; 24+ messages in thread
From: Andre Vieira (lists) @ 2016-09-23 10:41 UTC (permalink / raw)
  To: gcc-patches, Sandra Loosemore

[-- Attachment #1: Type: text/plain, Size: 2559 bytes --]

On 23/09/16 09:33, Andre Vieira (lists) wrote:
> On 23/09/16 02:21, Sandra Loosemore wrote:
>> On 09/22/2016 07:52 AM, Richard Earnshaw (lists) wrote:
>>> On 11/07/16 17:56, Andre Vieira (lists) wrote:
>>>> +
>>>> diff --git a/gcc/target.def b/gcc/target.def
>>>> index
>>>> a4df363698ce776b51d11c187baed2069ba88a52..a3d46fa48d919a16699c33b2b78236e62a33e025
>>>> 100644
>>>> --- a/gcc/target.def
>>>> +++ b/gcc/target.def
>>>> @@ -432,6 +432,19 @@ this section is associated.",
>>>>    void, (const char *name, unsigned int flags, tree decl),
>>>>    default_no_named_section)
>>>>
>>>> +/* Tell assembler what section attributes to assign this elf section
>>>> +   declaration, using their numerical value.  */
>>>> +DEFHOOK
>>>> +(elf_flags_numeric,
>>>> + "If the target needs to represent ELF section attributes using
>>>> their\n\
>>>> +numerical value, then this hook should be implemented to return true
>>>> and\n\
>>>> +write the numerical value of @var{flags} in @var{num}.  This
>>>> function is\n\
>>>> +called by @code{default_elf_asm_named_section}, which prints
>>>> @var{num}\n\
>>>> +as the value representing the ELF section attributes if this
>>>> function\n\
>>>> +returns true.",
>>>
>>>
>>> I think this should read something like.
>>>
>>> This hook can be used to encode ELF section flags for which no letter
>>> code has been defined in the assembler.  It is called by
>>> @code{default_asm_named_section} whenever the section flags need to be
>>> emitted in the assembler output.  If the hook returns true, then the
>>> numerical value for ELF section flags should be calculated from
>>> @var{flags} and saved in @var{*num}; the value will be printed out
>>> instead of the normal sequence of letter codes.  If the hook is not
>>> defined, or if it returns false, then @var{num} will be ignored and the
>>> traditional letter sequence will be emitted.
>>
>> Can we please write this in the present tense instead of the future,
>> assuming it describes current behavior (as modified by the patch)?
>>
>> s/will be/is/g
>>
>> -Sandra
>>
> Hi Sandra,
> 
> Is this better?
> 
> Cheers,
> Andre
> 
> gcc/ChangeLog
> 2016-09-23  Andre Vieira  <andre.simoesdiasvieira@arm.com>
> 
>         * target.def(elf_flags_numeric): Change documentation to
>         present tense.
> 
And here is the patch with the tm.texi regeneration.

Cheers,
Andre

gcc/ChangeLog
2016-09-23  Andre Vieira  <andre.simoesdiasvieira@arm.com>

        * target.def(elf_flags_numeric): Change documentation to
        present tense.
        * doc/tm.texi: Regenerate.

[-- Attachment #2: diff --]
[-- Type: text/plain, Size: 2219 bytes --]

diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 68a77e81aa1e2abcc15bc9088011295df699c4d0..8a98ba43a67eac87c2be8a974f6c0b924e519f52 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -7574,10 +7574,10 @@ code has been defined in the assembler.  It is called by
 @code{default_asm_named_section} whenever the section flags need to be
 emitted in the assembler output.  If the hook returns true, then the
 numerical value for ELF section flags should be calculated from
-@var{flags} and saved in @var{*num}; the value will be printed out
-instead of the normal sequence of letter codes.  If the hook is not
-defined, or if it returns false, then @var{num} will be ignored and the
-traditional letter sequence will be emitted.
+@var{flags} and saved in @var{*num}; the value is printed out instead of the
+normal sequence of letter codes.  If the hook is not defined, or if it
+returns false, then @var{num} is ignored and the traditional letter sequence
+is emitted.
 @end deftypefn
 
 @deftypefn {Target Hook} {section *} TARGET_ASM_FUNCTION_SECTION (tree @var{decl}, enum node_frequency @var{freq}, bool @var{startup}, bool @var{exit})
diff --git a/gcc/target.def b/gcc/target.def
index ac693318adaaa230ea300f10bc37282881d9da6f..4adb8aabc6548889b717abc9310e98f0e6fc161b 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -441,10 +441,10 @@ code has been defined in the assembler.  It is called by\n\
 @code{default_asm_named_section} whenever the section flags need to be\n\
 emitted in the assembler output.  If the hook returns true, then the\n\
 numerical value for ELF section flags should be calculated from\n\
-@var{flags} and saved in @var{*num}; the value will be printed out\n\
-instead of the normal sequence of letter codes.  If the hook is not\n\
-defined, or if it returns false, then @var{num} will be ignored and the\n\
-traditional letter sequence will be emitted.",
+@var{flags} and saved in @var{*num}; the value is printed out instead of the\n\
+normal sequence of letter codes.  If the hook is not defined, or if it\n\
+returns false, then @var{num} is ignored and the traditional letter sequence\n\
+is emitted.",
  bool, (unsigned int flags, unsigned int *num),
  hook_uint_uintp_false)
 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH, arm-embedded] -mpure-code option for ARM
  2016-09-22 15:10       ` [PATCHv3][ARM] " Andre Vieira (lists)
  2016-09-22 15:47         ` Richard Earnshaw (lists)
@ 2016-09-23 13:47         ` Andre Vieira (lists)
  1 sibling, 0 replies; 24+ messages in thread
From: Andre Vieira (lists) @ 2016-09-23 13:47 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 38379 bytes --]

On 22/09/16 16:04, Andre Vieira (lists) wrote:
> On 22/09/16 14:52, Richard Earnshaw (lists) wrote:
>> On 11/07/16 17:56, Andre Vieira (lists) wrote:
>>> On 07/07/16 13:30, mickael guene wrote:
>>>> Hi Andre,
>>>>
>>>>  Another feedback on your purecode patch.
>>>>  You have to disable casesi pattern since then it will
>>>> generate wrong code with -mpure-code option.
>>>>  Indeed it will generate an 'adr rx, .Lx' (aka
>>>> 'subs rx, PC, #offset') which will not work in our
>>>> case since 'Lx' label is put in an .rodata section.
>>>> So offset value is unknown and can be impossible
>>>> to encode correctly.
>>>>
>>>> Regards
>>>> Mickael
>>>>
>>>> On 06/30/2016 04:32 PM, Andre Vieira (lists) wrote:
>>>>> Hello,
>>>>>
>>>>> This patch adds the -mpure-code option for ARM. This option ensures
>>>>> functions are put into sections that contain only code and no data. To
>>>>> ensure this throughout compilation we give these sections the ARM
>>>>> processor-specific ELF section attribute "SHF_ARM_PURECODE". This option
>>>>> is only supported for non-pic code for armv7-m targets.
>>>>>
>>>>> This patch introduces a new target hook 'TARGET_ASM_ELF_FLAGS_NUMERIC'.
>>>>> This target hook enables a target to use the numeric value for elf
>>>>> section attributes rather than their alphabetical representation. If
>>>>> TARGET_ASM_ELF_FLAGS_NUMERIC returns TRUE, the existing
>>>>> 'default_elf_asm_named_section', will print the numeric value of the
>>>>> section attributes for the current section. This target hook has two
>>>>> parameters:
>>>>> unsigned int FLAGS, the input parameter that tells the function the
>>>>> current section's attributes;
>>>>> unsigned int *NUM, used to pass down the numerical representation of the
>>>>> section's attributes.
>>>>>
>>>>> The default implementation for TARGET_ASM_ELF_FLAGS_NUMERIC will return
>>>>> false, so existing behavior is not changed.
>>>>>
>>>>> Bootstrapped and tested for arm-none-linux-gnueabihf. Further tested for
>>>>> arm-none-eabi with a Cortex-M3 target.
>>>>>
>>>>>
>>>>> gcc/ChangeLog:
>>>>> 2016-06-30  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>>>>             Terry Guo  <terry.guo@arm.com>
>>>>>
>>>>>         * target.def (elf_flags_numeric): New target hook.
>>>>>         * targhooks.h (default_asm_elf_flags_numeric): New.
>>>>>         * varasm.c (default_asm_elf_flags_numeric): New.
>>>>>           (default_elf_asm_named_section): Use new target hook.
>>>>>         * config/arm/arm.opt (mpure-code): New.
>>>>>         * config/arm/arm.h (SECTION_ARM_PURECODE): New.
>>>>>         * config/arm/arm.c (arm_asm_init_sections): Add section
>>>>>           attribute to default text section if -mpure-code.
>>>>>           (arm_option_check_internal): Diagnose use of option with
>>>>>           non supported targets and/or options.
>>>>>           (arm_asm_elf_flags_numeric): New.
>>>>>           (arm_function_section): New.
>>>>>           (arm_elf_section_type_flags): New.
>>>>>         * config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Disable
>>>>>           for -mpure-code.
>>>>>         * gcc/doc/texi (TARGET_ASM_ELF_FLAGS_NUMERIC): New.
>>>>>         * gcc/doc/texi.in (TARGET_ASM_ELF_FLAGS_NUMERIC): Likewise.
>>>>>
>>>>>
>>>>>
>>>>> gcc/testsuite/ChangeLog:
>>>>> 2016-06-30  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>>>>             Terry Guo  <terry.guo@arm.com>
>>>>>
>>>>>         * gcc.target/arm/pure-code/ffunction-sections.c: New.
>>>>>         * gcc.target/arm/pure-code/no-literal-pool.c: New.
>>>>>         * gcc.target/arm/pure-code/pure-code.exp: New.
>>>>>
>>>>
>>> Hi Sandra, Mickael,
>>>
>>> Thank you for your comments. I changed the description of -mpure-code in
>>> invoke.texi to better reflect the error message you get wrt supported
>>> targets.
>>>
>>> As for the target hook description, I hope the text is clearer now. Let
>>> me know if you think it needs further explanation.
>>>
>>> I also fixed the double '%' in the text string for unnamed text sections
>>> and disabled the casesi pattern.
>>>
>>> I duplicated the original casesi test
>>> 'gcc/testsuite/gcc.c-torture/compile/pr46934.c' for pure-code to make
>>> sure the casesi was disabled and other patterns were selected instead.
>>>
>>> Reran regressions for pure-code.exp for Cortex-M3.
>>>
>>> Cheers,
>>> Andre
>>>
>>>
>>> gcc/ChangeLog:
>>> 2016-07-11  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>>             Terry Guo  <terry.guo@arm.com>
>>>
>>>         * target.def (elf_flags_numeric): New target hook.
>>>         * hooks.c (hook_uint_uintp_false): New generic hook.
>>>         * varasm.c (default_elf_asm_named_section): Use new target hook.
>>>         * config/arm/arm.opt (mpure-code): New.
>>>         * config/arm/arm.h (SECTION_ARM_PURECODE): New.
>>>         * config/arm/arm.c (arm_asm_init_sections): Add section
>>>         attribute to default text section if -mpure-code.
>>>         (arm_option_check_internal): Diagnose use of option with
>>>         non supported targets and/or options.
>>>         (arm_asm_elf_flags_numeric): New.
>>>         (arm_function_section): New.
>>>         (arm_elf_section_type_flags): New.
>>>         * config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Disable
>>>         for -mpure-code.
>>>         * config/arm/arm.md (casesi): Disable pattern for
>>>         -mpure-code.
>>>         * gcc/doc/texi (TARGET_ASM_ELF_FLAGS_NUMERIC): New.
>>>         * gcc/doc/texi.in (TARGET_ASM_ELF_FLAGS_NUMERIC): Likewise.
>>>
>>>
>>>
>>> gcc/testsuite/ChangeLog:
>>> 2016-07-11  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>>             Terry Guo  <terry.guo@arm.com>
>>>
>>>         * gcc.target/arm/pure-code/ffunction-sections.c: New.
>>>         * gcc.target/arm/pure-code/no-literal-pool.c: New.
>>>         * gcc.target/arm/pure-code/no-casesi.c: New.
>>>         * gcc.target/arm/pure-code/pure-code.exp: New.
>>>
>>>
>>> 0001-mpure-code-for-ARM.patch
>>>
>>>
>>> diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
>>> index f0cdd669191689bc5dcf3a7c2b60da5a2d201e3f..d10605cee0e6e0e07bbb4e1910d30c91443f8d17 100644
>>> --- a/gcc/config/arm/arm.h
>>> +++ b/gcc/config/arm/arm.h
>>> @@ -2263,4 +2263,8 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
>>>  /* For switching between functions with different target attributes.  */
>>>  #define SWITCHABLE_TARGET 1
>>>  
>>> +/* Define SECTION_ARM_PURECODE as the ARM specific section attribute
>>> +   representation for SHF_ARM_PURECODE in GCC.  */
>>> +#define SECTION_ARM_PURECODE SECTION_MACH_DEP
>>> +
>>>  #endif /* ! GCC_ARM_H */
>>> From b35a27e363a6123c6c50bd29e284c89f6ae434a5 Mon Sep 17 00:00:00 2001
>>> From: Andre Simoes Dias Vieira <andsim01@arm.com>
>>> Date: Tue, 14 Jun 2016 11:17:12 +0100
>>> Subject: [PATCH] -mpure-code for ARM
>>>
>>> ---
>>>  gcc/config/arm/arm.c                               | 150 ++++++++++++++++++++-
>>>  gcc/config/arm/arm.h                               |   4 +
>>>  gcc/config/arm/arm.md                              |   2 +-
>>>  gcc/config/arm/arm.opt                             |   6 +
>>>  gcc/config/arm/elf.h                               |   3 +-
>>>  gcc/doc/invoke.texi                                |  11 +-
>>>  gcc/doc/tm.texi                                    |   9 ++
>>>  gcc/doc/tm.texi.in                                 |   2 +
>>>  gcc/hooks.c                                        |  10 ++
>>>  gcc/target.def                                     |  13 ++
>>>  gcc/targhooks.h                                    |   1 -
>>>  .../gcc.target/arm/pure-code/ffunction-sections.c  |  17 +++
>>>  gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c |  29 ++++
>>>  .../gcc.target/arm/pure-code/no-literal-pool.c     |  68 ++++++++++
>>>  .../gcc.target/arm/pure-code/pure-code.exp         |  54 ++++++++
>>>  gcc/varasm.c                                       |  50 ++++---
>>>  16 files changed, 398 insertions(+), 31 deletions(-)
>>>  create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c
>>>  create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c
>>>  create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c
>>>  create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp
>>>
>>> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
>>> index f60955438d6f1cc5d996e7eacd4b453213044181..9b5013a069235d18eebc10a312e364de9f756906 100644
>>> --- a/gcc/config/arm/arm.c
>>> +++ b/gcc/config/arm/arm.c
>>> @@ -214,8 +214,8 @@ static bool arm_return_in_memory (const_tree, const_tree);
>>>  static void arm_unwind_emit (FILE *, rtx_insn *);
>>>  static bool arm_output_ttype (rtx);
>>>  static void arm_asm_emit_except_personality (rtx);
>>> -static void arm_asm_init_sections (void);
>>>  #endif
>>> +static void arm_asm_init_sections (void);
>>>  static rtx arm_dwarf_register_span (rtx);
>>>  
>>>  static tree arm_cxx_guard_type (void);
>>> @@ -299,7 +299,10 @@ static unsigned HOST_WIDE_INT arm_asan_shadow_offset (void);
>>>  static void arm_sched_fusion_priority (rtx_insn *, int, int *, int*);
>>>  static bool arm_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT,
>>>  				     const_tree);
>>> -
>>> +static section *arm_function_section (tree, enum node_frequency, bool, bool);
>>> +static bool arm_asm_elf_flags_numeric (unsigned int flags, unsigned int *num);
>>> +static unsigned int arm_elf_section_type_flags (tree decl, const char *name,
>>> +						int reloc);
>>>  \f
>>>  /* Table of machine attributes.  */
>>>  static const struct attribute_spec arm_attribute_table[] =
>>> @@ -587,8 +590,8 @@ static const struct attribute_spec arm_attribute_table[] =
>>>  #define TARGET_ASM_EMIT_EXCEPT_PERSONALITY arm_asm_emit_except_personality
>>>  
>>>  #undef TARGET_ASM_INIT_SECTIONS
>>> -#define TARGET_ASM_INIT_SECTIONS arm_asm_init_sections
>>>  #endif /* ARM_UNWIND_INFO */
>>> +#define TARGET_ASM_INIT_SECTIONS arm_asm_init_sections
>>>  
>>>  #undef TARGET_DWARF_REGISTER_SPAN
>>>  #define TARGET_DWARF_REGISTER_SPAN arm_dwarf_register_span
>>> @@ -729,6 +732,15 @@ static const struct attribute_spec arm_attribute_table[] =
>>>  #undef TARGET_SCHED_FUSION_PRIORITY
>>>  #define TARGET_SCHED_FUSION_PRIORITY arm_sched_fusion_priority
>>>  
>>> +#undef  TARGET_ASM_FUNCTION_SECTION
>>> +#define TARGET_ASM_FUNCTION_SECTION arm_function_section
>>> +
>>> +#undef TARGET_ASM_ELF_FLAGS_NUMERIC
>>> +#define TARGET_ASM_ELF_FLAGS_NUMERIC arm_asm_elf_flags_numeric
>>> +
>>> +#undef TARGET_SECTION_TYPE_FLAGS
>>> +#define TARGET_SECTION_TYPE_FLAGS arm_elf_section_type_flags
>>> +
>>>  struct gcc_target targetm = TARGET_INITIALIZER;
>>>  \f
>>>  /* Obstack for minipool constant handling.  */
>>> @@ -2815,6 +2827,17 @@ arm_option_check_internal (struct gcc_options *opts)
>>>        && ((!(arm_arch7 && !arm_arch_notm) && !arm_arch7em)
>>>  	  || (TARGET_THUMB1_P (flags) || flag_pic || TARGET_NEON)))
>>>      error ("-mslow-flash-data only supports non-pic code on armv7-m targets");
>>> +
>>> +#ifdef OBJECT_FORMAT_ELF
>>> +  /* We only support -mpure-code on Thumb-2 M-profile targets.  */
>>> +  if (target_pure_code
>>> +      && (!arm_arch_thumb2 || arm_arch_notm || flag_pic || TARGET_NEON))
>>> +    error ("-mpure-code only supports non-pic code on armv7-m targets");
>>> +#else
>>> +  if (target_pure_code)
>>> +    error ("-mpure-code is only available for the ELF object format.");
>>> +#endif
>>
>> It looks to me as though the only reason for restricting this to ELF is
>> that only that object format supports a PURECODE section flag.  However,
>> that's not a reason to restrict the behaviour to ELF-only.  Please can
>> we change this to be enabled for all object formats, even if they don't
>> have a special marker flag.
>>
>>> +
>>>  }
>>>  
>>>  /* Recompute the global settings depending on target attribute options.  */
>>> @@ -3453,8 +3476,9 @@ arm_option_override (void)
>>>  			 global_options.x_param_values,
>>>  			 global_options_set.x_param_values);
>>>  
>>> -  /* Currently, for slow flash data, we just disable literal pools.  */
>>> -  if (target_slow_flash_data)
>>> +  /* Currently, for slow flash data, we just disable literal pools.  We also
>>> +     disable it for -mpure-code.  */
>>
>> Better to just refer to 'pure code' and not directly to the option name.
>>  This applies elsewhere, too.
>>
>>> +  if (target_slow_flash_data || target_pure_code)
>>>      arm_disable_literal_pool = true;
>>>  
>>>    /* Disable scheduling fusion by default if it's not armv7 processor
>>> @@ -27208,17 +27232,22 @@ arm_asm_emit_except_personality (rtx personality)
>>>    output_addr_const (asm_out_file, personality);
>>>    fputc ('\n', asm_out_file);
>>>  }
>>> +#endif /* ARM_UNWIND_INFO */
>>>  
>>>  /* Implement TARGET_ASM_INITIALIZE_SECTIONS.  */
>>>  
>>>  static void
>>>  arm_asm_init_sections (void)
>>>  {
>>> +#if ARM_UNWIND_INFO
>>>    exception_section = get_unnamed_section (0, output_section_asm_op,
>>>  					   "\t.handlerdata");
>>> -}
>>>  #endif /* ARM_UNWIND_INFO */
>>>  
>>> +  if (target_pure_code)
>>> +    text_section->unnamed.data = "\t.section .text,\"0x20000006\",%progbits";
>>> +}
>>> +
>>>  /* Output unwind directives for the start/end of a function.  */
>>>  
>>>  void
>>> @@ -30529,4 +30558,113 @@ arm_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT vcall_offset,
>>>    return true;
>>>  }
>>>  
>>> +/* Implement the TARGET_ASM_ELF_FLAGS_NUMERIC hook.
>>> +
>>> +   For sections with SECTION_ARM_PURECODE flag set, make sure you pass the
>>> +   machine specific flag attribute when printing the numeric value.  */
>>
>> The comment is confusing.  Perhaps it's better to write:
>>
>> For pure-code sections there is no letter code for this attribute, so
>> output all the section flags numerically when this is needed.
>>
>>> +
>>> +static bool
>>> +arm_asm_elf_flags_numeric (unsigned int flags, unsigned int *num)
>>> +{
>>> +
>>> +  if (flags & SECTION_ARM_PURECODE)
>>> +    {
>>> +      *num = 0x20000000;
>>> +
>>> +      if (!(flags & SECTION_DEBUG))
>>> +	*num |= 0x2;
>>> +#if defined (HAVE_GAS_SECTION_EXCLUDE) && HAVE_GAS_SECTION_EXCLUDE == 1
>>> +      if (flags & SECTION_EXCLUDE)
>>> +	*num |= 0x80000000;
>>> +#endif
>>
>> Do we really need this ifdef?  Can't we assume that if our assembler
>> supports pure-code then it also supports the exclude attribute?
>>
>>> +      if (flags & SECTION_WRITE)
>>> +	*num |= 0x1;
>>> +      if (flags & SECTION_CODE)
>>> +	*num |= 0x4;
>>> +      if (flags & SECTION_MERGE)
>>> +	*num |= 0x10;
>>> +      if (flags & SECTION_STRINGS)
>>> +	*num |= 0x20;
>>> +      if (flags & SECTION_TLS)
>>> +	*num |= 0x400;
>>> +      if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
>>> +	*num |= 0x200;
>>> +
>>> +	return true;
>>> +    }
>>> +
>>> +  return false;
>>> +}
>>> +
>>> +/* Implement the TARGET_ASM_FUNCTION_SECTION hook.
>>> +
>>> +   If -mpure_code is passed as an option, make sure all functions are in
>>> +   sections that have the SHF_ARM_PURECODE attribute.  */
>>> +
>>> +static section *
>>> +arm_function_section (tree decl, enum node_frequency freq,
>>> +		      bool startup, bool exit)
>>> +{
>>> +  const char * section_name;
>>> +  section * sec;
>>> +
>>> +  if (!decl || TREE_CODE (decl) != FUNCTION_DECL)
>>> +    return default_function_section (decl, freq, startup, exit);
>>> +
>>> +  if (!target_pure_code)
>>> +    return default_function_section (decl, freq, startup, exit);
>>> +
>>> +
>>> +  section_name = DECL_SECTION_NAME (decl);
>>> +
>>> +  /* If a function is not in a named section then it falls under the 'default'
>>> +     text section, also known as '.text'. We can preserve previous behavior as
>>
>> Two spaces after a full stop.  There are other instances of this as well.
>>
>>
>>> +     the default text section already has the SHF_ARM_PURECODE section
>>> +     attribute.  */
>>> +  if (!section_name)
>>> +    {
>>> +      section *default_sec = default_function_section (decl, freq, startup,
>>> +						       exit);
>>> +
>>> +      /* If default_sec is not null, then it must be a special section like for
>>> +	 example .text.startup. We set the pure-code attribute and return the
>>
>> Like here.
>>
>>> +	 same section to preserve behavior.  */
>>
>> Preserve what behaviour?  Existing?  Or some other?
>>
>>> +      if (default_sec)
>>> +	  default_sec->common.flags |= SECTION_ARM_PURECODE;
>>> +      return default_sec;
>>> +    }
>>> +
>>> +  /* Otherwise look whether a section has already been created with
>>> +     'section_name'.  */
>>> +  sec = get_named_section (decl, section_name, 0);
>>> +  if (!sec)
>>> +    /* If that is not the case passing NULL as the name section to
>>
>> s/name section/section name/ ?
>>
>>> +       'get_named_section' will create a section with the declarations
>>> +       section name.  */
>>> +    sec = get_named_section (decl, NULL, 0);
>>> +
>>> +  /* Set the SHF_ARM_PURECODE attribute.  */
>>> +  sec->common.flags |= SECTION_ARM_PURECODE;
>>> +
>>> +  return sec;
>>> +}
>>> +
>>> +/* Implements the TARGET_SECTION_FLAGS hook.
>>> +
>>> +   If DECL is a function declaration and -mpure-code is passed as an option
>>> +   then add the SFH_ARM_PURECODE attribute to the section flags.  NAME is the
>>> +   sections name and RELOC indicates whether the declarations initializer may
>>
>> section's
>>
>>> +   contain runtime relocations.  */
>>> +
>>> +static unsigned int
>>> +arm_elf_section_type_flags (tree decl, const char *name, int reloc)
>>> +{
>>> +  unsigned int flags = default_section_type_flags (decl, name, reloc);
>>> +
>>> +  if (decl && TREE_CODE (decl) == FUNCTION_DECL && target_pure_code)
>>> +    flags |= SECTION_ARM_PURECODE;
>>> +
>>> +  return flags;
>>> +}
>>> +
>>>  #include "gt-arm.h"
>>> diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
>>> index 16498316bee9f19baff414885efe1e78191da047..9f49ab6014e61e7b49972f29c96ad03c11101aa1 100644
>>> --- a/gcc/config/arm/arm.md
>>> +++ b/gcc/config/arm/arm.md
>>> @@ -8180,7 +8180,7 @@
>>>     (match_operand:SI 2 "const_int_operand" "")	; total range
>>>     (match_operand:SI 3 "" "")			; table label
>>>     (match_operand:SI 4 "" "")]			; Out of range label
>>> -  "TARGET_32BIT || optimize_size || flag_pic"
>>> +  "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
>>>    "
>>>    {
>>>      enum insn_code code;
>>> diff --git a/gcc/config/arm/arm.opt b/gcc/config/arm/arm.opt
>>> index 0ebe0174390167b79a64583c35a3f8fb018f6538..6c142d9fc6bee9d5ec30f7a25bd017e8bc02b801 100644
>>> --- a/gcc/config/arm/arm.opt
>>> +++ b/gcc/config/arm/arm.opt
>>> @@ -281,3 +281,9 @@ Assume loading data from flash is slower than fetching instructions.
>>>  masm-syntax-unified
>>>  Target Report Var(inline_asm_unified) Init(0) Save
>>>  Assume unified syntax for inline assembly code.
>>> +
>>> +mpure-code
>>> +Target Report Var(target_pure_code) Init(0)
>>> +Generate assembly which places functions in sections that contain only code.
>>> +This requires that no literal pools are generated for such
>>> +functions and that jump tables are not put in the same section.
>>
>> I think this should read something like:
>>
>>   Do not allow constant data to placed in code sections.
>>
>> For the short help from the compiler that's more than enough to remind a
>> user what the option does.
>>
>>> diff --git a/gcc/config/arm/elf.h b/gcc/config/arm/elf.h
>>> index 77f30554d5286bd83aeab0c8dc308cfd44e732dc..395a22282be0cd2edc9459e1ba14d7848073fa5d 100644
>>> --- a/gcc/config/arm/elf.h
>>> +++ b/gcc/config/arm/elf.h
>>> @@ -104,7 +104,8 @@
>>>     the code more efficient, but for Thumb-1 it's better to put them out of
>>>     band unless we are generating compressed tables.  */
>>>  #define JUMP_TABLES_IN_TEXT_SECTION					\
>>> -   (TARGET_32BIT || (TARGET_THUMB && (optimize_size || flag_pic)))
>>> +   ((TARGET_32BIT || (TARGET_THUMB && (optimize_size || flag_pic))) \
>>> +    && !target_pure_code)
>>>  
>>>  #ifndef LINK_SPEC
>>>  #define LINK_SPEC "%{mbig-endian:-EB} %{mlittle-endian:-EL} -X"
>>> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
>>> index 4f24daebc01f0fd006540df8d863014aa864d060..faeb4299acc1f0859eafa3e13cf4b24c4d0224d6 100644
>>> --- a/gcc/doc/invoke.texi
>>> +++ b/gcc/doc/invoke.texi
>>> @@ -639,7 +639,8 @@ Objective-C and Objective-C++ Dialects}.
>>>  -mneon-for-64bits @gol
>>>  -mslow-flash-data @gol
>>>  -masm-syntax-unified @gol
>>> --mrestrict-it}
>>> +-mrestrict-it @gol
>>> +-mpure-code}
>>>  
>>>  @emph{AVR Options}
>>>  @gccoptlist{-mmcu=@var{mcu} -maccumulate-args -mbranch-cost=@var{cost} @gol
>>> @@ -14498,6 +14499,14 @@ Print CPU tuning information as comment in assembler file.  This is
>>>  an option used only for regression testing of the compiler and not
>>>  intended for ordinary use in compiling code.  This option is disabled
>>>  by default.
>>> +
>>> +@item -mpure-code
>>> +@opindex mpure-code
>>> +Generate assembly where instructions and data are in separate sections.
>>
>> This should probably be the same text as the help option.
>>
>>> +Additionally, give all text sections the ELF processor-specific section
>>> +attribute SHF_ARM_PURECODE.  This option is only available when generating
>>> +non-pic code in ELF object format for ARMv7-M targets.
>>
>> And this bit will need re-wording for the other changes.
>>
>>> +
>>>  @end table
>>>  
>>>  @node AVR Options
>>> diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
>>> index b318615b7b35ab93ad13e5e535a1d4e6d02cb7f7..c9e1489a0453845a2bffb2df514cc3b5b73933dc 100644
>>> --- a/gcc/doc/tm.texi
>>> +++ b/gcc/doc/tm.texi
>>> @@ -7543,6 +7543,15 @@ is non-NULL, it is the @code{VAR_DECL} or @code{FUNCTION_DECL} with which
>>>  this section is associated.
>>>  @end deftypefn
>>>  
>>> +@deftypefn {Target Hook} bool TARGET_ASM_ELF_FLAGS_NUMERIC (unsigned int @var{flags}, unsigned int *@var{num})
>>> +If the target needs to represent ELF section attributes using their
>>> +numerical value, then this hook should be implemented to return true and
>>> +write the numerical value of @var{flags} in @var{num}.  This function is
>>> +called by @code{default_elf_asm_named_section}, which prints @var{num}
>>> +as the value representing the ELF section attributes if this function
>>> +returns true.
>>> +@end deftypefn
>>> +
>>>  @deftypefn {Target Hook} {section *} TARGET_ASM_FUNCTION_SECTION (tree @var{decl}, enum node_frequency @var{freq}, bool @var{startup}, bool @var{exit})
>>>  Return preferred text (sub)section for function @var{decl}.
>>>  Main purpose of this function is to separate cold, normal and hot
>>> diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
>>> index 1e8423cb4e255acd8144e4b105186cee3d1d04fd..17a2ca73f07516526543253c77c088c73326af2c 100644
>>> --- a/gcc/doc/tm.texi.in
>>> +++ b/gcc/doc/tm.texi.in
>>> @@ -5229,6 +5229,8 @@ of the filename using this macro.
>>>  
>>>  @hook TARGET_ASM_NAMED_SECTION
>>>  
>>> +@hook TARGET_ASM_ELF_FLAGS_NUMERIC
>>> +
>>>  @hook TARGET_ASM_FUNCTION_SECTION
>>>  
>>>  @hook TARGET_ASM_FUNCTION_SWITCHED_TEXT_SECTIONS
>>> diff --git a/gcc/hooks.c b/gcc/hooks.c
>>> index 99ec4014adb6fcbb073bf538dd00fe8695ee6cb2..1e925645c3173f8d97e104b9b2f480fca2ede438 100644
>>> --- a/gcc/hooks.c
>>> +++ b/gcc/hooks.c
>>> @@ -481,3 +481,13 @@ void
>>>  hook_void_gcc_optionsp (struct gcc_options *opts ATTRIBUTE_UNUSED)
>>>  {
>>>  }
>>> +
>>> +/* Generic hook that takes an unsigned int, an unsigned int pointer and
>>> +   returns false.  */
>>> +
>>> +bool
>>> +hook_uint_uintp_false (unsigned int, unsigned int *)
>>> +{
>>> +  return false;
>>> +}
>>> +
>>> diff --git a/gcc/target.def b/gcc/target.def
>>> index a4df363698ce776b51d11c187baed2069ba88a52..a3d46fa48d919a16699c33b2b78236e62a33e025 100644
>>> --- a/gcc/target.def
>>> +++ b/gcc/target.def
>>> @@ -432,6 +432,19 @@ this section is associated.",
>>>   void, (const char *name, unsigned int flags, tree decl),
>>>   default_no_named_section)
>>>  
>>> +/* Tell assembler what section attributes to assign this elf section
>>> +   declaration, using their numerical value.  */
>>> +DEFHOOK
>>> +(elf_flags_numeric,
>>> + "If the target needs to represent ELF section attributes using their\n\
>>> +numerical value, then this hook should be implemented to return true and\n\
>>> +write the numerical value of @var{flags} in @var{num}.  This function is\n\
>>> +called by @code{default_elf_asm_named_section}, which prints @var{num}\n\
>>> +as the value representing the ELF section attributes if this function\n\
>>> +returns true.",
>>
>>
>> I think this should read something like.
>>
>> This hook can be used to encode ELF section flags for which no letter
>> code has been defined in the assembler.  It is called by
>> @code{default_asm_named_section} whenever the section flags need to be
>> emitted in the assembler output.  If the hook returns true, then the
>> numerical value for ELF section flags should be calculated from
>> @var{flags} and saved in @var{*num}; the value will be printed out
>> instead of the normal sequence of letter codes.  If the hook is not
>> defined, or if it returns false, then @var{num} will be ignored and the
>> traditional letter sequence will be emitted.
>>
>>
>>> + bool, (unsigned int flags, unsigned int *num),
>>> + hook_uint_uintp_false)
>>> +
>>>  /* Return preferred text (sub)section for function DECL.
>>>     Main purpose of this function is to separate cold, normal and hot
>>>     functions. STARTUP is true when function is known to be used only 
>>> diff --git a/gcc/targhooks.h b/gcc/targhooks.h
>>> index d6581cfab893e0da619c6bc0f98ff722a7ab4404..19ad97fa453cf6102b1502f97d8b66fe413284ee 100644
>>> --- a/gcc/targhooks.h
>>> +++ b/gcc/targhooks.h
>>> @@ -254,5 +254,4 @@ extern void default_setup_incoming_vararg_bounds (cumulative_args_t ca ATTRIBUTE
>>>  						  int second_time ATTRIBUTE_UNUSED);
>>>  extern bool default_optab_supported_p (int, machine_mode, machine_mode,
>>>  				       optimization_type);
>>> -
>>>  #endif /* GCC_TARGHOOKS_H */
>>> diff --git a/gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c b/gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c
>>> new file mode 100644
>>> index 0000000000000000000000000000000000000000..26fe38c05295b70ccc35ed900d41b34aae2c87a8
>>> --- /dev/null
>>> +++ b/gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c
>>> @@ -0,0 +1,17 @@
>>> +/* { dg-do compile } */
>>> +/* { dg-skip-if "" { *-*-* } { "-fpic" "-fPIC" } { "" } } */
>>> +/* { dg-options "-ffunction-sections -mpure-code" } */
>>> +#include <limits.h>
>>> +
>>> +char * foo (void)
>>> +{
>>> +  return "foo";
>>> +}
>>> +
>>> +unsigned int bar (unsigned int b)
>>> +{
>>> +  return UINT_MAX - b;
>>> +}
>>> +
>>> +/* { dg-final { scan-assembler {\.section\t\.text\.foo[^\n]*\"0x20000006\"} } } */
>>> +/* { dg-final { scan-assembler {\.section\t\.text\.bar[^\n]*\"0x20000006\"} } } */
>>> diff --git a/gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c b/gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c
>>> new file mode 100644
>>> index 0000000000000000000000000000000000000000..ba116a8261b16610e6af47d26a6e1a07b0127561
>>> --- /dev/null
>>> +++ b/gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c
>>> @@ -0,0 +1,29 @@
>>> +/* { dg-do compile } */
>>> +/* { dg-options "-mpure-code" } */
>>> +/* { dg-skip-if "" { *-*-* } { "-g" "-fpic" "-fPIC" } { "" } } */
>>> +
>>> +extern int foo (void);
>>> +extern int bar (void);
>>> +extern int baz (void);
>>> +extern int fooz (void);
>>> +
>>> +int caller (unsigned int reg_type)
>>> +{
>>> +  switch (reg_type)
>>> +    {
>>> +    case 0x80000000:
>>> +      return (int) foo ();
>>> +
>>> +    case 0x80000003:
>>> +      return (int) bar ();
>>> +
>>> +    case 0x80000001:
>>> +      return (int) baz ();
>>> +
>>> +    case 0x80000004:
>>> +      return (int) fooz ();
>>> +    }
>>> +}
>>> +
>>> +/* { dg-final { scan-assembler-not "\\.(float|l\\?double|\d?byte|short|int|long|quad|word)\\s+\[^.\]" } } */
>>> +/* { dg-final { scan-assembler "text,\"0x20000006\"" } } */
>>> diff --git a/gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c b/gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c
>>> new file mode 100644
>>> index 0000000000000000000000000000000000000000..4b893fd32f722e6cd7dfde5c8542ab98327ba375
>>> --- /dev/null
>>> +++ b/gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c
>>> @@ -0,0 +1,68 @@
>>> +/* { dg-do compile } */
>>> +/* { dg-options "-mpure-code" } */
>>> +/* { dg-skip-if "" { *-*-* } { "-g" "-fpic" "-fPIC" } { "" } } */
>>> +
>>> +float sf;
>>> +double df;
>>> +long long l;
>>> +static char *p = "Hello World";
>>> +
>>> +float
>>> +testsf (float *p)
>>> +{
>>> +  if (*p > 1.1234f)
>>> +    return 2.1234f;
>>> +  else
>>> +    return 3.1234f;
>>> +}
>>> +
>>> +double
>>> +testdf (double *p)
>>> +{
>>> +  if (*p > 4.1234)
>>> +    return 2.1234;
>>> +  else
>>> +    return 3.1234;
>>> +}
>>> +
>>> +long long
>>> +testll (long long *p)
>>> +{
>>> +  if (*p > 0x123456789ABCDEFll)
>>> +    return 0x111111111ll;
>>> +  else
>>> +    return 0x222222222ll;
>>> +}
>>> +
>>> +char *
>>> +testchar ()
>>> +{
>>> +  return p + 4;
>>> +}
>>> +
>>> +int
>>> +foo (int a, int b)
>>> +{
>>> +  int i;
>>> +  volatile int *labelref = &&label1;
>>> +
>>> +  if (a > b)
>>> +    {
>>> +      while (i < b)
>>> +	{
>>> +	  a += *labelref;
>>> +	  i += 1;
>>> +	}
>>> +      goto *labelref;
>>> +    }
>>> +  else
>>> +    b = b + 3;
>>> +
>>> +  a = a * b;
>>> +
>>> +label1:
>>> +  return a + b;
>>> +}
>>> +
>>> +/* { dg-final { scan-assembler-not "\\.(float|l\\?double|\d?byte|short|int|long|quad|word)\\s+\[^.\]" } } */
>>> +/* { dg-final { scan-assembler "text,\"0x20000006\"" } } */
>>> diff --git a/gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp b/gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp
>>> new file mode 100644
>>> index 0000000000000000000000000000000000000000..1abe7782c0e5dbb6e2deef25f4bea9415664f942
>>> --- /dev/null
>>> +++ b/gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp
>>> @@ -0,0 +1,54 @@
>>> +#   Copyright (C) 1997-2016 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
>>> +# <http://www.gnu.org/licenses/>.
>>> +
>>> +# GCC testsuite for ARM's -mpure-code option, using the `dg.exp' driver.
>>> +
>>> +# 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"
>>> +}
>>> +
>>> +# The -mpure-code option is only available for M-profile targets that support
>>> +# thumb2.
>>> +if {[check_effective_target_arm_thumb2_ok]
>>> +    && ![check_effective_target_arm_arm_ok]} then {
>>> +# Initialize `dg'.
>>> +dg-init
>>> +
>>> +set saved-dg-do-what-default ${dg-do-what-default}
>>> +set dg-do-what-default "assemble"
>>> +
>>> +set saved-lto_torture_options ${LTO_TORTURE_OPTIONS}
>>> +
>>> +# Add -ffat-lto-objects option to all LTO options such that we can do assembly
>>> +# scans.
>>> +proc add_fat_objects { list } {
>>> +    set res {}
>>> +    foreach el $list {set res [lappend res [concat $el " -ffat-lto-objects"]]}
>>> +    return $res
>>> +};
>>> +set LTO_TORTURE_OPTIONS [add_fat_objects ${LTO_TORTURE_OPTIONS}]
>>> +
>>> +gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] \
>>> +	"" $DEFAULT_CFLAGS
>>> +
>>> +# All done.
>>> +dg-finish
>>> +}
>>> diff --git a/gcc/varasm.c b/gcc/varasm.c
>>> index de8bcd6f20c823acd03991f813da3521b80547ff..13007d8c1ce2d094633422abeb01d91b1e986ac4 100644
>>> --- a/gcc/varasm.c
>>> +++ b/gcc/varasm.c
>>> @@ -6244,6 +6244,7 @@ default_elf_asm_named_section (const char *name, unsigned int flags,
>>>  			       tree decl)
>>>  {
>>>    char flagchars[11], *f = flagchars;
>>> +  unsigned int numeric_value;
>>
>> I think this should be initialized to zero, rather than assuming the
>> hook caller will do that for you.
>>
>>>  
>>>    /* If we have already declared this section, we can use an
>>>       abbreviated form to switch back to it -- unless this section is
>>> @@ -6256,31 +6257,38 @@ default_elf_asm_named_section (const char *name, unsigned int flags,
>>>        return;
>>>      }
>>>  
>>> -  if (!(flags & SECTION_DEBUG))
>>> -    *f++ = 'a';
>>> +  /* If we have a machine specific flag, then use the numeric value to pass
>>> +     this on to GAS.  */
>>> +  if (targetm.asm_out.elf_flags_numeric (flags, &numeric_value))
>>> +      snprintf (f, sizeof (flagchars), "0x%08x", numeric_value);
>>> +  else
>>> +    {
>>> +      if (!(flags & SECTION_DEBUG))
>>> +	*f++ = 'a';
>>>  #if defined (HAVE_GAS_SECTION_EXCLUDE) && HAVE_GAS_SECTION_EXCLUDE == 1
>>> -  if (flags & SECTION_EXCLUDE)
>>> -    *f++ = 'e';
>>> +      if (flags & SECTION_EXCLUDE)
>>> +	*f++ = 'e';
>>>  #endif
>>> -  if (flags & SECTION_WRITE)
>>> -    *f++ = 'w';
>>> -  if (flags & SECTION_CODE)
>>> -    *f++ = 'x';
>>> -  if (flags & SECTION_SMALL)
>>> -    *f++ = 's';
>>> -  if (flags & SECTION_MERGE)
>>> -    *f++ = 'M';
>>> -  if (flags & SECTION_STRINGS)
>>> -    *f++ = 'S';
>>> -  if (flags & SECTION_TLS)
>>> -    *f++ = TLS_SECTION_ASM_FLAG;
>>> -  if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
>>> -    *f++ = 'G';
>>> +      if (flags & SECTION_WRITE)
>>> +	*f++ = 'w';
>>> +      if (flags & SECTION_CODE)
>>> +	*f++ = 'x';
>>> +      if (flags & SECTION_SMALL)
>>> +	*f++ = 's';
>>> +      if (flags & SECTION_MERGE)
>>> +	*f++ = 'M';
>>> +      if (flags & SECTION_STRINGS)
>>> +	*f++ = 'S';
>>> +      if (flags & SECTION_TLS)
>>> +	*f++ = TLS_SECTION_ASM_FLAG;
>>> +      if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
>>> +	*f++ = 'G';
>>>  #ifdef MACH_DEP_SECTION_ASM_FLAG
>>> -  if (flags & SECTION_MACH_DEP)
>>> -    *f++ = MACH_DEP_SECTION_ASM_FLAG;
>>> +      if (flags & SECTION_MACH_DEP)
>>> +	*f++ = MACH_DEP_SECTION_ASM_FLAG;
>>>  #endif
>>> -  *f = '\0';
>>> +      *f = '\0';
>>> +    }
>>>  
>>>    fprintf (asm_out_file, "\t.section\t%s,\"%s\"", name, flagchars);
>>>  
>>>
>>
>> R.
>>
> 
> I reworked the patch according to the comments above.
> 
> Is this OK?
> 
> gcc/ChangeLog:
> 2016-09-22  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>             Terry Guo  <terry.guo@arm.com>
> 
>         * target.def (elf_flags_numeric): New target hook.
>         * targhooks.h (default_asm_elf_flags_numeric): New.
>         * varasm.c (default_asm_elf_flags_numeric): New.
>           (default_elf_asm_named_section): Use new target hook.
>         * config/arm/arm.opt (mpure-code): New.
>         * config/arm/arm.h (SECTION_ARM_PURECODE): New.
>         * config/arm/arm.c (arm_asm_init_sections): Add section
>           attribute to default text section if -mpure-code.
>           (arm_option_check_internal): Diagnose use of option with
>           non supported targets and/or options.
>           (arm_asm_elf_flags_numeric): New.
>           (arm_function_section): New.
>           (arm_elf_section_type_flags): New.
>         * config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Disable
>           for -mpure-code.
>         * gcc/doc/texi (TARGET_ASM_ELF_FLAGS_NUMERIC): New.
>         * gcc/doc/texi.in (TARGET_ASM_ELF_FLAGS_NUMERIC): Likewise.
> 
> 
> 
> gcc/testsuite/ChangeLog:
> 2016-09-22  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>             Terry Guo  <terry.guo@arm.com>
> 
>         * gcc.target/arm/pure-code/ffunction-sections.c: New.
>         * gcc.target/arm/pure-code/no-literal-pool.c: New.
>         * gcc.target/arm/pure-code/pure-code.exp: New.
> 

Applied a backport of this to embedded-5-branch with fixed ChangeLog and
including the fix for PR77695 and documentation fix.


gcc/ChangeLog.arm:
2016-09-23  Andre Vieira  <andre.simoesdiasvieira@arm.com>

        Backport from mainline
        2016-09-23  Uros Bizjak  <ubizjak@gmail.com>
	            Jakub Jelinek  <jakub@redhat.com>

	* hooks.h (hook_uint_uintp_false): Rename to...
	(hook_bool_uint_uintp_false): ... this.
	* hooks.c (hook_uint_uintp_false): Rename to...
	(hook_bool_uint_uintp_false): ... this.
	* target.def (elf_flags_numeric): Use hook_bool_uint_uintp_false
	instead of hook_uint_uintp_false.

        2016-09-23  Richard Biener  <rguenther@suse.de>

        * hooks.h (hook_uint_uintp_false): Declare.

        2016-09-22  Andre Vieira  <andre.simoesdiasvieira@arm.com>
                    Terry Guo  <terry.guo@arm.com>

        * target.def (elf_flags_numeric): New target hook.
        * targhooks.h (default_asm_elf_flags_numeric): New.
        * hooks.c (hook_uint_uintp_false): New.
        * varasm.c (default_asm_elf_flags_numeric): New.
        (default_elf_asm_named_section): Use new target hook.
        * config/arm/arm.opt (mpure-code): New.
        * config/arm/arm.h (SECTION_ARM_PURECODE): New.
        * config/arm/arm.c (arm_asm_init_sections): Add section
        attribute to default text section if -mpure-code.
        (arm_option_option_override): Diagnose use of option with
        non supported targets and/or options.
        (arm_asm_elf_flags_numeric): New.
        (arm_function_section): New.
        (arm_elf_section_type_flags): New.
        * config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Disable
        for -mpure-code.
        * gcc/doc/texi (TARGET_ASM_ELF_FLAGS_NUMERIC): New.
        * gcc/doc/texi.in (TARGET_ASM_ELF_FLAGS_NUMERIC): Likewise.



gcc/testsuite/ChangeLog:
2016-09-23 Andre Vieira <andre.simoesdiasvieira@arm.com>

        Backport from mainline
        2016-09-22  Andre Vieira  <andre.simoesdiasvieira@arm.com>
                    Terry Guo  <terry.guo@arm.com>

        * gcc.target/arm/pure-code/ffunction-sections.c: New.
        * gcc.target/arm/pure-code/no-literal-pool.c: New.
        * gcc.target/arm/pure-code/pure-code.exp: New.


[-- Attachment #2: diff --]
[-- Type: text/plain, Size: 21872 bytes --]

diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index d3efe84f3199aee3d648b2adafd12bb70c38fffc..34d452d4ee75264ce2bad6713722aa3b1d87dba4 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -2435,4 +2435,9 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
 
 #define DRIVER_SELF_SPECS MCPU_MTUNE_NATIVE_SPECS
 #define TARGET_SUPPORTS_WIDE_INT 1
+
+/* Define SECTION_ARM_PURECODE as the ARM specific section attribute
+   representation for SHF_ARM_PURECODE in GCC.  */
+#define SECTION_ARM_PURECODE SECTION_MACH_DEP
+
 #endif /* ! GCC_ARM_H */
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 2e271240963d06751dde5c1a44d45b4aba26e8ba..4bcd8076f35462911e5bd8e4ab034f21b648d64a 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -249,8 +249,8 @@ static bool arm_return_in_memory (const_tree, const_tree);
 static void arm_unwind_emit (FILE *, rtx_insn *);
 static bool arm_output_ttype (rtx);
 static void arm_asm_emit_except_personality (rtx);
-static void arm_asm_init_sections (void);
 #endif
+static void arm_asm_init_sections (void);
 static rtx arm_dwarf_register_span (rtx);
 
 static tree arm_cxx_guard_type (void);
@@ -328,6 +328,10 @@ static void arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
 static unsigned HOST_WIDE_INT arm_asan_shadow_offset (void);
 
 static void arm_sched_fusion_priority (rtx_insn *, int, int *, int*);
+static section *arm_function_section (tree, enum node_frequency, bool, bool);
+static bool arm_asm_elf_flags_numeric (unsigned int flags, unsigned int *num);
+static unsigned int arm_elf_section_type_flags (tree decl, const char *name,
+						int reloc);
 \f
 /* Table of machine attributes.  */
 static const struct attribute_spec arm_attribute_table[] =
@@ -599,8 +603,8 @@ static const struct attribute_spec arm_attribute_table[] =
 #define TARGET_ASM_EMIT_EXCEPT_PERSONALITY arm_asm_emit_except_personality
 
 #undef TARGET_ASM_INIT_SECTIONS
-#define TARGET_ASM_INIT_SECTIONS arm_asm_init_sections
 #endif /* ARM_UNWIND_INFO */
+#define TARGET_ASM_INIT_SECTIONS arm_asm_init_sections
 
 #undef TARGET_DWARF_REGISTER_SPAN
 #define TARGET_DWARF_REGISTER_SPAN arm_dwarf_register_span
@@ -747,6 +751,15 @@ static const struct attribute_spec arm_attribute_table[] =
 #undef TARGET_SCHED_FUSION_PRIORITY
 #define TARGET_SCHED_FUSION_PRIORITY arm_sched_fusion_priority
 
+#undef  TARGET_ASM_FUNCTION_SECTION
+#define TARGET_ASM_FUNCTION_SECTION arm_function_section
+
+#undef TARGET_ASM_ELF_FLAGS_NUMERIC
+#define TARGET_ASM_ELF_FLAGS_NUMERIC arm_asm_elf_flags_numeric
+
+#undef TARGET_SECTION_TYPE_FLAGS
+#define TARGET_SECTION_TYPE_FLAGS arm_elf_section_type_flags
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
 /* Obstack for minipool constant handling.  */
@@ -3222,8 +3235,14 @@ arm_option_override (void)
 	  || (TARGET_THUMB1 || flag_pic || TARGET_NEON)))
     error ("-mslow-flash-data only supports non-pic code on armv7-m targets");
 
-  /* Currently, for slow flash data, we just disable literal pools.  */
-  if (target_slow_flash_data)
+  /* We only support pure-code on Thumb-2 M-profile targets.  */
+  if (target_pure_code
+      && (!arm_arch_thumb2 || arm_arch_notm || flag_pic || TARGET_NEON))
+    error ("-mpure-code only supports non-pic code on armv7-m targets");
+
+  /* Currently, for slow flash data, we just disable literal pools.  We also
+     disable it for pure-code.  */
+  if (target_slow_flash_data || target_pure_code)
     arm_disable_literal_pool = true;
 
   /* Thumb2 inline assembly code should always use unified syntax.
@@ -27604,17 +27623,24 @@ arm_asm_emit_except_personality (rtx personality)
   output_addr_const (asm_out_file, personality);
   fputc ('\n', asm_out_file);
 }
+#endif /* ARM_UNWIND_INFO */
 
 /* Implement TARGET_ASM_INITIALIZE_SECTIONS.  */
 
 static void
 arm_asm_init_sections (void)
 {
+#if ARM_UNWIND_INFO
   exception_section = get_unnamed_section (0, output_section_asm_op,
 					   "\t.handlerdata");
-}
 #endif /* ARM_UNWIND_INFO */
 
+#ifdef OBJECT_FORMAT_ELF
+  if (target_pure_code)
+    text_section->unnamed.data = "\t.section .text,\"0x20000006\",%progbits";
+#endif
+}
+
 /* Output unwind directives for the start/end of a function.  */
 
 void
@@ -30389,4 +30415,112 @@ arm_sched_fusion_priority (rtx_insn *insn, int max_pri,
   *pri = tmp;
   return;
 }
+
+/* Implement the TARGET_ASM_ELF_FLAGS_NUMERIC hook.
+
+   For pure-code sections there is no letter code for this attribute, so
+   output all the section flags numerically when this is needed.  */
+
+static bool
+arm_asm_elf_flags_numeric (unsigned int flags, unsigned int *num)
+{
+
+  if (flags & SECTION_ARM_PURECODE)
+    {
+      *num = 0x20000000;
+
+      if (!(flags & SECTION_DEBUG))
+	*num |= 0x2;
+      if (flags & SECTION_EXCLUDE)
+	*num |= 0x80000000;
+      if (flags & SECTION_WRITE)
+	*num |= 0x1;
+      if (flags & SECTION_CODE)
+	*num |= 0x4;
+      if (flags & SECTION_MERGE)
+	*num |= 0x10;
+      if (flags & SECTION_STRINGS)
+	*num |= 0x20;
+      if (flags & SECTION_TLS)
+	*num |= 0x400;
+      if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
+	*num |= 0x200;
+
+	return true;
+    }
+
+  return false;
+}
+
+/* Implement the TARGET_ASM_FUNCTION_SECTION hook.
+
+   If pure-code is passed as an option, make sure all functions are in
+   sections that have the SHF_ARM_PURECODE attribute.  */
+
+static section *
+arm_function_section (tree decl, enum node_frequency freq,
+		      bool startup, bool exit)
+{
+  const char * section_name;
+  section * sec;
+
+  if (!decl || TREE_CODE (decl) != FUNCTION_DECL)
+    return default_function_section (decl, freq, startup, exit);
+
+  if (!target_pure_code)
+    return default_function_section (decl, freq, startup, exit);
+
+
+  section_name = DECL_SECTION_NAME (decl);
+
+  /* If a function is not in a named section then it falls under the 'default'
+     text section, also known as '.text'.  We can preserve previous behavior as
+     the default text section already has the SHF_ARM_PURECODE section
+     attribute.  */
+  if (!section_name)
+    {
+      section *default_sec = default_function_section (decl, freq, startup,
+						       exit);
+
+      /* If default_sec is not null, then it must be a special section like for
+	 example .text.startup.  We set the pure-code attribute and return the
+	 same section to preserve existing behavior.  */
+      if (default_sec)
+	  default_sec->common.flags |= SECTION_ARM_PURECODE;
+      return default_sec;
+    }
+
+  /* Otherwise look whether a section has already been created with
+     'section_name'.  */
+  sec = get_named_section (decl, section_name, 0);
+  if (!sec)
+    /* If that is not the case passing NULL as the section's name to
+       'get_named_section' will create a section with the declaration's
+       section name.  */
+    sec = get_named_section (decl, NULL, 0);
+
+  /* Set the SHF_ARM_PURECODE attribute.  */
+  sec->common.flags |= SECTION_ARM_PURECODE;
+
+  return sec;
+}
+
+/* Implements the TARGET_SECTION_FLAGS hook.
+
+   If DECL is a function declaration and pure-code is passed as an option
+   then add the SFH_ARM_PURECODE attribute to the section flags.  NAME is the
+   section's name and RELOC indicates whether the declarations initializer may
+   contain runtime relocations.  */
+
+static unsigned int
+arm_elf_section_type_flags (tree decl, const char *name, int reloc)
+{
+  unsigned int flags = default_section_type_flags (decl, name, reloc);
+
+  if (decl && TREE_CODE (decl) == FUNCTION_DECL && target_pure_code)
+    flags |= SECTION_ARM_PURECODE;
+
+  return flags;
+}
+
 #include "gt-arm.h"
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 7f4af1872961ea09796d745499c0d65fe92273bf..6ab9752af28b71a0493ac4b782fdc66f6190e9f7 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -8218,7 +8218,7 @@
    (match_operand:SI 2 "const_int_operand" "")	; total range
    (match_operand:SI 3 "" "")			; table label
    (match_operand:SI 4 "" "")]			; Out of range label
-  "TARGET_32BIT || optimize_size || flag_pic"
+  "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
   "
   {
     enum insn_code code;
diff --git a/gcc/config/arm/arm.opt b/gcc/config/arm/arm.opt
index d536366e82a738ebd26f6f87b4ab2a90db349fa5..6ae2d18240f4c90529b824b29942f38e73f4335f 100644
--- a/gcc/config/arm/arm.opt
+++ b/gcc/config/arm/arm.opt
@@ -281,3 +281,7 @@ Assume loading data from flash is slower than fetching instructions.
 masm-syntax-unified
 Target Report Var(inline_asm_unified) Init(0)
 Assume unified syntax for Thumb inline assembly code.
+
+mpure-code
+Target Report Var(target_pure_code) Init(0)
+Do not allow constant data to be placed in code sections.
diff --git a/gcc/config/arm/elf.h b/gcc/config/arm/elf.h
index 8189701708cdb492cccaed55b4392e6497da1a65..68822ef731bdf9348577ed9403f49b64963de48e 100644
--- a/gcc/config/arm/elf.h
+++ b/gcc/config/arm/elf.h
@@ -95,7 +95,8 @@
    the code more efficient, but for Thumb-1 it's better to put them out of
    band unless we are generating compressed tables.  */
 #define JUMP_TABLES_IN_TEXT_SECTION					\
-   (TARGET_32BIT || (TARGET_THUMB && (optimize_size || flag_pic)))
+   ((TARGET_32BIT || (TARGET_THUMB && (optimize_size || flag_pic))) \
+    && !target_pure_code)
 
 #ifndef LINK_SPEC
 #define LINK_SPEC "%{mbig-endian:-EB} %{mlittle-endian:-EL} -X"
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 6e46ea00b6c933b65f4722e36d5a94b332ca7a2e..ea654754c4f420e3352d15de8dc7a43e400f8157 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -569,8 +569,9 @@ Objective-C and Objective-C++ Dialects}.
 -mneon-for-64bits @gol
 -mslow-flash-data @gol
 -masm-syntax-unified @gol
--mrestrict-it
--mcmse}
+-mrestrict-it @gol
+-mcmse @gol
+-mpure-code}
 
 @emph{AVR Options}
 @gccoptlist{-mmcu=@var{mcu} -maccumulate-args -mbranch-cost=@var{cost} @gol
@@ -13532,6 +13533,14 @@ by default.
 @item -mcmse
 @opindex mcmse
 Generate secure code as per ARMv8-M Security Extensions.
+
+@item -mpure-code
+@opindex mpure-code
+Do not allow constant data to be placed in code sections.
+Additionally, when compiling for ELF object format give all text sections the
+ELF processor-specific section attribute @code{SHF_ARM_PURECODE}.  This option
+is only available when generating non-pic code for ARMv7-M targets.
+
 @end table
 
 @node AVR Options
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index e32e77ea14ac679707f2e03bd9d6d7eca99fc862..9b35651c8e8cf1fe34bd24f03e1b7f38e832ec4a 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -7433,6 +7433,18 @@ is non-NULL, it is the @code{VAR_DECL} or @code{FUNCTION_DECL} with which
 this section is associated.
 @end deftypefn
 
+@deftypefn {Target Hook} bool TARGET_ASM_ELF_FLAGS_NUMERIC (unsigned int @var{flags}, unsigned int *@var{num})
+This hook can be used to encode ELF section flags for which no letter
+code has been defined in the assembler.  It is called by
+@code{default_asm_named_section} whenever the section flags need to be
+emitted in the assembler output.  If the hook returns true, then the
+numerical value for ELF section flags should be calculated from
+@var{flags} and saved in @var{*num}; the value is printed out instead of the
+normal sequence of letter codes.  If the hook is not defined, or if it
+returns false, then @var{num} is ignored and the traditional letter sequence
+is emitted.
+@end deftypefn
+
 @deftypefn {Target Hook} {section *} TARGET_ASM_FUNCTION_SECTION (tree @var{decl}, enum node_frequency @var{freq}, bool @var{startup}, bool @var{exit})
 Return preferred text (sub)section for function @var{decl}.
 Main purpose of this function is to separate cold, normal and hot
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 2de5d2744ab21e2ff49ce36dfcdc4747de16dce3..c0ad079631926090741771d9573ed6c29a584c27 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -5192,6 +5192,8 @@ of the filename using this macro.
 
 @hook TARGET_ASM_NAMED_SECTION
 
+@hook TARGET_ASM_ELF_FLAGS_NUMERIC
+
 @hook TARGET_ASM_FUNCTION_SECTION
 
 @hook TARGET_ASM_FUNCTION_SWITCHED_TEXT_SECTIONS
diff --git a/gcc/hooks.h b/gcc/hooks.h
index 8c929e8884ed32d0acc8763fe7fac1a484e65ee0..0dfdca6eb5e914574308aa1aa11d3bdcd388044c 100644
--- a/gcc/hooks.h
+++ b/gcc/hooks.h
@@ -78,6 +78,7 @@ extern void hook_void_tree (tree);
 extern void hook_void_tree_treeptr (tree, tree *);
 extern void hook_void_int_int (int, int);
 extern void hook_void_gcc_optionsp (struct gcc_options *);
+extern bool hook_bool_uint_uintp_false (unsigned int, unsigned int *);
 
 extern int hook_int_uint_mode_1 (unsigned int, machine_mode);
 extern int hook_int_const_tree_0 (const_tree);
diff --git a/gcc/hooks.c b/gcc/hooks.c
index 824aeb0869f56ed8dfbaa81b7d869431e8038713..61f25ac884229915b46f92e3efb050658f0d005c 100644
--- a/gcc/hooks.c
+++ b/gcc/hooks.c
@@ -489,3 +489,13 @@ void
 hook_void_gcc_optionsp (struct gcc_options *opts ATTRIBUTE_UNUSED)
 {
 }
+
+/* Generic hook that takes an unsigned int, an unsigned int pointer and
+   returns false.  */
+
+bool
+hook_bool_uint_uintp_false (unsigned int, unsigned int *)
+{
+  return false;
+}
+
diff --git a/gcc/target.def b/gcc/target.def
index a00181aa9bb721cd626d8402f40894549fd6026a..8ff044a743731950d86056731ad6f2080bacb0f8 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -432,6 +432,22 @@ this section is associated.",
  void, (const char *name, unsigned int flags, tree decl),
  default_no_named_section)
 
+/* Tell assembler what section attributes to assign this elf section
+   declaration, using their numerical value.  */
+DEFHOOK
+(elf_flags_numeric,
+ "This hook can be used to encode ELF section flags for which no letter\n\
+code has been defined in the assembler.  It is called by\n\
+@code{default_asm_named_section} whenever the section flags need to be\n\
+emitted in the assembler output.  If the hook returns true, then the\n\
+numerical value for ELF section flags should be calculated from\n\
+@var{flags} and saved in @var{*num}; the value is printed out instead of the\n\
+normal sequence of letter codes.  If the hook is not defined, or if it\n\
+returns false, then @var{num} is ignored and the traditional letter sequence\n\
+is emitted.",
+ bool, (unsigned int flags, unsigned int *num),
+ hook_bool_uint_uintp_false)
+
 /* Return preferred text (sub)section for function DECL.
    Main purpose of this function is to separate cold, normal and hot
    functions. STARTUP is true when function is known to be used only 
diff --git a/gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c b/gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c
new file mode 100644
index 0000000000000000000000000000000000000000..26fe38c05295b70ccc35ed900d41b34aae2c87a8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pure-code/ffunction-sections.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-fpic" "-fPIC" } { "" } } */
+/* { dg-options "-ffunction-sections -mpure-code" } */
+#include <limits.h>
+
+char * foo (void)
+{
+  return "foo";
+}
+
+unsigned int bar (unsigned int b)
+{
+  return UINT_MAX - b;
+}
+
+/* { dg-final { scan-assembler {\.section\t\.text\.foo[^\n]*\"0x20000006\"} } } */
+/* { dg-final { scan-assembler {\.section\t\.text\.bar[^\n]*\"0x20000006\"} } } */
diff --git a/gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c b/gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c
new file mode 100644
index 0000000000000000000000000000000000000000..ba116a8261b16610e6af47d26a6e1a07b0127561
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pure-code/no-casesi.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-mpure-code" } */
+/* { dg-skip-if "" { *-*-* } { "-g" "-fpic" "-fPIC" } { "" } } */
+
+extern int foo (void);
+extern int bar (void);
+extern int baz (void);
+extern int fooz (void);
+
+int caller (unsigned int reg_type)
+{
+  switch (reg_type)
+    {
+    case 0x80000000:
+      return (int) foo ();
+
+    case 0x80000003:
+      return (int) bar ();
+
+    case 0x80000001:
+      return (int) baz ();
+
+    case 0x80000004:
+      return (int) fooz ();
+    }
+}
+
+/* { dg-final { scan-assembler-not "\\.(float|l\\?double|\d?byte|short|int|long|quad|word)\\s+\[^.\]" } } */
+/* { dg-final { scan-assembler "text,\"0x20000006\"" } } */
diff --git a/gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c b/gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c
new file mode 100644
index 0000000000000000000000000000000000000000..4b893fd32f722e6cd7dfde5c8542ab98327ba375
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pure-code/no-literal-pool.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-mpure-code" } */
+/* { dg-skip-if "" { *-*-* } { "-g" "-fpic" "-fPIC" } { "" } } */
+
+float sf;
+double df;
+long long l;
+static char *p = "Hello World";
+
+float
+testsf (float *p)
+{
+  if (*p > 1.1234f)
+    return 2.1234f;
+  else
+    return 3.1234f;
+}
+
+double
+testdf (double *p)
+{
+  if (*p > 4.1234)
+    return 2.1234;
+  else
+    return 3.1234;
+}
+
+long long
+testll (long long *p)
+{
+  if (*p > 0x123456789ABCDEFll)
+    return 0x111111111ll;
+  else
+    return 0x222222222ll;
+}
+
+char *
+testchar ()
+{
+  return p + 4;
+}
+
+int
+foo (int a, int b)
+{
+  int i;
+  volatile int *labelref = &&label1;
+
+  if (a > b)
+    {
+      while (i < b)
+	{
+	  a += *labelref;
+	  i += 1;
+	}
+      goto *labelref;
+    }
+  else
+    b = b + 3;
+
+  a = a * b;
+
+label1:
+  return a + b;
+}
+
+/* { dg-final { scan-assembler-not "\\.(float|l\\?double|\d?byte|short|int|long|quad|word)\\s+\[^.\]" } } */
+/* { dg-final { scan-assembler "text,\"0x20000006\"" } } */
diff --git a/gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp b/gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp
new file mode 100644
index 0000000000000000000000000000000000000000..1abe7782c0e5dbb6e2deef25f4bea9415664f942
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pure-code/pure-code.exp
@@ -0,0 +1,54 @@
+#   Copyright (C) 1997-2016 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
+# <http://www.gnu.org/licenses/>.
+
+# GCC testsuite for ARM's -mpure-code option, using the `dg.exp' driver.
+
+# 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"
+}
+
+# The -mpure-code option is only available for M-profile targets that support
+# thumb2.
+if {[check_effective_target_arm_thumb2_ok]
+    && ![check_effective_target_arm_arm_ok]} then {
+# Initialize `dg'.
+dg-init
+
+set saved-dg-do-what-default ${dg-do-what-default}
+set dg-do-what-default "assemble"
+
+set saved-lto_torture_options ${LTO_TORTURE_OPTIONS}
+
+# Add -ffat-lto-objects option to all LTO options such that we can do assembly
+# scans.
+proc add_fat_objects { list } {
+    set res {}
+    foreach el $list {set res [lappend res [concat $el " -ffat-lto-objects"]]}
+    return $res
+};
+set LTO_TORTURE_OPTIONS [add_fat_objects ${LTO_TORTURE_OPTIONS}]
+
+gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] \
+	"" $DEFAULT_CFLAGS
+
+# All done.
+dg-finish
+}
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 49d177d4fc43cb5a51bd72db479abbbb65d20d39..3435e1fe20ac7cd10c63915a76c047c677db2fff 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6253,7 +6253,8 @@ void
 default_elf_asm_named_section (const char *name, unsigned int flags,
 			       tree decl ATTRIBUTE_UNUSED)
 {
-  char flagchars[10], *f = flagchars;
+  char flagchars[11], *f = flagchars;
+  unsigned int numeric_value = 0;
 
   /* If we have already declared this section, we can use an
      abbreviated form to switch back to it -- unless this section is
@@ -6266,27 +6267,34 @@ default_elf_asm_named_section (const char *name, unsigned int flags,
       return;
     }
 
-  if (!(flags & SECTION_DEBUG))
-    *f++ = 'a';
+  /* If we have a machine specific flag, then use the numeric value to pass
+     this on to GAS.  */
+  if (targetm.asm_out.elf_flags_numeric (flags, &numeric_value))
+      snprintf (f, sizeof (flagchars), "0x%08x", numeric_value);
+  else
+    {
+      if (!(flags & SECTION_DEBUG))
+	*f++ = 'a';
 #if defined (HAVE_GAS_SECTION_EXCLUDE) && HAVE_GAS_SECTION_EXCLUDE == 1
-  if (flags & SECTION_EXCLUDE)
-    *f++ = 'e';
+      if (flags & SECTION_EXCLUDE)
+	*f++ = 'e';
 #endif
-  if (flags & SECTION_WRITE)
-    *f++ = 'w';
-  if (flags & SECTION_CODE)
-    *f++ = 'x';
-  if (flags & SECTION_SMALL)
-    *f++ = 's';
-  if (flags & SECTION_MERGE)
-    *f++ = 'M';
-  if (flags & SECTION_STRINGS)
-    *f++ = 'S';
-  if (flags & SECTION_TLS)
-    *f++ = TLS_SECTION_ASM_FLAG;
-  if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
-    *f++ = 'G';
-  *f = '\0';
+    if (flags & SECTION_WRITE)
+      *f++ = 'w';
+    if (flags & SECTION_CODE)
+      *f++ = 'x';
+    if (flags & SECTION_SMALL)
+      *f++ = 's';
+    if (flags & SECTION_MERGE)
+      *f++ = 'M';
+    if (flags & SECTION_STRINGS)
+      *f++ = 'S';
+    if (flags & SECTION_TLS)
+      *f++ = TLS_SECTION_ASM_FLAG;
+    if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
+      *f++ = 'G';
+    *f = '\0';
+    }
 
   fprintf (asm_out_file, "\t.section\t%s,\"%s\"", name, flagchars);
 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCHv2][ARM] -mpure-code option for ARM
  2016-09-23 10:41           ` Andre Vieira (lists)
@ 2016-09-23 15:12             ` Sandra Loosemore
  2016-10-04 13:24               ` mickael guene
  0 siblings, 1 reply; 24+ messages in thread
From: Sandra Loosemore @ 2016-09-23 15:12 UTC (permalink / raw)
  To: Andre Vieira (lists), gcc-patches

On 09/23/2016 04:39 AM, Andre Vieira (lists) wrote:
>> Hi Sandra,
>>
>> Is this better?
>>
>> Cheers,
>> Andre
>>
>> gcc/ChangeLog
>> 2016-09-23  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>
>>          * target.def(elf_flags_numeric): Change documentation to
>>          present tense.
>>
> And here is the patch with the tm.texi regeneration.
>
> Cheers,
> Andre
>
> gcc/ChangeLog
> 2016-09-23  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>
>          * target.def(elf_flags_numeric): Change documentation to
>          present tense.
>          * doc/tm.texi: Regenerate.
>

This looks good to me.  Thanks.

-Sandra the grammar geek

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCHv2][ARM] -mpure-code option for ARM
  2016-09-23 15:12             ` Sandra Loosemore
@ 2016-10-04 13:24               ` mickael guene
  2016-10-04 14:15                 ` Andre Vieira (lists)
  0 siblings, 1 reply; 24+ messages in thread
From: mickael guene @ 2016-10-04 13:24 UTC (permalink / raw)
  To: Andre Vieira (lists), gcc-patches

Hi Andre,

  I can't see new testsuite files in trunk :
gcc.target/arm/pure-code/ffunction-sections.c
gcc.target/arm/pure-code/no-literal-pool.c
gcc.target/arm/pure-code/pure-code.exp

  It seems you forgot to include them in your patch.
Can you post a new one with those files ?

Regards
Mickael

On 09/23/2016 05:04 PM, Sandra Loosemore wrote:
> On 09/23/2016 04:39 AM, Andre Vieira (lists) wrote:
>>> Hi Sandra,
>>>
>>> Is this better?
>>>
>>> Cheers,
>>> Andre
>>>
>>> gcc/ChangeLog
>>> 2016-09-23  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>>
>>>          * target.def(elf_flags_numeric): Change documentation to
>>>          present tense.
>>>
>> And here is the patch with the tm.texi regeneration.
>>
>> Cheers,
>> Andre
>>
>> gcc/ChangeLog
>> 2016-09-23  Andre Vieira  <andre.simoesdiasvieira@arm.com>
>>
>>          * target.def(elf_flags_numeric): Change documentation to
>>          present tense.
>>          * doc/tm.texi: Regenerate.
>>
>
> This looks good to me.  Thanks.
>
> -Sandra the grammar geek
>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCHv2][ARM] -mpure-code option for ARM
  2016-10-04 13:24               ` mickael guene
@ 2016-10-04 14:15                 ` Andre Vieira (lists)
  0 siblings, 0 replies; 24+ messages in thread
From: Andre Vieira (lists) @ 2016-10-04 14:15 UTC (permalink / raw)
  To: mickael guene, gcc-patches

On 04/10/16 14:24, mickael guene wrote:
> Hi Andre,
> 
>  I can't see new testsuite files in trunk :
> gcc.target/arm/pure-code/ffunction-sections.c
> gcc.target/arm/pure-code/no-literal-pool.c
> gcc.target/arm/pure-code/pure-code.exp
> 
>  It seems you forgot to include them in your patch.
> Can you post a new one with those files ?
> 
> Regards
> Mickael
> 

Yeah ... forgot to svn add, committed in revision r240746. Thanks for
that catch!

Cheers,
Andre

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2016-10-04 14:15 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-30 14:46 [PATCH][ARM] -mpure-code option for ARM Andre Vieira (lists)
2016-07-01 19:04 ` Sandra Loosemore
2016-07-07 12:29 ` mickael guene
2016-07-07 12:31 ` mickael guene
2016-07-11 16:57   ` [PATCHv2][ARM] " Andre Vieira (lists)
2016-07-25 10:52     ` [PATCHv2, PING][ARM] " Andre Vieira (lists)
2016-08-11 14:13       ` [PATCHv2, PING 2][ARM] " Andre Vieira (lists)
2016-08-30  8:01         ` [PATCHv2, PING 3][ARM] " Andre Vieira (lists)
2016-09-19  9:25           ` [PATCHv2, PING 4][ARM] " Andre Vieira (lists)
2016-09-22 14:22     ` [PATCHv2][ARM] " Richard Earnshaw (lists)
2016-09-22 15:10       ` [PATCHv3][ARM] " Andre Vieira (lists)
2016-09-22 15:47         ` Richard Earnshaw (lists)
2016-09-22 17:24           ` Andre Vieira (lists)
2016-09-22 19:34             ` Christophe Lyon
2016-09-22 20:05             ` Bill Seurer
2016-09-22 20:30               ` Martin Sebor
2016-09-22 20:20             ` Paolo Carlini
2016-09-23 13:47         ` [PATCH, arm-embedded] " Andre Vieira (lists)
2016-09-23  6:31       ` [PATCHv2][ARM] " Sandra Loosemore
2016-09-23  8:51         ` Andre Vieira (lists)
2016-09-23 10:41           ` Andre Vieira (lists)
2016-09-23 15:12             ` Sandra Loosemore
2016-10-04 13:24               ` mickael guene
2016-10-04 14:15                 ` Andre Vieira (lists)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).