public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 6/6] [ARC] Add 'aux' variable attribute.
  2017-11-02 12:34 [PATCH 0/6] [ARC] New baremetal features and fixes Claudiu Zissulescu
  2017-11-02 12:34 ` [PATCH 1/6] [ARC] Add JLI support Claudiu Zissulescu
  2017-11-02 12:34 ` [PATCH 4/6] [ARC] Rework delegitimate_address hook Claudiu Zissulescu
@ 2017-11-02 12:34 ` Claudiu Zissulescu
  2018-01-29 20:28   ` Andrew Burgess
  2017-11-02 12:34 ` [PATCH 3/6] [ARC] Add support for "register file 16" reduced register set Claudiu Zissulescu
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 18+ messages in thread
From: Claudiu Zissulescu @ 2017-11-02 12:34 UTC (permalink / raw)
  To: gcc-patches; +Cc: Claudiu.Zissulescu, Francois.Bedard, andrew.burgess

From: claziss <claziss@synopsys.com>

The 'aux' variable attribute is used to directly access the auxiliary
register space from C.

gcc/
2017-07-25  Claudiu Zissulescu  <claziss@synopsys.com>

	* config/arc/arc.c (arc_handle_aux_attribute): New function.
	(arc_attribute_table): Add 'aux' attribute.
	(arc_in_small_data_p): Consider aux like variables.
	(arc_is_aux_reg_p): New function.
	(arc_asm_output_aligned_decl_local): Ignore 'aux' like variables.
	(arc_get_aux_arg): New function.
	(prepare_move_operands): Handle aux-register access.
	(arc_handle_aux_attribute): New function.
	* doc/extend.texi (ARC Variable attributes): Add subsection.

testsuite/
2017-07-25  Claudiu Zissulescu  <claziss@synopsys.com>

	* gcc.target/arc/taux-1.c: New test.
	* gcc.target/arc/taux-2.c: Likewise.
---
 gcc/config/arc/arc.c                  | 160 +++++++++++++++++++++++++++++++++-
 gcc/doc/extend.texi                   |  13 +++
 gcc/testsuite/gcc.target/arc/taux-1.c |  38 ++++++++
 gcc/testsuite/gcc.target/arc/taux-2.c |  15 ++++
 4 files changed, 225 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/arc/taux-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/taux-2.c

diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index a397cbd..33f68ef 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -223,6 +223,7 @@ static tree arc_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
 static tree arc_handle_jli_attribute (tree *, tree, tree, int, bool *);
 static tree arc_handle_secure_attribute (tree *, tree, tree, int, bool *);
 static tree arc_handle_uncached_attribute (tree *, tree, tree, int, bool *);
+static tree arc_handle_aux_attribute (tree *, tree, tree, int, bool *);
 
 /* Initialized arc_attribute_table to NULL since arc doesnot have any
    machine specific supported attributes.  */
@@ -257,6 +258,8 @@ const struct attribute_spec arc_attribute_table[] =
   /* Bypass caches using .di flag.  */
   { "uncached", 0, 0, false, true, false, arc_handle_uncached_attribute,
     false },
+  /* Declare a variable as aux.  */
+  { "aux", 0, 1, true, false, false, arc_handle_aux_attribute, false },
   { NULL, 0, 0, false, false, false, NULL, false }
 };
 static int arc_comp_type_attributes (const_tree, const_tree);
@@ -8071,6 +8074,11 @@ arc_in_small_data_p (const_tree decl)
   if (lookup_attribute ("uncached", attr))
     return false;
 
+  /* and for aux regs.  */
+  attr = DECL_ATTRIBUTES (decl);
+  if (lookup_attribute ("aux", attr))
+    return false;
+
   if (DECL_SECTION_NAME (decl) != 0)
     {
       const char *name = DECL_SECTION_NAME (decl);
@@ -8238,6 +8246,35 @@ compact_sda_memory_operand (rtx op, machine_mode mode, bool short_p)
   return false;
 }
 
+/* Return TRUE if PAT is accessing an aux-reg.  */
+
+static bool
+arc_is_aux_reg_p (rtx pat)
+{
+  tree attrs = NULL_TREE;
+  tree addr;
+
+  if (!MEM_P (pat))
+    return false;
+
+  /* Get the memory attributes.  */
+  addr = MEM_EXPR (pat);
+  if (!addr)
+    return false;
+
+  /* Get the attributes.  */
+  if (TREE_CODE (addr) == VAR_DECL)
+    attrs = DECL_ATTRIBUTES (addr);
+  else if (TREE_CODE (addr) == MEM_REF)
+    attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 0)));
+  else
+    return false;
+
+  if (lookup_attribute ("aux", attrs))
+    return true;
+  return false;
+}
+
 /* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL.  */
 
 void
@@ -8246,7 +8283,14 @@ arc_asm_output_aligned_decl_local (FILE * stream, tree decl, const char * name,
 				   unsigned HOST_WIDE_INT align,
 				   unsigned HOST_WIDE_INT globalize_p)
 {
-  int in_small_data =   arc_in_small_data_p (decl);
+  int in_small_data = arc_in_small_data_p (decl);
+  rtx mem = decl == NULL_TREE ? NULL_RTX : DECL_RTL (decl);
+
+  /* Don't output aux-reg symbols.  */
+  if (mem != NULL_RTX && MEM_P (mem)
+      && SYMBOL_REF_P (XEXP (mem, 0))
+      && arc_is_aux_reg_p (mem))
+    return;
 
   if (in_small_data)
     switch_to_section (get_named_section (NULL, ".sbss", 0));
@@ -8586,12 +8630,80 @@ arc_expand_movmem (rtx *operands)
   return true;
 }
 
+static bool
+arc_get_aux_arg (rtx pat, int *auxr)
+{
+  tree attr, addr = MEM_EXPR (pat);
+  if (TREE_CODE (addr) != VAR_DECL)
+    return false;
+
+  attr = DECL_ATTRIBUTES (addr);
+  if (lookup_attribute ("aux", attr))
+    {
+      tree arg = TREE_VALUE (attr);
+      if (arg)
+	{
+	  *auxr = TREE_INT_CST_LOW (TREE_VALUE (arg));
+	  return true;
+	}
+    }
+
+  return false;
+}
+
 /* Prepare operands for move in MODE.  Return true iff the move has
    been emitted.  */
 
 bool
 prepare_move_operands (rtx *operands, machine_mode mode)
 {
+  /* First handle aux attribute.  */
+  if (mode == SImode
+      && (MEM_P (operands[0]) || MEM_P (operands[1])))
+    {
+      rtx tmp;
+      int auxr = 0;
+      if (MEM_P (operands[0]) && arc_is_aux_reg_p (operands[0]))
+	{
+	  /* Save operation.  */
+	  if (arc_get_aux_arg (operands[0], &auxr))
+	    {
+	      tmp = gen_reg_rtx (SImode);
+	      emit_move_insn (tmp, GEN_INT (auxr));
+	    }
+	  else
+	    {
+	      tmp = XEXP (operands[0], 0);
+	    }
+
+	  operands[1] = force_reg (SImode, operands[1]);
+	  emit_insn (gen_rtx_UNSPEC_VOLATILE
+		     (VOIDmode, gen_rtvec (2, operands[1], tmp),
+		      VUNSPEC_ARC_SR));
+	  return true;
+	}
+      if (MEM_P (operands[1]) && arc_is_aux_reg_p (operands[1]))
+	{
+	  if (arc_get_aux_arg (operands[1], &auxr))
+	    {
+	      tmp = gen_reg_rtx (SImode);
+	      emit_move_insn (tmp, GEN_INT (auxr));
+	    }
+	  else
+	    {
+	      tmp = XEXP (operands[1], 0);
+	      gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
+	    }
+	  /* Load operation.  */
+	  gcc_assert (REG_P (operands[0]));
+	  emit_insn (gen_rtx_SET (operands[0],
+				  gen_rtx_UNSPEC_VOLATILE
+				  (SImode, gen_rtvec (1, tmp),
+				   VUNSPEC_ARC_LR)));
+	  return true;
+	}
+    }
+
   /* We used to do this only for MODE_INT Modes, but addresses to floating
      point variables may well be in the small data section.  */
   if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[0], Pmode))
@@ -11127,6 +11239,52 @@ arc_is_uncached_mem_p (rtx pat)
   return false;
 }
 
+/* Handle aux attribute.  The auxiliary registers are addressed using
+   special instructions lr and sr.  The attribute 'aux' indicates if a
+   variable refers to the aux-regs and what is the register number
+   desired.  */
+
+static tree
+arc_handle_aux_attribute (tree *node,
+			  tree name, tree args, int,
+			  bool *no_add_attrs)
+{
+  /* Isn't it better to use address spaces for the aux-regs?  */
+  if (DECL_P (*node))
+    {
+      if (TREE_CODE (*node) != VAR_DECL)
+	{
+	  error ("%qE attribute only applies to variables",  name);
+	  *no_add_attrs = true;
+	}
+      else if (args)
+	{
+	  if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
+	    TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
+	  tree arg = TREE_VALUE (args);
+	  if (TREE_CODE (arg) != INTEGER_CST)
+	    {
+	      warning (0, "%qE attribute allows only an integer "
+		       "constant argument", name);
+	      *no_add_attrs = true;
+	    }
+	  /* FIXME! add range check.  TREE_INT_CST_LOW (arg) */
+	}
+
+      if (TREE_CODE (*node) == VAR_DECL)
+	{
+	  tree fntype = TREE_TYPE (*node);
+	  if (fntype && TREE_CODE (fntype) == POINTER_TYPE)
+	    {
+	      tree attrs = tree_cons (get_identifier ("aux"), NULL_TREE,
+				      TYPE_ATTRIBUTES (fntype));
+	      TYPE_ATTRIBUTES (fntype) = attrs;
+	    }
+	}
+    }
+  return NULL_TREE;
+}
+
 /* Implement TARGET_USE_ANCHORS_FOR_SYMBOL_P.  We don't want to use
    anchors for small data: the GP register acts as an anchor in that
    case.  We also don't want to use them for PC-relative accesses,
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 0f8ba05..1f6ef4e 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -5803,6 +5803,7 @@ attributes.
 
 @menu
 * Common Variable Attributes::
+* ARC Variable Attributes::
 * AVR Variable Attributes::
 * Blackfin Variable Attributes::
 * H8/300 Variable Attributes::
@@ -6165,6 +6166,18 @@ The @code{weak} attribute is described in
 
 @end table
 
+@node ARC Variable Attributes
+@subsection ARC Variable Attributes
+
+@table @code
+@item aux
+@cindex @code{aux} variable attribute, ARC
+The @code{aux} attribute is used to directly access the ARC's
+auxiliary register space from C.  The auxilirary register number is
+given via attribute argument.
+
+@end table
+
 @node AVR Variable Attributes
 @subsection AVR Variable Attributes
 
diff --git a/gcc/testsuite/gcc.target/arc/taux-1.c b/gcc/testsuite/gcc.target/arc/taux-1.c
new file mode 100644
index 0000000..a2b7778
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/taux-1.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 */
+
+
+#define __aux() __attribute__((aux))
+
+__aux() int *a_ptr;
+extern __aux() int a_var;
+
+/* Generates:
+   mov r0, @a_var
+   sr  10,[r0]
+*/
+void foo (void)
+{
+  a_var = 10;
+}
+
+/* Generates:
+   mov r0, @a_ptr
+   sr  a_var,[r0]
+*/
+void foo1 (void)
+{
+  a_ptr = &a_var;
+}
+
+/* Generates:
+   lr  %r1,[a_ptr]
+   sr  10,[%r1]
+*/
+void foo2 (void)
+{
+  *a_ptr = 10;
+}
+
+/* { dg-final { scan-assembler-times "sr" 3 } } */
+/* { dg-final { scan-assembler-times "lr" 1 } } */
diff --git a/gcc/testsuite/gcc.target/arc/taux-2.c b/gcc/testsuite/gcc.target/arc/taux-2.c
new file mode 100644
index 0000000..5644bcd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/taux-2.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 */
+
+#define __aux(r) __attribute__((aux(r)))
+static volatile __aux(0x1000) int var;
+
+int foo (void)
+{
+  var++;
+}
+
+/* { dg-final { scan-assembler-times "sr" 1 } } */
+/* { dg-final { scan-assembler-times "lr" 1 } } */
+/* { dg-final { scan-assembler "4096" } } */
+/* { dg-final { scan-assembler-not "\\.type\tvar, @object" } } */
-- 
1.9.1

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

* [PATCH 0/6] [ARC] New baremetal features and fixes
@ 2017-11-02 12:34 Claudiu Zissulescu
  2017-11-02 12:34 ` [PATCH 1/6] [ARC] Add JLI support Claudiu Zissulescu
                   ` (6 more replies)
  0 siblings, 7 replies; 18+ messages in thread
From: Claudiu Zissulescu @ 2017-11-02 12:34 UTC (permalink / raw)
  To: gcc-patches; +Cc: Claudiu.Zissulescu, Francois.Bedard, andrew.burgess

From: claziss <claziss@synopsys.com>

Hi,

This set of patches are adding support for:
     - JLI/SJLI instructions;
     - reduced register file 16 specific for particular ARC configurations;
     - 'uncached' attribute, used to toggle .di flag on variable basis;
     - 'aux' attribute, used to easily access auxiliary registers.

Also I've rework delegitimate address hook in a easier way.

Ok to apply?
Claudiu


Claudiu Zissulescu (3):
  [ARC] Add JLI support.
  [ARC] Add SJLI support.
  [ARC] Add support for "register file 16" reduced register set
  [ARC] Rework delegitimate_address hook
  [ARC] Add 'uncached' attribute.
  [ARC] Add 'aux' variable attribute.

 gcc/config/arc/arc-arches.def                     |   8 +-
 gcc/config/arc/arc-c.def                          |   1 +
 gcc/config/arc/arc-cpus.def                       |   1 +
 gcc/config/arc/arc-options.def                    |   2 +-
 gcc/config/arc/arc-protos.h                       |   4 +
 gcc/config/arc/arc-tables.opt                     |   3 +
 gcc/config/arc/arc.c                              | 645 ++++++++++++++++++++--
 gcc/config/arc/arc.h                              |   2 +-
 gcc/config/arc/arc.md                             | 138 ++---
 gcc/config/arc/arc.opt                            |   8 +
 gcc/config/arc/constraints.md                     |  13 +
 gcc/config/arc/elf.h                              |   7 +
 gcc/config/arc/fpx.md                             |  18 +-
 gcc/config/arc/genmultilib.awk                    |   2 +
 gcc/config/arc/linux.h                            |  10 +
 gcc/config/arc/predicates.md                      |   7 +-
 gcc/config/arc/simdext.md                         |   2 +-
 gcc/config/arc/t-multilib                         |   4 +-
 gcc/doc/extend.texi                               |  29 +
 gcc/doc/invoke.texi                               |  15 +-
 gcc/testsuite/gcc.dg/builtin-apply2.c             |   8 +-
 gcc/testsuite/gcc.target/arc/jli-1.c              |  19 +
 gcc/testsuite/gcc.target/arc/jli-2.c              |  19 +
 gcc/testsuite/gcc.target/arc/taux-1.c             |  38 ++
 gcc/testsuite/gcc.target/arc/taux-2.c             |  15 +
 gcc/testsuite/gcc.target/arc/tdelegitimize_addr.c |  23 +
 gcc/testsuite/gcc.target/arc/uncached.c           |  18 +
 libgcc/config/arc/lib1funcs.S                     |  22 +-
 28 files changed, 920 insertions(+), 161 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arc/jli-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/jli-2.c
 create mode 100644 gcc/testsuite/gcc.target/arc/taux-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/taux-2.c
 create mode 100755 gcc/testsuite/gcc.target/arc/tdelegitimize_addr.c
 create mode 100644 gcc/testsuite/gcc.target/arc/uncached.c

-- 
1.9.1

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

* [PATCH 3/6] [ARC] Add support for "register file 16" reduced register set
  2017-11-02 12:34 [PATCH 0/6] [ARC] New baremetal features and fixes Claudiu Zissulescu
                   ` (2 preceding siblings ...)
  2017-11-02 12:34 ` [PATCH 6/6] [ARC] Add 'aux' variable attribute Claudiu Zissulescu
@ 2017-11-02 12:34 ` Claudiu Zissulescu
  2018-01-16 10:52   ` Andrew Burgess
  2017-11-02 12:34 ` [PATCH 2/6] [ARC] Add SJLI support Claudiu Zissulescu
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 18+ messages in thread
From: Claudiu Zissulescu @ 2017-11-02 12:34 UTC (permalink / raw)
  To: gcc-patches; +Cc: Claudiu.Zissulescu, Francois.Bedard, andrew.burgess

gcc/
2017-03-20  Claudiu Zissulescu  <claziss@synopsys.com>

	* config/arc/arc-arches.def: Option mrf16 valid for all
	architectures.
	* config/arc/arc-c.def (__ARC_RF16__): New predefined macro.
	* config/arc/arc-cpus.def (em_mini): New cpu with rf16 on.
	* config/arc/arc-options.def (FL_RF16): Add mrf16 option.
	* config/arc/arc-tables.opt: Regenerate.
	* config/arc/arc.c (arc_conditional_register_usage): Handle
	reduced register file case.
	(arc_file_start): Set must have build attributes.
	* config/arc/arc.h (MAX_ARC_PARM_REGS): Conditional define using
	mrf16 option value.
	* config/arc/arc.opt (mrf16): Add new option.
	* config/arc/elf.h (ATTRIBUTE_PCS): Define.
	* config/arc/genmultilib.awk: Handle new mrf16 option.
	* config/arc/linux.h (ATTRIBUTE_PCS): Define.
	* config/arc/t-multilib: Regenerate.
	* doc/invoke.texi (ARC Options): Document mrf16 option.

gcc/testsuite/
2017-03-20  Claudiu Zissulescu  <claziss@synopsys.com>

	* gcc.dg/builtin-apply2.c: Change for the ARC's reduced register
	set file case.

libgcc/
2017-09-18  Claudiu Zissulescu  <claziss@synopsys.com>

	* config/arc/lib1funcs.S (__udivmodsi4): Use safe version for RF16
	option.
	(__divsi3): Use RF16 safe registers.
	(__modsi3): Likewise.
---
 gcc/config/arc/arc-arches.def         |  8 ++++----
 gcc/config/arc/arc-c.def              |  1 +
 gcc/config/arc/arc-cpus.def           |  1 +
 gcc/config/arc/arc-options.def        |  2 +-
 gcc/config/arc/arc-tables.opt         |  3 +++
 gcc/config/arc/arc.c                  | 27 +++++++++++++++++++++++++++
 gcc/config/arc/arc.h                  |  2 +-
 gcc/config/arc/arc.opt                |  4 ++++
 gcc/config/arc/elf.h                  |  4 ++++
 gcc/config/arc/genmultilib.awk        |  2 ++
 gcc/config/arc/linux.h                |  9 +++++++++
 gcc/config/arc/t-multilib             |  4 ++--
 gcc/doc/invoke.texi                   |  8 +++++++-
 gcc/testsuite/gcc.dg/builtin-apply2.c |  8 +++++++-
 libgcc/config/arc/lib1funcs.S         | 22 +++++++++++-----------
 15 files changed, 84 insertions(+), 21 deletions(-)

diff --git a/gcc/config/arc/arc-arches.def b/gcc/config/arc/arc-arches.def
index 29cb9c4..a0d585b 100644
--- a/gcc/config/arc/arc-arches.def
+++ b/gcc/config/arc/arc-arches.def
@@ -40,15 +40,15 @@
 
 ARC_ARCH ("arcem", em, FL_MPYOPT_1_6 | FL_DIVREM | FL_CD | FL_NORM	\
 	  | FL_BS | FL_SWAP | FL_FPUS | FL_SPFP | FL_DPFP		\
-	  | FL_SIMD | FL_FPUDA | FL_QUARK, 0)
+	  | FL_SIMD | FL_FPUDA | FL_QUARK | FL_RF16, 0)
 ARC_ARCH ("archs", hs, FL_MPYOPT_7_9 | FL_DIVREM | FL_NORM | FL_CD	\
 	  | FL_ATOMIC | FL_LL64 | FL_BS | FL_SWAP			\
-	  | FL_FPUS | FL_FPUD,						\
+	  | FL_FPUS | FL_FPUD | FL_RF16,				\
 	  FL_CD | FL_ATOMIC | FL_BS | FL_NORM | FL_SWAP)
 ARC_ARCH ("arc6xx", 6xx, FL_BS | FL_NORM | FL_SWAP | FL_MUL64 | FL_MUL32x16 \
-	  | FL_SPFP | FL_ARGONAUT | FL_DPFP, 0)
+	  | FL_SPFP | FL_ARGONAUT | FL_DPFP | FL_RF16, 0)
 ARC_ARCH ("arc700", 700, FL_ATOMIC | FL_BS | FL_NORM | FL_SWAP | FL_EA \
-	  | FL_SIMD | FL_SPFP | FL_ARGONAUT | FL_DPFP,		       \
+	  | FL_SIMD | FL_SPFP | FL_ARGONAUT | FL_DPFP | FL_RF16,       \
 	  FL_BS | FL_NORM | FL_SWAP)
 
 /* Local Variables: */
diff --git a/gcc/config/arc/arc-c.def b/gcc/config/arc/arc-c.def
index 8c5097e..c9443c9 100644
--- a/gcc/config/arc/arc-c.def
+++ b/gcc/config/arc/arc-c.def
@@ -28,6 +28,7 @@ ARC_C_DEF ("__ARC_NORM__",	TARGET_NORM)
 ARC_C_DEF ("__ARC_MUL64__",	TARGET_MUL64_SET)
 ARC_C_DEF ("__ARC_MUL32BY16__", TARGET_MULMAC_32BY16_SET)
 ARC_C_DEF ("__ARC_SIMD__",	TARGET_SIMD_SET)
+ARC_C_DEF ("__ARC_RF16__",	TARGET_RF16)
 
 ARC_C_DEF ("__ARC_BARREL_SHIFTER__", TARGET_BARREL_SHIFTER)
 
diff --git a/gcc/config/arc/arc-cpus.def b/gcc/config/arc/arc-cpus.def
index 60b4045..c2b0062 100644
--- a/gcc/config/arc/arc-cpus.def
+++ b/gcc/config/arc/arc-cpus.def
@@ -46,6 +46,7 @@
    TUNE	  Tune value for the given configuration, otherwise NONE.  */
 
 ARC_CPU (em,	    em, 0, NONE)
+ARC_CPU (em_mini,   em, FL_RF16, NONE)
 ARC_CPU (arcem,	    em, FL_MPYOPT_2|FL_CD|FL_BS, NONE)
 ARC_CPU (em4,	    em, FL_CD, NONE)
 ARC_CPU (em4_dmips, em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS, NONE)
diff --git a/gcc/config/arc/arc-options.def b/gcc/config/arc/arc-options.def
index be51614..8fc7b50 100644
--- a/gcc/config/arc/arc-options.def
+++ b/gcc/config/arc/arc-options.def
@@ -60,7 +60,7 @@
 ARC_OPT (FL_CD,	      (1ULL << 0), MASK_CODE_DENSITY,	   "code density")
 ARC_OPT (FL_DIVREM,   (1ULL << 1), MASK_DIVREM,		   "div/rem")
 ARC_OPT (FL_NORM,     (1ULL << 2), MASK_NORM_SET,	   "norm")
-
+ARC_OPT (FL_RF16,     (1ULL << 3), MASK_RF16,              "rf16")
 ARC_OPT (FL_ATOMIC,   (1ULL << 4), MASK_ATOMIC,		   "atomic")
 ARC_OPT (FL_LL64,     (1ULL << 5), MASK_LL64,		   "double load/store")
 ARC_OPT (FL_BS,	      (1ULL << 6), MASK_BARREL_SHIFTER,	   "barrel shifter")
diff --git a/gcc/config/arc/arc-tables.opt b/gcc/config/arc/arc-tables.opt
index ce23a52..21fc2d3 100644
--- a/gcc/config/arc/arc-tables.opt
+++ b/gcc/config/arc/arc-tables.opt
@@ -28,6 +28,9 @@ EnumValue
 Enum(processor_type) String(em) Value(PROCESSOR_em)
 
 EnumValue
+Enum(processor_type) String(em_mini) Value(PROCESSOR_em_mini)
+
+EnumValue
 Enum(processor_type) String(arcem) Value(PROCESSOR_arcem)
 
 EnumValue
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 9867e6e..e7194a2 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -1741,6 +1741,19 @@ arc_conditional_register_usage (void)
 	reg_alloc_order [i] = i;
     }
 
+  /* Reduced configuration: don't use r4-r9, r16-r25.  */
+  if (TARGET_RF16)
+    {
+      for (i = 4; i <= 9; i++)
+	{
+	  fixed_regs[i] = call_used_regs[i] = 1;
+	}
+      for (i = 16; i <= 25; i++)
+	{
+	  fixed_regs[i] = call_used_regs[i] = 1;
+	}
+    }
+
   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
     if (!call_used_regs[regno])
       CLEAR_HARD_REG_BIT (reg_class_contents[SIBCALL_REGS], regno);
@@ -5125,6 +5138,20 @@ static void arc_file_start (void)
 {
   default_file_start ();
   fprintf (asm_out_file, "\t.cpu %s\n", arc_cpu_string);
+
+  /* Set some want to have build attributes.  */
+  asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_PCS_config, %d\n",
+	       ATTRIBUTE_PCS);
+  asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_rf16, %d\n",
+	       TARGET_RF16 ? 1 : 0);
+  asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_pic, %d\n",
+	       flag_pic ? 2 : 0);
+  asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_tls, %d\n",
+	       (arc_tp_regno != -1) ? 1 : 0);
+  asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_sda, %d\n",
+	       TARGET_NO_SDATA_SET ? 0 : 2);
+  asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_exceptions, %d\n",
+	       TARGET_OPTFPE ? 1 : 0);
 }
 
 /* Implement `TARGET_ASM_FILE_END'.  */
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index ab12413..de211e2 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -727,7 +727,7 @@ arc_return_addr_rtx(COUNT,FRAME)
   ((CUM) = 0)
 
 /* The number of registers used for parameter passing.  Local to this file.  */
-#define MAX_ARC_PARM_REGS 8
+#define MAX_ARC_PARM_REGS (TARGET_RF16 ? 4 : 8)
 
 /* 1 if N is a possible register number for function argument passing.  */
 #define FUNCTION_ARG_REGNO_P(N) \
diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt
index 9baaf77..aacb599 100644
--- a/gcc/config/arc/arc.opt
+++ b/gcc/config/arc/arc.opt
@@ -523,3 +523,7 @@ Enum(arc_lpc) String(28) Value(28)
 
 EnumValue
 Enum(arc_lpc) String(32) Value(32)
+
+mrf16
+Target Report Mask(RF16)
+Enable 16-entry register file.
diff --git a/gcc/config/arc/elf.h b/gcc/config/arc/elf.h
index 175e9fd..288a845 100644
--- a/gcc/config/arc/elf.h
+++ b/gcc/config/arc/elf.h
@@ -67,5 +67,9 @@ along with GCC; see the file COPYING3.  If not see
 #undef TARGET_AUTO_MODIFY_REG_DEFAULT
 #define TARGET_AUTO_MODIFY_REG_DEFAULT 1
 
+/* Build attribute: procedure call standard.  */
+#undef ATTRIBUTE_PCS
+#define ATTRIBUTE_PCS 2
+
 #undef TARGET_ASM_FILE_END
 #define TARGET_ASM_FILE_END arc_file_end
diff --git a/gcc/config/arc/genmultilib.awk b/gcc/config/arc/genmultilib.awk
index 2734adc..3266bb0 100644
--- a/gcc/config/arc/genmultilib.awk
+++ b/gcc/config/arc/genmultilib.awk
@@ -130,6 +130,8 @@ BEGIN {
 	    line = line "/spfp"
 	  else if (cpu_flg[i] == "FL_DPFP")
 	    line = line "/dpfp"
+	  else if (cpu_flg[i] == "FL_RF16")
+	    line = line "/mrf16"
 	  else
 	    {
 	      print "Don't know the flag " cpu_flg[i] > "/dev/stderr"
diff --git a/gcc/config/arc/linux.h b/gcc/config/arc/linux.h
index 8abc2c6..5099391 100644
--- a/gcc/config/arc/linux.h
+++ b/gcc/config/arc/linux.h
@@ -92,3 +92,12 @@ along with GCC; see the file COPYING3.  If not see
 /* Pre/post modify with register displacement are default off.  */
 #undef TARGET_AUTO_MODIFY_REG_DEFAULT
 #define TARGET_AUTO_MODIFY_REG_DEFAULT 0
+
+#undef SUBTARGET_CPP_SPEC
+#define SUBTARGET_CPP_SPEC "\
+   %{pthread:-D_REENTRANT} \
+"
+
+/* Build attribute: procedure call standard.  */
+#undef ATTRIBUTE_PCS
+#define ATTRIBUTE_PCS 3
diff --git a/gcc/config/arc/t-multilib b/gcc/config/arc/t-multilib
index 9ffd4a6..eb1d8e3 100644
--- a/gcc/config/arc/t-multilib
+++ b/gcc/config/arc/t-multilib
@@ -21,9 +21,9 @@
 # along with GCC; see the file COPYING3.  If not see
 # <http://www.gnu.org/licenses/>.
 
-MULTILIB_OPTIONS = mcpu=em/mcpu=arcem/mcpu=em4/mcpu=em4_dmips/mcpu=em4_fpus/mcpu=em4_fpuda/mcpu=quarkse_em/mcpu=hs/mcpu=archs/mcpu=hs34/mcpu=hs38/mcpu=hs38_linux/mcpu=arc600/mcpu=arc600_norm/mcpu=arc600_mul64/mcpu=arc600_mul32x16/mcpu=arc601/mcpu=arc601_norm/mcpu=arc601_mul64/mcpu=arc601_mul32x16/mcpu=arc700/mcpu=nps400
+MULTILIB_OPTIONS = mcpu=em/mcpu=em_mini/mcpu=arcem/mcpu=em4/mcpu=em4_dmips/mcpu=em4_fpus/mcpu=em4_fpuda/mcpu=quarkse_em/mcpu=hs/mcpu=archs/mcpu=hs34/mcpu=hs38/mcpu=hs38_linux/mcpu=hs4x/mcpu=hs4xd/mcpu=arc600/mcpu=arc600_norm/mcpu=arc600_mul64/mcpu=arc600_mul32x16/mcpu=arc601/mcpu=arc601_norm/mcpu=arc601_mul64/mcpu=arc601_mul32x16/mcpu=arc700/mcpu=nps400
 
-MULTILIB_DIRNAMES = em arcem em4 em4_dmips em4_fpus em4_fpuda quarkse_em hs archs hs34 hs38 hs38_linux arc600 arc600_norm arc600_mul64 arc600_mul32x16 arc601 arc601_norm arc601_mul64 arc601_mul32x16 arc700 nps400
+MULTILIB_DIRNAMES = em em_mini arcem em4 em4_dmips em4_fpus em4_fpuda quarkse_em hs archs hs34 hs38 hs38_linux hs4x hs4xd arc600 arc600_norm arc600_mul64 arc600_mul32x16 arc601 arc601_norm arc601_mul64 arc601_mul32x16 arc700 nps400
 
 # Aliases:
 MULTILIB_MATCHES  = mcpu?arc600=mcpu?ARC600
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 041be9a..409f9be 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -625,7 +625,7 @@ Objective-C and Objective-C++ Dialects}.
 -mmixed-code  -mq-class  -mRcq  -mRcw  -msize-level=@var{level} @gol
 -mtune=@var{cpu}  -mmultcost=@var{num} @gol
 -munalign-prob-threshold=@var{probability}  -mmpy-option=@var{multo} @gol
--mdiv-rem  -mcode-density  -mll64  -mfpu=@var{fpu}}
+-mdiv-rem  -mcode-density  -mll64  -mfpu=@var{fpu} -mrf16}
 
 @emph{ARM Options}
 @gccoptlist{-mapcs-frame  -mno-apcs-frame @gol
@@ -14969,6 +14969,12 @@ specified, the compiler and run-time library might continue to use the
 loop mechanism for various needs.  This option defines macro
 @code{__ARC_LPC_WIDTH__} with the value of @var{width}.
 
+@item -mrf16
+@opindex mrf16
+This option instructs the compiler to generate code for a 16-entry
+register file.  This option defines the @code{__ARC_RF16__}
+preprocessor macro.
+
 @end table
 
 The following options are passed through to the assembler, and also
diff --git a/gcc/testsuite/gcc.dg/builtin-apply2.c b/gcc/testsuite/gcc.dg/builtin-apply2.c
index 3768caa..d811272 100644
--- a/gcc/testsuite/gcc.dg/builtin-apply2.c
+++ b/gcc/testsuite/gcc.dg/builtin-apply2.c
@@ -19,9 +19,15 @@
    E, F and G are passed on stack.  So the size of the stack argument
    data is 20.  */
 #define STACK_ARGUMENTS_SIZE  20
-#elif defined __MMIX__ || defined __arc__
+#elif defined __MMIX__
 /* No parameters on stack for bar.  */
 #define STACK_ARGUMENTS_SIZE 0
+#elif defined __arc__
+# ifdef __ARC_RF16__
+#  define STACK_ARGUMENTS_SIZE 4*4
+# else
+#  define STACK_ARGUMENTS_SIZE 0
+# endif
 #else
 #define STACK_ARGUMENTS_SIZE  64
 #endif
diff --git a/libgcc/config/arc/lib1funcs.S b/libgcc/config/arc/lib1funcs.S
index c3127ad..08e1510 100644
--- a/libgcc/config/arc/lib1funcs.S
+++ b/libgcc/config/arc/lib1funcs.S
@@ -370,7 +370,7 @@ SYM(__udivmodsi4):
 	mov_s	r0,1
 	j_s.d	[blink]
 	mov.c	r0,0
-#elif !defined (__OPTIMIZE_SIZE__)
+#elif !defined (__OPTIMIZE_SIZE__) && !defined (__ARC_RF16__)
 #if defined (__ARC_NORM__) && defined (__ARC_BARREL_SHIFTER__)
 	lsr_s r2,r0
 	brhs.d r1,r2,.Lret0_3
@@ -509,14 +509,14 @@ SYM(__udivsi3):
 #ifndef __ARC_EA__
 SYM(__divsi3):
 	/* A5 / ARC60? */
-	mov r7,blink
-	xor r6,r0,r1
+	mov r12,blink
+	xor r11,r0,r1
 	abs_s r0,r0
 	bl.d @SYM(__udivmodsi4)
-	 abs_s r1,r1
-	tst r6,r6
-	j.d [r7]
-	 neg.mi r0,r0
+	abs_s r1,r1
+	tst r11,r11
+	j.d [r12]
+	neg.mi r0,r0
 #else 	/* !ifndef __ARC_EA__ */
 	;; We can use the abs, norm, divaw and mpy instructions for ARC700
 #define MULDIV
@@ -913,14 +913,14 @@ SYM(__modsi3):
 #ifndef __ARC_EA__
 	/* A5 / ARC60? */
 	mov_s r12,blink
-	mov_s r6,r0
+	mov_s r11,r0
 	abs_s r0,r0
 	bl.d @SYM(__udivmodsi4)
-	 abs_s r1,r1
-	tst r6,r6
+	abs_s r1,r1
+	tst r11,r11
 	neg_s r0,r1
 	j_s.d [r12]
-	 mov.pl r0,r1
+	mov.pl r0,r1
 #else /* __ARC_EA__ */
 	abs_s	r2,r1
 	norm.f	r4,r0
-- 
1.9.1

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

* [PATCH 2/6] [ARC] Add SJLI support.
  2017-11-02 12:34 [PATCH 0/6] [ARC] New baremetal features and fixes Claudiu Zissulescu
                   ` (3 preceding siblings ...)
  2017-11-02 12:34 ` [PATCH 3/6] [ARC] Add support for "register file 16" reduced register set Claudiu Zissulescu
@ 2017-11-02 12:34 ` Claudiu Zissulescu
  2018-01-16 10:37   ` Andrew Burgess
  2017-11-02 12:34 ` [PATCH 5/6] [ARC] Add 'uncached' attribute Claudiu Zissulescu
  2018-02-01 10:10 ` [PATCH 0/6] [ARC] New baremetal features and fixes Claudiu Zissulescu
  6 siblings, 1 reply; 18+ messages in thread
From: Claudiu Zissulescu @ 2017-11-02 12:34 UTC (permalink / raw)
  To: gcc-patches; +Cc: Claudiu.Zissulescu, Francois.Bedard, andrew.burgess

gcc/
2017-02-20  Claudiu Zissulescu  <claziss@synopsys.com>

	* config/arc/arc-protos.h: Add arc_is_secure_call_p proto.
	* config/arc/arc.c (arc_handle_secure_attribute): New function.
	(arc_attribute_table): Add 'secure_call' attribute.
	(arc_print_operand): Print secure call operand.
	(arc_function_ok_for_sibcall): Don't optimize tail calls when
	secure.
	(arc_is_secure_call_p): New function.
	* config/arc/arc.md (call_i): Add support for sjli instruction.
	(call_value_i): Likewise.
	* config/arc/constraints.md (Csc): New constraint.
---
 gcc/config/arc/arc-protos.h   |   1 +
 gcc/config/arc/arc.c          | 164 +++++++++++++++++++++++++++++++-----------
 gcc/config/arc/arc.md         |  32 +++++----
 gcc/config/arc/constraints.md |   7 ++
 gcc/doc/extend.texi           |   6 ++
 5 files changed, 155 insertions(+), 55 deletions(-)

diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h
index 1557293..f8e7937 100644
--- a/gcc/config/arc/arc-protos.h
+++ b/gcc/config/arc/arc-protos.h
@@ -118,3 +118,4 @@ extern bool arc_store_addr_hazard_p (rtx_insn *, rtx_insn *);
 extern rtx arc_eh_return_address_location (void);
 extern bool arc_is_jli_call_p (rtx);
 extern void arc_file_end (void);
+extern bool arc_is_secure_call_p (rtx);
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 489cb91..9867e6e 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -221,6 +221,7 @@ static int get_arc_condition_code (rtx);
 static tree arc_handle_interrupt_attribute (tree *, tree, tree, int, bool *);
 static tree arc_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
 static tree arc_handle_jli_attribute (tree *, tree, tree, int, bool *);
+static tree arc_handle_secure_attribute (tree *, tree, tree, int, bool *);
 
 
 /* Initialized arc_attribute_table to NULL since arc doesnot have any
@@ -250,6 +251,9 @@ const struct attribute_spec arc_attribute_table[] =
      table is given as input parameter.  */
   { "jli_fixed",    1, 1, false, true,  true,  arc_handle_jli_attribute,
     false },
+  /* Call a function using secure-mode.  */
+  { "secure_call",  1, 1, false, true, true, arc_handle_secure_attribute,
+    false },
   { NULL, 0, 0, false, false, false, NULL, false }
 };
 static int arc_comp_type_attributes (const_tree, const_tree);
@@ -3687,6 +3691,46 @@ arc_trampoline_adjust_address (rtx addr)
   return plus_constant (Pmode, addr, 2);
 }
 
+/* Add the given function declaration to emit code in JLI section.  */
+
+static void
+arc_add_jli_section (rtx pat)
+{
+  const char *name;
+  tree attrs;
+  arc_jli_section *sec = arc_jli_sections, *new_section;
+  tree decl = SYMBOL_REF_DECL (pat);
+
+  if (!pat)
+    return;
+
+  if (decl)
+    {
+      /* For fixed locations do not generate the jli table entry.  It
+	 should be provided by the user as an asm file.  */
+      attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
+      if (lookup_attribute ("jli_fixed", attrs))
+	return;
+    }
+
+  name = XSTR (pat, 0);
+
+  /* Don't insert the same symbol twice.  */
+  while (sec != NULL)
+    {
+      if(strcmp (name, sec->name) == 0)
+	return;
+      sec = sec->next;
+    }
+
+  /* New name, insert it.  */
+  new_section = (arc_jli_section *) xmalloc (sizeof (arc_jli_section));
+  gcc_assert (new_section != NULL);
+  new_section->name = name;
+  new_section->next = arc_jli_sections;
+  arc_jli_sections = new_section;
+}
+
 /* This is set briefly to 1 when we output a ".as" address modifer, and then
    reset when we output the scaled address.  */
 static int output_scaled = 0;
@@ -3714,6 +3758,7 @@ static int output_scaled = 0;
     'D'
     'R': Second word
     'S': JLI instruction
+    'j': used by mov instruction to properly emit jli related labels.
     'B': Branch comparison operand - suppress sda reference
     'H': Most significant word
     'L': Least significant word
@@ -3928,6 +3973,7 @@ arc_print_operand (FILE *file, rtx x, int code)
       else
 	output_operand_lossage ("invalid operand to %%R code");
       return;
+    case 'j':
     case 'S' :
       if (GET_CODE (x) == SYMBOL_REF
 	  && arc_is_jli_call_p (x))
@@ -3939,6 +3985,9 @@ arc_print_operand (FILE *file, rtx x, int code)
 			    : NULL_TREE);
 	      if (lookup_attribute ("jli_fixed", attrs))
 		{
+		  /* No special treatment for jli_fixed functions.  */
+		  if (code == 'j' )
+		    break;
 		  fprintf (file, "%ld\t; @",
 			   TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs))));
 		  assemble_name (file, XSTR (x, 0));
@@ -3947,6 +3996,22 @@ arc_print_operand (FILE *file, rtx x, int code)
 	    }
 	  fprintf (file, "@__jli.");
 	  assemble_name (file, XSTR (x, 0));
+	  if (code == 'j')
+	    arc_add_jli_section (x);
+	  return;
+	}
+      if (GET_CODE (x) == SYMBOL_REF
+	  && arc_is_secure_call_p (x))
+	{
+	  /* No special treatment for secure functions.  */
+	  if (code == 'j' )
+	    break;
+	  tree attrs = (TREE_TYPE (SYMBOL_REF_DECL (x)) != error_mark_node
+			? TYPE_ATTRIBUTES (TREE_TYPE (SYMBOL_REF_DECL (x)))
+			: NULL_TREE);
+	  fprintf (file, "%ld\t; @",
+		   TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs))));
+	  assemble_name (file, XSTR (x, 0));
 	  return;
 	}
       break;
@@ -6897,6 +6962,8 @@ arc_function_ok_for_sibcall (tree decl,
 	return false;
       if (lookup_attribute ("jli_fixed", attrs))
 	return false;
+      if (lookup_attribute ("secure_call", attrs))
+	return false;
     }
 
   /* Everything else is ok.  */
@@ -7594,46 +7661,6 @@ arc_reorg_loops (void)
   reorg_loops (true, &arc_doloop_hooks);
 }
 
-/* Add the given function declaration to emit code in JLI section.  */
-
-static void
-arc_add_jli_section (rtx pat)
-{
-  const char *name;
-  tree attrs;
-  arc_jli_section *sec = arc_jli_sections, *new_section;
-  tree decl = SYMBOL_REF_DECL (pat);
-
-  if (!pat)
-    return;
-
-  if (decl)
-    {
-      /* For fixed locations do not generate the jli table entry.  It
-	 should be provided by the user as an asm file.  */
-      attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
-      if (lookup_attribute ("jli_fixed", attrs))
-	return;
-    }
-
-  name = XSTR (pat, 0);
-
-  /* Don't insert the same symbol twice.  */
-  while (sec != NULL)
-    {
-      if(strcmp (name, sec->name) == 0)
-	return;
-      sec = sec->next;
-    }
-
-  /* New name, insert it.  */
-  new_section = (arc_jli_section *) xmalloc (sizeof (arc_jli_section));
-  gcc_assert (new_section != NULL);
-  new_section->name = name;
-  new_section->next = arc_jli_sections;
-  arc_jli_sections = new_section;
-}
-
 /* Scan all calls and add symbols to be emitted in the jli section if
    needed.  */
 
@@ -10968,6 +10995,63 @@ arc_handle_jli_attribute (tree *node ATTRIBUTE_UNUSED,
    return NULL_TREE;
 }
 
+/* Handle and "scure" attribute; arguments as in struct
+   attribute_spec.handler.  */
+
+static tree
+arc_handle_secure_attribute (tree *node ATTRIBUTE_UNUSED,
+			  tree name, tree args, int,
+			  bool *no_add_attrs)
+{
+  if (!TARGET_EM)
+    {
+      warning (OPT_Wattributes,
+	       "%qE attribute only valid for ARC EM architecture",
+	       name);
+      *no_add_attrs = true;
+    }
+
+  if (args == NULL_TREE)
+    {
+      warning (OPT_Wattributes,
+	       "argument of %qE attribute is missing",
+	       name);
+      *no_add_attrs = true;
+    }
+  else
+    {
+      if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
+	TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
+      tree arg = TREE_VALUE (args);
+      if (TREE_CODE (arg) != INTEGER_CST)
+	{
+	  warning (0, "%qE attribute allows only an integer constant argument",
+		   name);
+	  *no_add_attrs = true;
+	}
+      /* FIXME! add range check.  TREE_INT_CST_LOW (arg) */
+    }
+   return NULL_TREE;
+}
+
+/* Return nonzero if the symbol is a secure function.  */
+
+bool
+arc_is_secure_call_p (rtx pat)
+{
+  tree attrs;
+  tree decl = SYMBOL_REF_DECL (pat);
+
+  if (!decl)
+    return false;
+
+  attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
+  if (lookup_attribute ("secure_call", attrs))
+    return true;
+
+  return false;
+}
+
 /* Implement TARGET_USE_ANCHORS_FOR_SYMBOL_P.  We don't want to use
    anchors for small data: the GP register acts as an anchor in that
    case.  We also don't want to use them for PC-relative accesses,
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index c72420c..48625d3 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -736,10 +736,10 @@
    mov%? %0,%1		;11
    add %0,%1		;12
    add %0,pcl,%1@pcl    ;13
-   mov%? %0,%1  	;14
-   mov%? %0,%1		;15
-   mov%? %0,%1		;16
-   ld%?%U1 %0,%1	;17
+   mov%? %0,%j1 	;14
+   mov%? %0,%j1		;15
+   mov%? %0,%j1		;16
+   ld%? %0,%1		;17
    st%? %1,%0%&		;18
    * return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\");
    * return arc_short_long (insn, \"pop%? %0%&\",  \"ld%U1 %0,%1%&\");
@@ -4229,7 +4229,7 @@
 ; alternative 1 ("q"), that means that we can't use the short form.
 (define_insn "*call_i"
   [(call (mem:SI (match_operand:SI 0
-		  "call_address_operand" "Rcq,q,c,Cji,Cbp,Cbr,L,I,Cal"))
+		  "call_address_operand" "Rcq,q,c,Cji,Csc,Cbp,Cbr,L,I,Cal"))
 	 (match_operand 1 "" ""))
    (clobber (reg:SI 31))]
   ""
@@ -4238,15 +4238,16 @@
    jl%!%* [%0]%&
    jl%!%* [%0]
    jli_s %S0
+   sjli  %S0
    bl%!%* %P0
    bl%!%* %P0
    jl%!%* %0
    jl%* %0
    jl%! %0"
-  [(set_attr "type" "call,call,call,call_no_delay_slot,call,call,call,call,call_no_delay_slot")
-   (set_attr "iscompact" "maybe,false,*,true,*,*,*,*,*")
-   (set_attr "predicable" "no,no,yes,no,yes,no,yes,no,yes")
-   (set_attr "length" "*,*,4,2,4,4,4,4,8")])
+  [(set_attr "type" "call,call,call,call_no_delay_slot,call_no_delay_slot,call,call,call,call,call_no_delay_slot")
+   (set_attr "iscompact" "maybe,false,*,true,*,*,*,*,*,*")
+   (set_attr "predicable" "no,no,yes,no,no,yes,no,yes,no,yes")
+   (set_attr "length" "*,*,4,2,4,4,4,4,4,8")])
 
 (define_expand "call_value"
   ;; operand 2 is stack_size_rtx
@@ -4272,9 +4273,9 @@
 ; At instruction output time, if it doesn't match and we end up with
 ; alternative 1 ("q"), that means that we can't use the short form.
 (define_insn "*call_value_i"
-  [(set (match_operand 0 "dest_reg_operand"  "=Rcq,q,w,  w,  w,  w,w,w,  w")
+  [(set (match_operand 0 "dest_reg_operand"  "=Rcq,q,w,  w,  w,  w,  w,w,w,  w")
 	(call (mem:SI (match_operand:SI 1
-		       "call_address_operand" "Rcq,q,c,Cji,Cbp,Cbr,L,I,Cal"))
+		       "call_address_operand" "Rcq,q,c,Cji,Csc,Cbp,Cbr,L,I,Cal"))
 	      (match_operand 2 "" "")))
    (clobber (reg:SI 31))]
   ""
@@ -4283,15 +4284,16 @@
    jl%!%* [%1]%&
    jl%!%* [%1]
    jli_s %S1
+   sjli  %S1
    bl%!%* %P1;1
    bl%!%* %P1;1
    jl%!%* %1
    jl%* %1
    jl%! %1"
-  [(set_attr "type" "call,call,call,call_no_delay_slot,call,call,call,call,call_no_delay_slot")
-   (set_attr "iscompact" "maybe,false,*,true,*,*,*,*,*")
-   (set_attr "predicable" "no,no,yes,no,yes,no,yes,no,yes")
-   (set_attr "length" "*,*,4,2,4,4,4,4,8")])
+  [(set_attr "type" "call,call,call,call_no_delay_slot,call_no_delay_slot,call,call,call,call,call_no_delay_slot")
+   (set_attr "iscompact" "maybe,false,*,true,false,*,*,*,*,*")
+   (set_attr "predicable" "no,no,yes,no,no,yes,no,yes,no,yes")
+   (set_attr "length" "*,*,4,2,4,4,4,4,4,8")])
 
 ; There is a bl_s instruction (16 bit opcode branch-and-link), but we can't
 ; use it for lack of inter-procedural branch shortening.
diff --git a/gcc/config/arc/constraints.md b/gcc/config/arc/constraints.md
index 7114e6e..3fed018 100644
--- a/gcc/config/arc/constraints.md
+++ b/gcc/config/arc/constraints.md
@@ -407,6 +407,13 @@
        (match_test "TARGET_CODE_DENSITY")
        (match_test "arc_is_jli_call_p (op)")))
 
+(define_constraint "Csc"
+  "Secure call"
+  (and (match_code "symbol_ref")
+       (match_test "TARGET_CODE_DENSITY")
+       (match_test "TARGET_EM")
+       (match_test "arc_is_secure_call_p (op)")))
+
 (define_constraint "Cpc"
   "pc-relative constant"
   (match_test "arc_legitimate_pic_addr_p (op)"))
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 1e16d06..0f8ba05 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -3761,6 +3761,12 @@ Forces the particular function to be called using jli instruction.
 Identical like the above one, but the location of the function in the
 JLI table is known and given as an attribute parameter.
 
+@item secure_call
+@cindex @code{secure_call} function attribute, ARC
+This attribute allows one to mark secure-code functions that are
+callable from normal mode.  The location of the secure call function
+into the SJLI table needs to be passed as argument.
+
 @end table
 
 @node ARM Function Attributes
-- 
1.9.1

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

* [PATCH 5/6] [ARC] Add 'uncached' attribute.
  2017-11-02 12:34 [PATCH 0/6] [ARC] New baremetal features and fixes Claudiu Zissulescu
                   ` (4 preceding siblings ...)
  2017-11-02 12:34 ` [PATCH 2/6] [ARC] Add SJLI support Claudiu Zissulescu
@ 2017-11-02 12:34 ` Claudiu Zissulescu
  2017-11-03  2:26   ` Sandra Loosemore
  2018-01-29 20:23   ` Andrew Burgess
  2018-02-01 10:10 ` [PATCH 0/6] [ARC] New baremetal features and fixes Claudiu Zissulescu
  6 siblings, 2 replies; 18+ messages in thread
From: Claudiu Zissulescu @ 2017-11-02 12:34 UTC (permalink / raw)
  To: gcc-patches; +Cc: Claudiu.Zissulescu, Francois.Bedard, andrew.burgess

From: claziss <claziss@synopsys.com>

The _Uncached type qualifier can be used to bypass the cache without
resorting to declaring variables as volatile.

gcc/
2017-07-12  Claudiu Zissulescu  <claziss@synopsys.com>

	* config/arc/arc-protos.h (arc_is_uncached_mem_p): Function proto.
	* config/arc/arc.c (arc_handle_uncached_attribute): New function.
	(arc_attribute_table): Add 'uncached' attribute.
	(arc_print_operand): Print '.di' flag for uncached memory
	accesses.
	(arc_in_small_data_p): Do not consider for small data the uncached
	types.
	(arc_is_uncached_mem_p): New function.
	* config/arc/predicates.md (compact_store_memory_operand): Check
	for uncached memory accesses.
	(nonvol_nonimm_operand): Likewise.

gcc/testsuite
2017-07-12  Claudiu Zissulescu  <claziss@synopsys.com>

	* gcc.target/arc/uncached.c: New test.
---
 gcc/config/arc/arc-protos.h             |  1 +
 gcc/config/arc/arc.c                    | 65 ++++++++++++++++++++++++++++++++-
 gcc/config/arc/predicates.md            |  7 +++-
 gcc/testsuite/gcc.target/arc/uncached.c | 18 +++++++++
 4 files changed, 88 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arc/uncached.c

diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h
index f8e7937..cc00730 100644
--- a/gcc/config/arc/arc-protos.h
+++ b/gcc/config/arc/arc-protos.h
@@ -47,6 +47,7 @@ extern void arc_expand_compare_and_swap (rtx *);
 extern bool compact_memory_operand_p (rtx, machine_mode, bool, bool);
 extern int arc_return_address_register (unsigned int);
 extern unsigned int arc_compute_function_type (struct function *);
+extern bool arc_is_uncached_mem_p (rtx);
 #endif /* RTX_CODE */
 
 extern unsigned int arc_compute_frame_size (int);
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 07dd072..a397cbd 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -222,7 +222,7 @@ static tree arc_handle_interrupt_attribute (tree *, tree, tree, int, bool *);
 static tree arc_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
 static tree arc_handle_jli_attribute (tree *, tree, tree, int, bool *);
 static tree arc_handle_secure_attribute (tree *, tree, tree, int, bool *);
-
+static tree arc_handle_uncached_attribute (tree *, tree, tree, int, bool *);
 
 /* Initialized arc_attribute_table to NULL since arc doesnot have any
    machine specific supported attributes.  */
@@ -254,6 +254,9 @@ const struct attribute_spec arc_attribute_table[] =
   /* Call a function using secure-mode.  */
   { "secure_call",  1, 1, false, true, true, arc_handle_secure_attribute,
     false },
+  /* Bypass caches using .di flag.  */
+  { "uncached", 0, 0, false, true, false, arc_handle_uncached_attribute,
+    false },
   { NULL, 0, 0, false, false, false, NULL, false }
 };
 static int arc_comp_type_attributes (const_tree, const_tree);
@@ -4135,7 +4138,8 @@ arc_print_operand (FILE *file, rtx x, int code)
 	 refs are defined to use the cache bypass mechanism.  */
       if (GET_CODE (x) == MEM)
 	{
-	  if (MEM_VOLATILE_P (x) && !TARGET_VOLATILE_CACHE_SET )
+	  if ((MEM_VOLATILE_P (x) && !TARGET_VOLATILE_CACHE_SET)
+	      || arc_is_uncached_mem_p (x))
 	    fputs (".di", file);
 	}
       else
@@ -8038,6 +8042,7 @@ static bool
 arc_in_small_data_p (const_tree decl)
 {
   HOST_WIDE_INT size;
+  tree attr;
 
   /* Only variables are going into small data area.  */
   if (TREE_CODE (decl) != VAR_DECL)
@@ -8061,6 +8066,11 @@ arc_in_small_data_p (const_tree decl)
       && TREE_THIS_VOLATILE (decl))
     return false;
 
+  /* Likewise for uncached data.  */
+  attr = TYPE_ATTRIBUTES (TREE_TYPE (decl));
+  if (lookup_attribute ("uncached", attr))
+    return false;
+
   if (DECL_SECTION_NAME (decl) != 0)
     {
       const char *name = DECL_SECTION_NAME (decl);
@@ -11066,6 +11076,57 @@ arc_is_secure_call_p (rtx pat)
   return false;
 }
 
+/* Handle "uncached" qualifier.  */
+
+static tree
+arc_handle_uncached_attribute (tree *node,
+			       tree name, tree args,
+			       int flags ATTRIBUTE_UNUSED,
+			       bool *no_add_attrs)
+{
+  if (DECL_P (*node) && TREE_CODE (*node) != TYPE_DECL)
+    {
+      error ("%qE attribute only applies to types",
+	     name);
+      *no_add_attrs = true;
+    }
+  else if (args)
+    {
+      warning (OPT_Wattributes, "argument of %qE attribute ignored", name);
+    }
+  return NULL_TREE;
+}
+
+/* Return TRUE if PAT is a memory addressing an uncached data.  */
+
+bool
+arc_is_uncached_mem_p (rtx pat)
+{
+  tree attrs;
+  tree ttype;
+  struct mem_attrs *refattrs;
+
+  if (!MEM_P (pat))
+    return false;
+
+  /* Get the memory attributes.  */
+  refattrs = MEM_ATTRS (pat);
+  if (!refattrs
+      || !refattrs->expr)
+    return false;
+
+  /* Get the type declaration.  */
+  ttype = TREE_TYPE (refattrs->expr);
+  if (!ttype)
+    return false;
+
+  /* Get the type attributes.  */
+  attrs = TYPE_ATTRIBUTES (ttype);
+  if (lookup_attribute ("uncached", attrs))
+    return true;
+  return false;
+}
+
 /* Implement TARGET_USE_ANCHORS_FOR_SYMBOL_P.  We don't want to use
    anchors for small data: the GP register acts as an anchor in that
    case.  We also don't want to use them for PC-relative accesses,
diff --git a/gcc/config/arc/predicates.md b/gcc/config/arc/predicates.md
index 3dfe0ca..68887be 100644
--- a/gcc/config/arc/predicates.md
+++ b/gcc/config/arc/predicates.md
@@ -217,6 +217,10 @@
   if (MEM_VOLATILE_P (op) && !TARGET_VOLATILE_CACHE_SET)
      return 0;
 
+  /* likewise for uncached types.  */
+  if (arc_is_uncached_mem_p (op))
+     return 0;
+
   size = GET_MODE_SIZE (mode);
 
   /* dword operations really put out 2 instructions, so eliminate them.  */
@@ -412,7 +416,8 @@
 ;; and only the standard movXX patterns are set up to handle them.
 (define_predicate "nonvol_nonimm_operand"
   (and (match_code "subreg, reg, mem")
-       (match_test "(GET_CODE (op) != MEM || !MEM_VOLATILE_P (op)) && nonimmediate_operand (op, mode)"))
+       (match_test "(GET_CODE (op) != MEM || !MEM_VOLATILE_P (op)) && nonimmediate_operand (op, mode)")
+       (match_test "!arc_is_uncached_mem_p (op)"))
 )
 
 ;; Return 1 if OP is a comparison operator valid for the mode of CC.
diff --git a/gcc/testsuite/gcc.target/arc/uncached.c b/gcc/testsuite/gcc.target/arc/uncached.c
new file mode 100644
index 0000000..367e8dc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/uncached.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+
+/* Check 'uncached' type attribute.  */
+
+typedef volatile unsigned int RwReg  __attribute__ ((uncached));
+
+typedef struct {
+  RwReg UART_THR;
+  int SIDE_DISH;
+} UART;
+
+void uart_putc(UART *port, char c)
+{
+    port->UART_THR = c;
+    port->SIDE_DISH = c;
+}
+
+/* { dg-final { scan-assembler-times "st\.di" 1 } } */
-- 
1.9.1

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

* [PATCH 4/6] [ARC] Rework delegitimate_address hook
  2017-11-02 12:34 [PATCH 0/6] [ARC] New baremetal features and fixes Claudiu Zissulescu
  2017-11-02 12:34 ` [PATCH 1/6] [ARC] Add JLI support Claudiu Zissulescu
@ 2017-11-02 12:34 ` Claudiu Zissulescu
  2018-01-23 23:07   ` Andrew Burgess
  2017-11-02 12:34 ` [PATCH 6/6] [ARC] Add 'aux' variable attribute Claudiu Zissulescu
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 18+ messages in thread
From: Claudiu Zissulescu @ 2017-11-02 12:34 UTC (permalink / raw)
  To: gcc-patches; +Cc: Claudiu.Zissulescu, Francois.Bedard, andrew.burgess

From: claziss <claziss@synopsys.com>

Delegitimize address is used to undo the obfuscating effect of PIC
addresses, returning the address in a way which is understood by the
compiler.

gcc/
2017-04-25  Claudiu Zissulescu  <claziss@synopsys.com>

	* config/arc/arc.c (arc_delegitimize_address_0): Refactored to
	recognize new pic like addresses.
	(arc_delegitimize_address): Clean up.

testsuite/
2017-08-31  Claudiu Zissulescu  <claziss@synopsys.com>

	* testsuite/gcc.target/arc/tdelegitimize_addr.c: New test.
---
 gcc/config/arc/arc.c                              | 91 ++++++++++-------------
 gcc/testsuite/gcc.target/arc/tdelegitimize_addr.c | 23 ++++++
 2 files changed, 62 insertions(+), 52 deletions(-)
 create mode 100755 gcc/testsuite/gcc.target/arc/tdelegitimize_addr.c

diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index e7194a2..07dd072 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -9506,68 +9506,55 @@ arc_legitimize_address (rtx orig_x, rtx oldx, machine_mode mode)
 }
 
 static rtx
-arc_delegitimize_address_0 (rtx x)
+arc_delegitimize_address_0 (rtx op)
 {
-  rtx u, gp, p;
-
-  if (GET_CODE (x) == CONST && GET_CODE (u = XEXP (x, 0)) == UNSPEC)
+  switch (GET_CODE (op))
     {
-      if (XINT (u, 1) == ARC_UNSPEC_GOT
-	  || XINT (u, 1) == ARC_UNSPEC_GOTOFFPC)
-	return XVECEXP (u, 0, 0);
+    case CONST:
+      return arc_delegitimize_address_0 (XEXP (op, 0));
+
+    case UNSPEC:
+      switch (XINT (op, 1))
+	{
+	case ARC_UNSPEC_GOT:
+	case ARC_UNSPEC_GOTOFFPC:
+	  return XVECEXP (op, 0, 0);
+	default:
+	  break;
+	}
+      break;
+
+    case PLUS:
+      {
+	rtx t1 = arc_delegitimize_address_0 (XEXP (op, 0));
+	rtx t2 = XEXP (op, 1);
+
+	if (t1 && t2)
+	  return gen_rtx_PLUS (GET_MODE (op), t1, t2);
+	break;
+      }
+
+    default:
+      break;
     }
-  else if (GET_CODE (x) == CONST && GET_CODE (p = XEXP (x, 0)) == PLUS
-	   && GET_CODE (u = XEXP (p, 0)) == UNSPEC
-	   && (XINT (u, 1) == ARC_UNSPEC_GOT
-	       || XINT (u, 1) == ARC_UNSPEC_GOTOFFPC))
-    return gen_rtx_CONST
-	    (GET_MODE (x),
-	     gen_rtx_PLUS (GET_MODE (p), XVECEXP (u, 0, 0), XEXP (p, 1)));
-  else if (GET_CODE (x) == PLUS
-	   && ((REG_P (gp = XEXP (x, 0))
-		&& REGNO (gp) == PIC_OFFSET_TABLE_REGNUM)
-	       || (GET_CODE (gp) == CONST
-		   && GET_CODE (u = XEXP (gp, 0)) == UNSPEC
-		   && XINT (u, 1) == ARC_UNSPEC_GOT
-		   && GET_CODE (XVECEXP (u, 0, 0)) == SYMBOL_REF
-		   && !strcmp (XSTR (XVECEXP (u, 0, 0), 0), "_DYNAMIC")))
-	   && GET_CODE (XEXP (x, 1)) == CONST
-	   && GET_CODE (u = XEXP (XEXP (x, 1), 0)) == UNSPEC
-	   && XINT (u, 1) == ARC_UNSPEC_GOTOFF)
-    return XVECEXP (u, 0, 0);
-  else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
-	   && ((REG_P (gp = XEXP (XEXP (x, 0), 1))
-		&& REGNO (gp) == PIC_OFFSET_TABLE_REGNUM)
-	       || (GET_CODE (gp) == CONST
-		   && GET_CODE (u = XEXP (gp, 0)) == UNSPEC
-		   && XINT (u, 1) == ARC_UNSPEC_GOT
-		   && GET_CODE (XVECEXP (u, 0, 0)) == SYMBOL_REF
-		   && !strcmp (XSTR (XVECEXP (u, 0, 0), 0), "_DYNAMIC")))
-	   && GET_CODE (XEXP (x, 1)) == CONST
-	   && GET_CODE (u = XEXP (XEXP (x, 1), 0)) == UNSPEC
-	   && XINT (u, 1) == ARC_UNSPEC_GOTOFF)
-    return gen_rtx_PLUS (GET_MODE (x), XEXP (XEXP (x, 0), 0),
-			 XVECEXP (u, 0, 0));
-  else if (GET_CODE (x) == PLUS
-	   && (u = arc_delegitimize_address_0 (XEXP (x, 1))))
-    return gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0), u);
   return NULL_RTX;
 }
 
 static rtx
-arc_delegitimize_address (rtx x)
+arc_delegitimize_address (rtx orig_x)
 {
-  rtx orig_x = x = delegitimize_mem_from_attrs (x);
-  if (GET_CODE (x) == MEM)
+  rtx x = orig_x;
+
+  if (MEM_P (x))
     x = XEXP (x, 0);
+
   x = arc_delegitimize_address_0 (x);
-  if (x)
-    {
-      if (MEM_P (orig_x))
-	x = replace_equiv_address_nv (orig_x, x);
-      return x;
-    }
-  return orig_x;
+  if (!x)
+    return orig_x;
+
+  if (MEM_P (orig_x))
+    x = replace_equiv_address_nv (orig_x, x);
+  return x;
 }
 
 /* Return a REG rtx for acc1.  N.B. the gcc-internal representation may
diff --git a/gcc/testsuite/gcc.target/arc/tdelegitimize_addr.c b/gcc/testsuite/gcc.target/arc/tdelegitimize_addr.c
new file mode 100755
index 0000000..0d010ff
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/tdelegitimize_addr.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
+/* { dg-options "-mcpu=archs -g -O1 -fpic -mlra" } */
+
+/* Check if delegitimize address returns correctly the un-obfuscated
+   address.  */
+
+typedef struct {
+  long long tv_usec;
+} t_a;
+
+static t_a a;
+
+int b;
+extern void fn2 (t_a);
+
+void fn1 (void)
+{
+ again:
+  fn2(a);
+  if (b)
+    goto again;
+}
-- 
1.9.1

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

* [PATCH 1/6] [ARC] Add JLI support.
  2017-11-02 12:34 [PATCH 0/6] [ARC] New baremetal features and fixes Claudiu Zissulescu
@ 2017-11-02 12:34 ` Claudiu Zissulescu
  2018-01-16 10:20   ` Andrew Burgess
  2017-11-02 12:34 ` [PATCH 4/6] [ARC] Rework delegitimate_address hook Claudiu Zissulescu
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 18+ messages in thread
From: Claudiu Zissulescu @ 2017-11-02 12:34 UTC (permalink / raw)
  To: gcc-patches; +Cc: Claudiu.Zissulescu, Francois.Bedard, andrew.burgess

The ARCv2 ISA provides the JLI instruction, which is two-byte instructions
that can be used to reduce code size in an application. To make use of it,
we provide two new function attributes 'jli_always' and 'jli_fixed' which
will force the compiler to call the indicated function using a jli_s
instruction. The compiler also generates the entries in the JLI table for
the case when we use 'jli_always' attribute. In the case of 'jli_fixed'
the compiler assumes a fixed position of the function into JLI
table. Thus, the user needs to provide an assembly file with the JLI table
for the final link. This is usefully when we want to have a table in ROM
and a second table in the RAM memory.

The jli instruction usage can be also forced without the need to annotate
the source code via '-mjli-always' command.

gcc/
2017-02-10  Claudiu Zissulescu  <claziss@synopsys.com>
	    John Eric Martin <John.Martin@emmicro-us.com>

	* config/arc/arc-protos.h: Add arc_is_jli_call_p proto.
	* config/arc/arc.c (_arc_jli_section): New struct.
	(arc_jli_section): New type.
	(rc_jli_sections): New static variable.
	(arc_handle_jli_attribute): New function.
	(arc_attribute_table): Add jli_always and jli_fixed attribute.
	(arc_file_end): New function.
	(TARGET_ASM_FILE_END): Define.
	(arc_print_operand): Reuse 'S' letter for JLI output instruction.
	(arc_add_jli_section): New function.
	(jli_call_scan): Likewise.
	(arc_reorg): Call jli_call_scan.
	(arc_output_addsi): Remove 'S' from printing asm operand.
	(arc_is_jli_call_p): New function.
	* config/arc/arc.md (movqi_insn): Remove 'S' from printing asm
	operand.
	(movhi_insn): Likewise.
	(movsi_insn): Likewise.
	(movsi_set_cc_insn): Likewise.
	(loadqi_update): Likewise.
	(load_zeroextendqisi_update): Likewise.
	(load_signextendqisi_update): Likewise.
	(loadhi_update): Likewise.
	(load_zeroextendhisi_update): Likewise.
	(load_signextendhisi_update): Likewise.
	(loadsi_update): Likewise.
	(loadsf_update): Likewise.
	(movsicc_insn): Likewise.
	(bset_insn): Likewise.
	(bxor_insn): Likewise.
	(bclr_insn): Likewise.
	(bmsk_insn): Likewise.
	(bicsi3_insn): Likewise.
	(cmpsi_cc_c_insn): Likewise.
	(movsi_ne): Likewise.
	(movsi_cond_exec): Likewise.
	(clrsbsi2): Likewise.
	(norm_f): Likewise.
	(normw): Likewise.
	(swap): Likewise.
	(divaw): Likewise.
	(flag): Likewise.
	(sr): Likewise.
	(kflag): Likewise.
	(ffs): Likewise.
	(ffs_f): Likewise.
	(fls): Likewise.
	(call_i): Remove 'S' asm letter, add jli instruction.
	(call_value_i): Likewise.
	* config/arc/arc.op (mjli-always): New option.
	* config/arc/constraints.md (Cji): New constraint.
	* config/arc/fpx.md (addsf3_fpx): Remove 'S' from printing asm
	operand.
	(subsf3_fpx): Likewise.
	(mulsf3_fpx): Likewise.
	* config/arc/simdext.md (vendrec_insn): Remove 'S' from printing
	asm operand.
	* doc/extend.texi (ARC): Document 'jli-always' and 'jli-fixed'
	function attrbutes.
	* doc/invoke.texi (ARC): Document mjli-always option.

gcc/testsuite
2017-02-10  Claudiu Zissulescu  <claziss@synopsys.com>

	* gcc.target/arc/jli-1.c: New file.
	* gcc.target/arc/jli-2.c: Likewise.
---
 gcc/config/arc/arc-protos.h          |   2 +
 gcc/config/arc/arc.c                 | 220 ++++++++++++++++++++++++++++++++++-
 gcc/config/arc/arc.md                | 128 ++++++++++----------
 gcc/config/arc/arc.opt               |   4 +
 gcc/config/arc/constraints.md        |   6 +
 gcc/config/arc/elf.h                 |   3 +
 gcc/config/arc/fpx.md                |  18 +--
 gcc/config/arc/linux.h               |   1 +
 gcc/config/arc/simdext.md            |   2 +-
 gcc/doc/extend.texi                  |  10 ++
 gcc/doc/invoke.texi                  |   7 +-
 gcc/testsuite/gcc.target/arc/jli-1.c |  19 +++
 gcc/testsuite/gcc.target/arc/jli-2.c |  19 +++
 13 files changed, 358 insertions(+), 81 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arc/jli-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/jli-2.c

diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h
index 6e7239f..1557293 100644
--- a/gcc/config/arc/arc-protos.h
+++ b/gcc/config/arc/arc-protos.h
@@ -116,3 +116,5 @@ extern void arc_secondary_reload_conv (rtx, rtx, rtx, bool);
 extern void arc_cpu_cpp_builtins (cpp_reader *);
 extern bool arc_store_addr_hazard_p (rtx_insn *, rtx_insn *);
 extern rtx arc_eh_return_address_location (void);
+extern bool arc_is_jli_call_p (rtx);
+extern void arc_file_end (void);
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index e35d198..489cb91 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -71,6 +71,14 @@ along with GCC; see the file COPYING3.  If not see
 static char arc_cpu_name[10] = "";
 static const char *arc_cpu_string = arc_cpu_name;
 
+typedef struct GTY (()) _arc_jli_section
+{
+  const char *name;
+  struct _arc_jli_section *next;
+} arc_jli_section;
+
+static arc_jli_section *arc_jli_sections = NULL;
+
 /* Maximum size of a loop.  */
 #define ARC_MAX_LOOP_LENGTH 4095
 
@@ -212,6 +220,8 @@ static int get_arc_condition_code (rtx);
 
 static tree arc_handle_interrupt_attribute (tree *, tree, tree, int, bool *);
 static tree arc_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
+static tree arc_handle_jli_attribute (tree *, tree, tree, int, bool *);
+
 
 /* Initialized arc_attribute_table to NULL since arc doesnot have any
    machine specific supported attributes.  */
@@ -233,6 +243,13 @@ const struct attribute_spec arc_attribute_table[] =
   /* Function which are not having the prologue and epilogue generated
      by the compiler.  */
   { "naked", 0, 0, true, false, false, arc_handle_fndecl_attribute, false },
+  /* Functions calls made using jli instruction.  The pointer in JLI
+     table is found latter.  */
+  { "jli_always",    0, 0, false, true,  true,  NULL, false },
+  /* Functions calls made using jli instruction.  The pointer in JLI
+     table is given as input parameter.  */
+  { "jli_fixed",    1, 1, false, true,  true,  arc_handle_jli_attribute,
+    false },
   { NULL, 0, 0, false, false, false, NULL, false }
 };
 static int arc_comp_type_attributes (const_tree, const_tree);
@@ -3696,7 +3713,7 @@ static int output_scaled = 0;
     'd'
     'D'
     'R': Second word
-    'S'
+    'S': JLI instruction
     'B': Branch comparison operand - suppress sda reference
     'H': Most significant word
     'L': Least significant word
@@ -3912,8 +3929,27 @@ arc_print_operand (FILE *file, rtx x, int code)
 	output_operand_lossage ("invalid operand to %%R code");
       return;
     case 'S' :
-	/* FIXME: remove %S option.  */
-	break;
+      if (GET_CODE (x) == SYMBOL_REF
+	  && arc_is_jli_call_p (x))
+	{
+	  if (SYMBOL_REF_DECL (x))
+	    {
+	      tree attrs = (TREE_TYPE (SYMBOL_REF_DECL (x)) != error_mark_node
+			    ? TYPE_ATTRIBUTES (TREE_TYPE (SYMBOL_REF_DECL (x)))
+			    : NULL_TREE);
+	      if (lookup_attribute ("jli_fixed", attrs))
+		{
+		  fprintf (file, "%ld\t; @",
+			   TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs))));
+		  assemble_name (file, XSTR (x, 0));
+		  return;
+		}
+	    }
+	  fprintf (file, "@__jli.");
+	  assemble_name (file, XSTR (x, 0));
+	  return;
+	}
+      break;
     case 'B' /* Branch or other LIMM ref - must not use sda references.  */ :
       if (CONSTANT_P (x))
 	{
@@ -5026,6 +5062,36 @@ static void arc_file_start (void)
   fprintf (asm_out_file, "\t.cpu %s\n", arc_cpu_string);
 }
 
+/* Implement `TARGET_ASM_FILE_END'.  */
+/* Outputs to the stdio stream FILE jli related text.  */
+
+void arc_file_end (void)
+{
+  arc_jli_section *sec = arc_jli_sections;
+
+  while (sec != NULL)
+  {
+    fprintf (asm_out_file, "\n");
+    fprintf (asm_out_file, "# JLI entry for function ");
+    assemble_name (asm_out_file, sec->name);
+    fprintf (asm_out_file, "\n\t.section .jlitab, \"axG\", @progbits, "
+	     ".jlitab.");
+    assemble_name (asm_out_file, sec->name);
+    fprintf (asm_out_file,", comdat\n");
+
+    fprintf (asm_out_file, "\t.align\t4\n");
+    fprintf (asm_out_file, "__jli.");
+    assemble_name (asm_out_file, sec->name);
+    fprintf (asm_out_file, ":\n\t.weak __jli.");
+    assemble_name (asm_out_file, sec->name);
+    fprintf (asm_out_file, "\n\tb\t@");
+    assemble_name (asm_out_file, sec->name);
+    fprintf (asm_out_file, "\n");
+    sec = sec->next;
+  }
+  file_end_indicate_exec_stack ();
+}
+
 /* Cost functions.  */
 
 /* Compute a (partial) cost for rtx X.  Return true if the complete
@@ -6814,13 +6880,25 @@ check_if_valid_sleep_operand (rtx *operands, int opno)
 /* Return true if it is ok to make a tail-call to DECL.  */
 
 static bool
-arc_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
+arc_function_ok_for_sibcall (tree decl,
 			     tree exp ATTRIBUTE_UNUSED)
 {
+  tree attrs = NULL_TREE;
+
   /* Never tailcall from an ISR routine - it needs a special exit sequence.  */
   if (ARC_INTERRUPT_P (arc_compute_function_type (cfun)))
     return false;
 
+  if (decl)
+    {
+      attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
+
+      if (lookup_attribute ("jli_always", attrs))
+	return false;
+      if (lookup_attribute ("jli_fixed", attrs))
+	return false;
+    }
+
   /* Everything else is ok.  */
   return true;
 }
@@ -7516,6 +7594,73 @@ arc_reorg_loops (void)
   reorg_loops (true, &arc_doloop_hooks);
 }
 
+/* Add the given function declaration to emit code in JLI section.  */
+
+static void
+arc_add_jli_section (rtx pat)
+{
+  const char *name;
+  tree attrs;
+  arc_jli_section *sec = arc_jli_sections, *new_section;
+  tree decl = SYMBOL_REF_DECL (pat);
+
+  if (!pat)
+    return;
+
+  if (decl)
+    {
+      /* For fixed locations do not generate the jli table entry.  It
+	 should be provided by the user as an asm file.  */
+      attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
+      if (lookup_attribute ("jli_fixed", attrs))
+	return;
+    }
+
+  name = XSTR (pat, 0);
+
+  /* Don't insert the same symbol twice.  */
+  while (sec != NULL)
+    {
+      if(strcmp (name, sec->name) == 0)
+	return;
+      sec = sec->next;
+    }
+
+  /* New name, insert it.  */
+  new_section = (arc_jli_section *) xmalloc (sizeof (arc_jli_section));
+  gcc_assert (new_section != NULL);
+  new_section->name = name;
+  new_section->next = arc_jli_sections;
+  arc_jli_sections = new_section;
+}
+
+/* Scan all calls and add symbols to be emitted in the jli section if
+   needed.  */
+
+static void
+jli_call_scan (void)
+{
+  rtx_insn *insn;
+
+  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+    {
+      if (!CALL_P (insn))
+	continue;
+
+      rtx pat = PATTERN (insn);
+      if (GET_CODE (pat) == COND_EXEC)
+	pat = COND_EXEC_CODE (pat);
+      pat =  XVECEXP (pat, 0, 0);
+      if (GET_CODE (pat) == SET)
+	pat = SET_SRC (pat);
+
+      pat = XEXP (XEXP (pat, 0), 0);
+      if (GET_CODE (pat) == SYMBOL_REF
+	  && arc_is_jli_call_p (pat))
+	arc_add_jli_section (pat);
+    }
+}
+
 static int arc_reorg_in_progress = 0;
 
 /* ARC's machince specific reorg function.  */
@@ -7540,6 +7685,7 @@ arc_reorg (void)
   arc_reorg_loops ();
 
   workaround_arc_anomaly ();
+  jli_call_scan ();
 
 /* FIXME: should anticipate ccfsm action, generate special patterns for
    to-be-deleted branches that have no delay slot and have at least the
@@ -8218,11 +8364,11 @@ arc_output_addsi (rtx *operands, bool cond_p, bool output_p)
   /* Try to emit a 16 bit opcode with long immediate.  */
   ret = 6;
   if (short_p && match)
-    ADDSI_OUTPUT1 ("add%? %0,%1,%S2");
+    ADDSI_OUTPUT1 ("add%? %0,%1,%2");
 
   /* We have to use a 32 bit opcode, and with a long immediate.  */
   ret = 8;
-  ADDSI_OUTPUT1 (intval < 0 ? "sub%? %0,%1,%n2" : "add%? %0,%1,%S2");
+  ADDSI_OUTPUT1 (intval < 0 ? "sub%? %0,%1,%n2" : "add%? %0,%1,%2");
 }
 
 /* Emit code for an commutative_cond_exec instruction with OPERANDS.
@@ -10760,6 +10906,68 @@ arc_builtin_setjmp_frame_value (void)
   return gen_raw_REG (Pmode, FRAME_POINTER_REGNUM);
 }
 
+/* Return nonzero if a jli call should be generated for a call from
+   the current function to DECL.  */
+
+bool
+arc_is_jli_call_p (rtx pat)
+{
+  tree attrs;
+  tree decl = SYMBOL_REF_DECL (pat);
+
+  /* If it is not a well defined public function then return false.  */
+  if (!decl || !SYMBOL_REF_FUNCTION_P (pat) || !TREE_PUBLIC (decl))
+    return false;
+
+  attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
+  if (lookup_attribute ("jli_always", attrs))
+    return true;
+
+  if (lookup_attribute ("jli_fixed", attrs))
+    return true;
+
+  return TARGET_JLI_ALWAYS;
+}
+
+/* Handle and "jli" attribute; arguments as in struct
+   attribute_spec.handler.  */
+
+static tree
+arc_handle_jli_attribute (tree *node ATTRIBUTE_UNUSED,
+			  tree name, tree args, int,
+			  bool *no_add_attrs)
+{
+  if (!TARGET_V2)
+    {
+      warning (OPT_Wattributes,
+	       "%qE attribute only valid for ARCv2 architecture",
+	       name);
+      *no_add_attrs = true;
+    }
+
+  if (args == NULL_TREE)
+    {
+      warning (OPT_Wattributes,
+	       "argument of %qE attribute is missing",
+	       name);
+      *no_add_attrs = true;
+    }
+  else
+    {
+      if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
+	TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
+      tree arg = TREE_VALUE (args);
+      if (TREE_CODE (arg) != INTEGER_CST)
+	{
+	  warning (0, "%qE attribute allows only an integer constant argument",
+		   name);
+	  *no_add_attrs = true;
+	}
+      /* FIXME! add range check.  TREE_INT_CST_LOW (arg) */
+    }
+   return NULL_TREE;
+}
+
 /* Implement TARGET_USE_ANCHORS_FOR_SYMBOL_P.  We don't want to use
    anchors for small data: the GP register acts as an anchor in that
    case.  We also don't want to use them for PC-relative accesses,
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index 43a962f..c72420c 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -637,7 +637,7 @@
    mov%? %0,%1
    mov%? %0,%1
    mov%? %0,%1
-   mov%? %0,%S1
+   mov%? %0,%1
    ldb%? %0,%1%&
    stb%? %1,%0%&
    ldb%? %0,%1%&
@@ -678,9 +678,9 @@
    mov%? %0,%1
    mov%? %0,%1
    mov%? %0,%1
-   mov%? %0,%S1%&
-   mov%? %0,%S1
-   mov%? %0,%S1
+   mov%? %0,%1%&
+   mov%? %0,%1
+   mov%? %0,%1
    ld%_%? %0,%1%&
    st%_%? %1,%0%&
    xld%_%U1 %0,%1
@@ -688,8 +688,8 @@
    xst%_%U0 %1,%0
    st%_%U0%V0 %1,%0
    st%_%U0%V0 %1,%0
-   st%_%U0%V0 %S1,%0
-   st%_%U0%V0 %S1,%0"
+   st%_%U0%V0 %1,%0
+   st%_%U0%V0 %1,%0"
   [(set_attr "type" "move,move,move,move,move,move,move,move,move,move,move,load,store,load,load,store,store,store,store,store")
    (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false,false,maybe_limm,maybe_limm,false,true,true,false,false,false,false,false,false,false")
    (set_attr "predicable" "yes,no,yes,no,no,yes,no,yes,yes,yes,yes,no,no,no,no,no,no,no,no,no")
@@ -734,7 +734,7 @@
    movh.cl %0,%L1>>16   ;9
    * return INTVAL (operands[1]) & 0xffffff ? \"movbi.cl %0,%1 >> %p1,%p1,8;10\" : \"movbi.cl %0,%L1 >> 24,24,8;10\";
    mov%? %0,%1		;11
-   add %0,%S1		;12
+   add %0,%1		;12
    add %0,pcl,%1@pcl    ;13
    mov%? %0,%1  	;14
    mov%? %0,%1		;15
@@ -795,7 +795,7 @@
    (set (match_operand:SI 0 "register_operand" "=w,w,w")
 	(match_dup 1))]
   ""
-  "mov%?.f %0,%S1"
+  "mov%?.f %0,%1"
   ; splitting to 'tst' allows short insns and combination into brcc.
   "reload_completed && operands_match_p (operands[0], operands[1])"
   [(set (match_dup 2) (match_dup 3))]
@@ -1283,7 +1283,7 @@
    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
-  "ldb.a%V4 %3,[%0,%S2]"
+  "ldb.a%V4 %3,[%0,%2]"
   [(set_attr "type" "load,load")
    (set_attr "length" "4,8")])
 
@@ -1295,7 +1295,7 @@
    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
-  "ldb.a%V4 %3,[%0,%S2]"
+  "ldb.a%V4 %3,[%0,%2]"
   [(set_attr "type" "load,load")
    (set_attr "length" "4,8")])
 
@@ -1307,7 +1307,7 @@
    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
-  "ldb.x.a%V4 %3,[%0,%S2]"
+  "ldb.x.a%V4 %3,[%0,%2]"
   [(set_attr "type" "load,load")
    (set_attr "length" "4,8")])
 
@@ -1333,7 +1333,7 @@
    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
-  "ld%_.a%V4 %3,[%0,%S2]"
+  "ld%_.a%V4 %3,[%0,%2]"
   [(set_attr "type" "load,load")
    (set_attr "length" "4,8")])
 
@@ -1345,7 +1345,7 @@
    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
-  "ld%_.a%V4 %3,[%0,%S2]"
+  "ld%_.a%V4 %3,[%0,%2]"
   [(set_attr "type" "load,load")
    (set_attr "length" "4,8")])
 
@@ -1358,7 +1358,7 @@
    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
-  "ld%_.x.a%V4 %3,[%0,%S2]"
+  "ld%_.x.a%V4 %3,[%0,%2]"
   [(set_attr "type" "load,load")
    (set_attr "length" "4,8")])
 
@@ -1383,7 +1383,7 @@
    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
-  "ld.a%V4 %3,[%0,%S2]"
+  "ld.a%V4 %3,[%0,%2]"
   [(set_attr "type" "load,load")
    (set_attr "length" "4,8")])
 
@@ -1407,7 +1407,7 @@
    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
-  "ld.a%V4 %3,[%0,%S2]"
+  "ld.a%V4 %3,[%0,%2]"
   [(set_attr "type" "load,load")
    (set_attr "length" "4,8")])
 
@@ -1475,7 +1475,7 @@
       && rtx_equal_p (operands[1], constm1_rtx)
       && GET_CODE (operands[3]) == LTU)
     return "sbc.cs %0,%0,%0";
-  return "mov.%d3 %0,%S1";
+  return "mov.%d3 %0,%1";
 }
   [(set_attr "type" "cmove,cmove")
    (set_attr "length" "4,8")])
@@ -3140,7 +3140,7 @@
   "@
      bset%? %0,%1,%2 ;;peep2, constr 1
      bset %0,%1,%2 ;;peep2, constr 2
-     bset %0,%S1,%2 ;;peep2, constr 3"
+     bset %0,%1,%2 ;;peep2, constr 3"
   [(set_attr "length" "4,4,8")
    (set_attr "predicable" "yes,no,no")
    (set_attr "cond" "canuse,nocond,nocond")]
@@ -3156,7 +3156,7 @@
   "@
      bxor%? %0,%1,%2
      bxor %0,%1,%2
-     bxor %0,%S1,%2"
+     bxor %0,%1,%2"
   [(set_attr "length" "4,4,8")
    (set_attr "predicable" "yes,no,no")
    (set_attr "cond" "canuse,nocond,nocond")]
@@ -3172,7 +3172,7 @@
   "@
      bclr%? %0,%1,%2
      bclr %0,%1,%2
-     bclr %0,%S1,%2"
+     bclr %0,%1,%2"
   [(set_attr "length" "4,4,8")
    (set_attr "predicable" "yes,no,no")
    (set_attr "cond" "canuse,nocond,nocond")]
@@ -3188,9 +3188,9 @@
 			 (const_int -1))))]
   ""
   "@
-     bmsk%? %0,%S1,%2
+     bmsk%? %0,%1,%2
      bmsk %0,%1,%2
-     bmsk %0,%S1,%2"
+     bmsk %0,%1,%2"
   [(set_attr "length" "4,4,8")
    (set_attr "predicable" "yes,no,no")
    (set_attr "cond" "canuse,nocond,nocond")]
@@ -3302,10 +3302,10 @@
    bic%? %0, %2, %1%& ;;constraint 0
    bic%? %0,%2,%1  ;;constraint 1
    bic %0,%2,%1    ;;constraint 2, FIXME: will it ever get generated ???
-   bic%? %0,%2,%S1 ;;constraint 3, FIXME: will it ever get generated ???
+   bic%? %0,%2,%1  ;;constraint 3, FIXME: will it ever get generated ???
    bic %0,%2,%1    ;;constraint 4
-   bic %0,%2,%S1   ;;constraint 5, FIXME: will it ever get generated ???
-   bic %0,%S2,%1   ;;constraint 6"
+   bic %0,%2,%1    ;;constraint 5, FIXME: will it ever get generated ???
+   bic %0,%2,%1    ;;constraint 6"
   [(set_attr "length" "*,4,4,8,4,8,8")
   (set_attr "iscompact" "maybe, false, false, false, false, false, false")
   (set_attr "predicable" "no,yes,no,yes,no,no,no")
@@ -3636,7 +3636,7 @@
 	(compare:CC_C (match_operand:SI 0 "register_operand"  "Rcqq,Rcqq,  h, c,Rcqq,  c")
 		      (match_operand:SI 1 "nonmemory_operand"   "cO,  hO,Cm1,cI, Cal,Cal")))]
   ""
-  "cmp%? %0,%S1%&"
+  "cmp%? %0,%1%&"
   [(set_attr "type" "compare")
    (set_attr "iscompact" "true,true,true,false,true_limm,false")
    (set_attr "cond" "set")
@@ -3743,7 +3743,7 @@
 	* current_insn_predicate = 0; return \"mov%?.ne %0,%1\";
 	* current_insn_predicate = 0; return \"mov%?.ne %0,%1\";
 	mov.ne %0,%1
-	mov.ne %0,%S1"
+	mov.ne %0,%1"
   [(set_attr "type" "cmove")
    (set_attr "iscompact" "true,true,true_limm,false,false")
    (set_attr "length" "2,2,6,4,8")
@@ -3756,7 +3756,7 @@
      (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
 	  (match_operand:SI 1 "nonmemory_operand" "LRac,?Cal")))]
   ""
-  "mov.%d3 %0,%S1"
+  "mov.%d3 %0,%1"
   [(set_attr "type" "cmove")
    (set_attr "length" "4,8")])
 
@@ -4224,13 +4224,12 @@
   }
 ")
 
-
 ; Rcq, which is used in alternative 0, checks for conditional execution.
 ; At instruction output time, if it doesn't match and we end up with
 ; alternative 1 ("q"), that means that we can't use the short form.
 (define_insn "*call_i"
   [(call (mem:SI (match_operand:SI 0
-		  "call_address_operand" "Rcq,q,c,Cbp,Cbr,L,I,Cal"))
+		  "call_address_operand" "Rcq,q,c,Cji,Cbp,Cbr,L,I,Cal"))
 	 (match_operand 1 "" ""))
    (clobber (reg:SI 31))]
   ""
@@ -4238,15 +4237,16 @@
    jl%!%* [%0]%&
    jl%!%* [%0]%&
    jl%!%* [%0]
+   jli_s %S0
    bl%!%* %P0
    bl%!%* %P0
-   jl%!%* %S0
-   jl%* %S0
-   jl%! %S0"
-  [(set_attr "type" "call,call,call,call,call,call,call,call_no_delay_slot")
-   (set_attr "iscompact" "maybe,false,*,*,*,*,*,*")
-   (set_attr "predicable" "no,no,yes,yes,no,yes,no,yes")
-   (set_attr "length" "*,*,4,4,4,4,4,8")])
+   jl%!%* %0
+   jl%* %0
+   jl%! %0"
+  [(set_attr "type" "call,call,call,call_no_delay_slot,call,call,call,call,call_no_delay_slot")
+   (set_attr "iscompact" "maybe,false,*,true,*,*,*,*,*")
+   (set_attr "predicable" "no,no,yes,no,yes,no,yes,no,yes")
+   (set_attr "length" "*,*,4,2,4,4,4,4,8")])
 
 (define_expand "call_value"
   ;; operand 2 is stack_size_rtx
@@ -4268,14 +4268,13 @@
       XEXP (operands[1], 0) = force_reg (Pmode, callee);
   }")
 
-
 ; Rcq, which is used in alternative 0, checks for conditional execution.
 ; At instruction output time, if it doesn't match and we end up with
 ; alternative 1 ("q"), that means that we can't use the short form.
 (define_insn "*call_value_i"
-  [(set (match_operand 0 "dest_reg_operand"  "=Rcq,q,w,  w,  w,w,w,  w")
+  [(set (match_operand 0 "dest_reg_operand"  "=Rcq,q,w,  w,  w,  w,w,w,  w")
 	(call (mem:SI (match_operand:SI 1
-		       "call_address_operand" "Rcq,q,c,Cbp,Cbr,L,I,Cal"))
+		       "call_address_operand" "Rcq,q,c,Cji,Cbp,Cbr,L,I,Cal"))
 	      (match_operand 2 "" "")))
    (clobber (reg:SI 31))]
   ""
@@ -4283,15 +4282,16 @@
    jl%!%* [%1]%&
    jl%!%* [%1]%&
    jl%!%* [%1]
+   jli_s %S1
    bl%!%* %P1;1
    bl%!%* %P1;1
-   jl%!%* %S1
-   jl%* %S1
-   jl%! %S1"
-  [(set_attr "type" "call,call,call,call,call,call,call,call_no_delay_slot")
-   (set_attr "iscompact" "maybe,false,*,*,*,*,*,*")
-   (set_attr "predicable" "no,no,yes,yes,no,yes,no,yes")
-   (set_attr "length" "*,*,4,4,4,4,4,8")])
+   jl%!%* %1
+   jl%* %1
+   jl%! %1"
+  [(set_attr "type" "call,call,call,call_no_delay_slot,call,call,call,call,call_no_delay_slot")
+   (set_attr "iscompact" "maybe,false,*,true,*,*,*,*,*")
+   (set_attr "predicable" "no,no,yes,no,yes,no,yes,no,yes")
+   (set_attr "length" "*,*,4,2,4,4,4,4,8")])
 
 ; There is a bl_s instruction (16 bit opcode branch-and-link), but we can't
 ; use it for lack of inter-procedural branch shortening.
@@ -4465,7 +4465,7 @@
   "TARGET_NORM"
   "@
    norm \t%0, %1
-   norm \t%0, %S1"
+   norm \t%0, %1"
   [(set_attr "length" "4,8")
    (set_attr "type" "two_cycle_core,two_cycle_core")])
 
@@ -4477,7 +4477,7 @@
   "TARGET_NORM"
   "@
    norm.f\t%0, %1
-   norm.f\t%0, %S1"
+   norm.f\t%0, %1"
   [(set_attr "length" "4,8")
    (set_attr "type" "two_cycle_core,two_cycle_core")])
 
@@ -4497,7 +4497,7 @@
   "TARGET_NORM"
   "@
    norm%_ \t%0, %1
-   norm%_ \t%0, %S1"
+   norm%_ \t%0, %1"
   [(set_attr "length" "4,8")
    (set_attr "type" "two_cycle_core,two_cycle_core")])
 
@@ -4586,7 +4586,7 @@
   "TARGET_SWAP"
   "@
    swap \t%0, %1
-   swap \t%0, %S1
+   swap \t%0, %1
    swap \t%0, %1"
   [(set_attr "length" "4,8,4")
    (set_attr "type" "two_cycle_core,two_cycle_core,two_cycle_core")])
@@ -4599,8 +4599,8 @@
   "TARGET_ARC700 || TARGET_EA_SET"
   "@
    divaw \t%0, %1, %2
-   divaw \t%0, %S1, %2
-   divaw \t%0, %1, %S2"
+   divaw \t%0, %1, %2
+   divaw \t%0, %1, %2"
   [(set_attr "length" "4,8,8")
    (set_attr "type" "divaw,divaw,divaw")])
 
@@ -4611,7 +4611,7 @@
   "@
     flag%? %0
     flag %0
-    flag%? %S0"
+    flag%? %0"
   [(set_attr "length" "4,4,8")
    (set_attr "type" "misc,misc,misc")
    (set_attr "predicable" "yes,no,yes")
@@ -4705,7 +4705,7 @@
 		     (match_operand:SI 1 "general_operand" "Ir,I,HCal,r")]
 		   VUNSPEC_ARC_SR)]
   ""
-  "sr\t%S0, [%1]"
+  "sr\t%0, [%1]"
   [(set_attr "length" "8,4,8,4")
    (set_attr "type" "sr,sr,sr,sr")])
 
@@ -5281,7 +5281,7 @@
 ;; ??? Should this use arc_output_libcall and set is_sfunc?
 (define_insn "*millicode_thunk_st"
   [(match_parallel 0 "millicode_store_operation"
-     [(set (mem:SI (reg:SI SP_REG)) (reg:SI 13))])]
+		   [(set (mem:SI (reg:SI SP_REG)) (reg:SI 13))])]
   ""
 {
   output_asm_insn ("bl%* __st_r13_to_%0",
@@ -5293,7 +5293,7 @@
 
 (define_insn "*millicode_thunk_ld"
   [(match_parallel 0 "millicode_load_clob_operation"
-     [(set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
+		   [(set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
   ""
 {
   output_asm_insn ("bl%* __ld_r13_to_%0",
@@ -5306,9 +5306,9 @@
 ; the sibthunk restores blink, so we use the return rtx.
 (define_insn "*millicode_sibthunk_ld"
   [(match_parallel 0 "millicode_load_operation"
-     [(return)
-      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (reg:SI 12)))
-      (set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
+		   [(return)
+		    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (reg:SI 12)))
+		    (set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
   ""
 {
   output_asm_insn ("b%* __ld_r13_to_%0_ret",
@@ -5627,7 +5627,7 @@
   "@
     kflag%? %0
     kflag %0
-    kflag%? %S0"
+    kflag%? %0"
   [(set_attr "length" "4,4,8")
    (set_attr "type" "misc,misc,misc")
    (set_attr "predicable" "yes,no,yes")
@@ -5649,7 +5649,7 @@
   "TARGET_NORM && TARGET_V2"
   "@
    ffs \t%0, %1
-   ffs \t%0, %S1"
+   ffs \t%0, %1"
   [(set_attr "length" "4,8")
    (set_attr "type" "two_cycle_core,two_cycle_core")])
 
@@ -5662,7 +5662,7 @@
   "TARGET_NORM && TARGET_V2"
   "@
    ffs.f\t%0, %1
-   ffs.f\t%0, %S1"
+   ffs.f\t%0, %1"
   [(set_attr "length" "4,8")
    (set_attr "type" "two_cycle_core,two_cycle_core")])
 
@@ -5689,7 +5689,7 @@
   "TARGET_NORM && TARGET_V2"
   "@
    fls \t%0, %1
-   fls \t%0, %S1"
+   fls \t%0, %1"
   [(set_attr "length" "4,8")
    (set_attr "type" "two_cycle_core,two_cycle_core")])
 
diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt
index d1ebd44..9baaf77 100644
--- a/gcc/config/arc/arc.opt
+++ b/gcc/config/arc/arc.opt
@@ -53,6 +53,10 @@ mARC700
 Target Report
 Same as -mA7.
 
+mjli-always
+Target Report Mask(JLI_ALWAYS)
+Force all calls to be made via a jli instruction.
+
 mmpy-option=
 Target RejectNegative Joined Enum(arc_mpy) Var(arc_mpy_option) Init(DEFAULT_arc_mpy_option)
 -mmpy-option=MPY Compile ARCv2 code with a multiplier design option.
diff --git a/gcc/config/arc/constraints.md b/gcc/config/arc/constraints.md
index b8a4a90..7114e6e 100644
--- a/gcc/config/arc/constraints.md
+++ b/gcc/config/arc/constraints.md
@@ -401,6 +401,12 @@
 	    (match_test "arc_is_shortcall_p (op)"))
        (match_code "label_ref")))
 
+(define_constraint "Cji"
+  "JLI call"
+  (and (match_code "symbol_ref")
+       (match_test "TARGET_CODE_DENSITY")
+       (match_test "arc_is_jli_call_p (op)")))
+
 (define_constraint "Cpc"
   "pc-relative constant"
   (match_test "arc_legitimate_pic_addr_p (op)"))
diff --git a/gcc/config/arc/elf.h b/gcc/config/arc/elf.h
index 43f3408..175e9fd 100644
--- a/gcc/config/arc/elf.h
+++ b/gcc/config/arc/elf.h
@@ -66,3 +66,6 @@ along with GCC; see the file COPYING3.  If not see
 /* Pre/post modify with register displacement are default.  */
 #undef TARGET_AUTO_MODIFY_REG_DEFAULT
 #define TARGET_AUTO_MODIFY_REG_DEFAULT 1
+
+#undef TARGET_ASM_FILE_END
+#define TARGET_ASM_FILE_END arc_file_end
diff --git a/gcc/config/arc/fpx.md b/gcc/config/arc/fpx.md
index 990b3a8..2daab44 100644
--- a/gcc/config/arc/fpx.md
+++ b/gcc/config/arc/fpx.md
@@ -59,9 +59,9 @@
   "@
    fadd %0,%1,%2
    fadd %0,%1,%2
-   fadd   %0,%S1,%2
-   fadd   %0,%1,%S2
-   fadd%? %0,%1,%S2"
+   fadd   %0,%1,%2
+   fadd   %0,%1,%2
+   fadd%? %0,%1,%2"
   [(set_attr "type" "spfp")
   (set_attr "length" "4,4,8,8,8")])
 
@@ -74,9 +74,9 @@
   "@
    fsub %0,%1,%2
    fsub %0,%1,%2
-   fsub   %0,%S1,%2
-   fsub   %0,%1,%S2
-   fsub%? %0,%1,%S2"
+   fsub   %0,%1,%2
+   fsub   %0,%1,%2
+   fsub%? %0,%1,%2"
   [(set_attr "type" "spfp")
   (set_attr "length" "4,4,8,8,8")])
 
@@ -89,9 +89,9 @@
   "@
    fmul %0,%1,%2
    fmul %0,%1,%2
-   fmul   %0,%S1,%2
-   fmul   %0,%1,%S2
-   fmul%? %0,%1,%S2"
+   fmul   %0,%1,%2
+   fmul   %0,%1,%2
+   fmul%? %0,%1,%2"
   [(set_attr "type" "spfp")
   (set_attr "length" "4,4,8,8,8")])
 
diff --git a/gcc/config/arc/linux.h b/gcc/config/arc/linux.h
index d8e0063..8abc2c6 100644
--- a/gcc/config/arc/linux.h
+++ b/gcc/config/arc/linux.h
@@ -61,6 +61,7 @@ along with GCC; see the file COPYING3.  If not see
    %{shared:-lc} \
    %{!shared:%{profile:-lc_p}%{!profile:-lc}}"
 
+#undef TARGET_ASM_FILE_END
 #define TARGET_ASM_FILE_END file_end_indicate_exec_stack
 
 /* No SDATA default for linux.  */
diff --git a/gcc/config/arc/simdext.md b/gcc/config/arc/simdext.md
index 9f5b4a8..32a9638 100644
--- a/gcc/config/arc/simdext.md
+++ b/gcc/config/arc/simdext.md
@@ -1190,7 +1190,7 @@
 (define_insn "vendrec_insn"
   [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand"  "r")] UNSPEC_ARC_SIMD_VENDREC)]
   "TARGET_SIMD_SET"
-  "vendrec %S0"
+  "vendrec %0"
   [(set_attr "type" "simd_vcontrol")
    (set_attr "length" "4")
    (set_attr "cond" "nocond")])
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 8aa443f..1e16d06 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -3751,6 +3751,16 @@ the call site.  A function marked with the @code{short_call}
 attribute will always be close enough to be called with a conditional
 branch-and-link instruction, which has a 21-bit offset from
 the call site.
+
+@item jli_always
+@cindex @code{jli_always} function attribute, ARC
+Forces the particular function to be called using jli instruction.
+
+@item jli_fixed
+@cindex @code{jli_fixed} function attribute, ARC
+Identical like the above one, but the location of the function in the
+JLI table is known and given as an attribute parameter.
+
 @end table
 
 @node ARM Function Attributes
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 1533a12..041be9a 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -608,7 +608,7 @@ Objective-C and Objective-C++ Dialects}.
 -msplit-vecmove-early  -m1reg-@var{reg}}
 
 @emph{ARC Options}
-@gccoptlist{-mbarrel-shifter @gol
+@gccoptlist{-mbarrel-shifter -mjli-always @gol
 -mcpu=@var{cpu}  -mA6  -mARC600  -mA7  -mARC700 @gol
 -mdpfp  -mdpfp-compact  -mdpfp-fast  -mno-dpfp-lrsr @gol
 -mea  -mno-mpy  -mmul32x16  -mmul64  -matomic @gol
@@ -14622,6 +14622,11 @@ is being compiled:
 Generate instructions supported by barrel shifter.  This is the default
 unless @option{-mcpu=ARC601} or @samp{-mcpu=ARCEM} is in effect.
 
+@item -mjli-always
+@opindex mjli-alawys
+Force to call a function using jli_s instruction.  This option is
+valid only for ARCv2 architecture.
+
 @item -mcpu=@var{cpu}
 @opindex mcpu
 Set architecture type, register usage, and instruction scheduling
diff --git a/gcc/testsuite/gcc.target/arc/jli-1.c b/gcc/testsuite/gcc.target/arc/jli-1.c
new file mode 100644
index 0000000..f7259b3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/jli-1.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-skip-if "jli only available for ARCv2" { arc700 || arc6xx } } */
+/* { dg-options "-O0 -mcode-density" } */
+
+int func(int i) __attribute__((jli_always));
+
+int func(int i)
+{
+  return i*i;
+}
+
+int main()
+{
+  return func(100);
+}
+
+/* { dg-final { scan-assembler "jli_s @__jli.func" } } */
+/* { dg-final { scan-assembler ".weak __jli.func" } } */
+/* { dg-final { scan-assembler "b\\\s+@func" } } */
diff --git a/gcc/testsuite/gcc.target/arc/jli-2.c b/gcc/testsuite/gcc.target/arc/jli-2.c
new file mode 100644
index 0000000..96a35a4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/jli-2.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-skip-if "jli only available for ARCv2" { arc700 || arc6xx } } */
+/* { dg-options "-O0 -mcode-density" } */
+
+int func(int i) __attribute__((jli_fixed(2)));
+
+int func(int i)
+{
+  return i*i;
+}
+
+int main()
+{
+  return func(100);
+}
+
+/* { dg-final { scan-assembler "jli_s 2" } } */
+/* { dg-final { scan-assembler-not ".weak __jli.func" } } */
+/* { dg-final { scan-assembler-not "b\\\s+@func" } } */
-- 
1.9.1

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

* Re: [PATCH 5/6] [ARC] Add 'uncached' attribute.
  2017-11-02 12:34 ` [PATCH 5/6] [ARC] Add 'uncached' attribute Claudiu Zissulescu
@ 2017-11-03  2:26   ` Sandra Loosemore
  2017-11-03 11:24     ` Claudiu Zissulescu
  2018-01-29 20:23   ` Andrew Burgess
  1 sibling, 1 reply; 18+ messages in thread
From: Sandra Loosemore @ 2017-11-03  2:26 UTC (permalink / raw)
  To: Claudiu Zissulescu, gcc-patches; +Cc: Francois.Bedard, andrew.burgess

On 11/02/2017 06:30 AM, Claudiu Zissulescu wrote:
> From: claziss <claziss@synopsys.com>
>
> The _Uncached type qualifier can be used to bypass the cache without
> resorting to declaring variables as volatile.
>
> gcc/
> 2017-07-12  Claudiu Zissulescu  <claziss@synopsys.com>
>
> 	* config/arc/arc-protos.h (arc_is_uncached_mem_p): Function proto.
> 	* config/arc/arc.c (arc_handle_uncached_attribute): New function.
> 	(arc_attribute_table): Add 'uncached' attribute.
> 	(arc_print_operand): Print '.di' flag for uncached memory
> 	accesses.
> 	(arc_in_small_data_p): Do not consider for small data the uncached
> 	types.
> 	(arc_is_uncached_mem_p): New function.
> 	* config/arc/predicates.md (compact_store_memory_operand): Check
> 	for uncached memory accesses.
> 	(nonvol_nonimm_operand): Likewise.

I see no documentation here.

-Sandra

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

* RE: [PATCH 5/6] [ARC] Add 'uncached' attribute.
  2017-11-03  2:26   ` Sandra Loosemore
@ 2017-11-03 11:24     ` Claudiu Zissulescu
  2017-11-03 18:55       ` Sandra Loosemore
  0 siblings, 1 reply; 18+ messages in thread
From: Claudiu Zissulescu @ 2017-11-03 11:24 UTC (permalink / raw)
  To: Sandra Loosemore, gcc-patches; +Cc: Francois.Bedard, andrew.burgess

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

> 
> I see no documentation here.
> 

Ups, forgot this one :) Please find it attached. I'll merge it into the final patch when everything is approved.

Thanks,
Claudiu 

[-- Attachment #2: 0001-ARC-DOC-Add-uncached-documentation.patch --]
[-- Type: application/octet-stream, Size: 1254 bytes --]

From 5799cd9915c07c498079fa463d813d0b4005fbc5 Mon Sep 17 00:00:00 2001
From: claziss <claziss@synopsys.com>
Date: Fri, 3 Nov 2017 12:16:02 +0100
Subject: [PATCH] [ARC][DOC] Add 'uncached' documentation

---
 gcc/doc/extend.texi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 1f6ef4e..b02777e 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -6728,6 +6728,7 @@ attributes.
 
 @menu
 * Common Type Attributes::
+* ARC Type Attributes::
 * ARM Type Attributes::
 * MeP Type Attributes::
 * PowerPC Type Attributes::
@@ -7161,6 +7162,16 @@ To specify multiple attributes, separate them by commas within the
 double parentheses: for example, @samp{__attribute__ ((aligned (16),
 packed))}.
 
+@node ARC Type Attributes
+@subsection ARC Type Attributes
+
+@cindex @code{uncached} type attribute, ARC
+Declaring variables @code{uncached} allows you to exclude data-cache
+participation in load and store operations on those variables without
+involving the additional semantic implications of volatile.  The
+@code{.di} instruction suffix is used for all loads and stores of data
+declared @code{uncached}.
+
 @node ARM Type Attributes
 @subsection ARM Type Attributes
 
-- 
1.9.1


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

* Re: [PATCH 5/6] [ARC] Add 'uncached' attribute.
  2017-11-03 11:24     ` Claudiu Zissulescu
@ 2017-11-03 18:55       ` Sandra Loosemore
  2017-11-09  9:13         ` Claudiu Zissulescu
  0 siblings, 1 reply; 18+ messages in thread
From: Sandra Loosemore @ 2017-11-03 18:55 UTC (permalink / raw)
  To: Claudiu Zissulescu, gcc-patches; +Cc: Francois.Bedard, andrew.burgess

On 11/03/2017 05:22 AM, Claudiu Zissulescu wrote:
>>
>> I see no documentation here.
>>
>
> Ups, forgot this one :) Please find it attached. I'll merge it into the final patch when everything is approved.
>
> Thanks,
> Claudiu
>
> +@node ARC Type Attributes
> +@subsection ARC Type Attributes
> +
> +@cindex @code{uncached} type attribute, ARC
> +Declaring variables @code{uncached} allows you to exclude data-cache

Since this is a type attribute and not a variable attribute (I presume 
to allow accessing objects through a pointer), it would be better to say

Declaring objects with the @code{uncached} type attribute allows....

> +participation in load and store operations on those variables without

And s/variables/objects/ here too.

> +involving the additional semantic implications of volatile.  The

You probably want @code{volatile} markup here?

> +@code{.di} instruction suffix is used for all loads and stores of data
> +declared @code{uncached}.
> +

Otherwise, the description makes sense to me.  (In fact, I might 
eventually want to copy this attribute over to the Nios II backend, too, 
since it also has similar "io"-variant load/store instructions.)

-Sandra

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

* RE: [PATCH 5/6] [ARC] Add 'uncached' attribute.
  2017-11-03 18:55       ` Sandra Loosemore
@ 2017-11-09  9:13         ` Claudiu Zissulescu
  0 siblings, 0 replies; 18+ messages in thread
From: Claudiu Zissulescu @ 2017-11-09  9:13 UTC (permalink / raw)
  To: Sandra Loosemore, gcc-patches; +Cc: Francois.Bedard, andrew.burgess

Just for the record, here it is the updated documentation as suggested. And, indeed the description may very well be suited for NIOS io-variant as well.

Thank you Sandra,
Claudiu

---
 gcc/doc/extend.texi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index a7a770f..3243494 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -6728,6 +6728,7 @@ attributes.
 
 @menu
 * Common Type Attributes::
+* ARC Type Attributes::
 * ARM Type Attributes::
 * MeP Type Attributes::
 * PowerPC Type Attributes::
@@ -7161,6 +7162,16 @@ To specify multiple attributes, separate them by commas within the
 double parentheses: for example, @samp{__attribute__ ((aligned (16),
 packed))}.
 
+@node ARC Type Attributes
+@subsection ARC Type Attributes
+
+@cindex @code{uncached} type attribute, ARC
+Declaring objects with @code{uncached} allows you to exclude
+data-cache participation in load and store operations on those objects
+without involving the additional semantic implications of
+@code{volatile}.  The @code{.di} instruction suffix is used for all
+loads and stores of data declared @code{uncached}.
+
 @node ARM Type Attributes
 @subsection ARM Type Attributes
 
-- 
1.9.1

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

* Re: [PATCH 1/6] [ARC] Add JLI support.
  2017-11-02 12:34 ` [PATCH 1/6] [ARC] Add JLI support Claudiu Zissulescu
@ 2018-01-16 10:20   ` Andrew Burgess
  0 siblings, 0 replies; 18+ messages in thread
From: Andrew Burgess @ 2018-01-16 10:20 UTC (permalink / raw)
  To: Claudiu Zissulescu; +Cc: gcc-patches, Francois.Bedard

* Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com> [2017-11-02 13:30:30 +0100]:

> The ARCv2 ISA provides the JLI instruction, which is two-byte instructions
> that can be used to reduce code size in an application. To make use of it,
> we provide two new function attributes 'jli_always' and 'jli_fixed' which
> will force the compiler to call the indicated function using a jli_s
> instruction. The compiler also generates the entries in the JLI table for
> the case when we use 'jli_always' attribute. In the case of 'jli_fixed'
> the compiler assumes a fixed position of the function into JLI
> table. Thus, the user needs to provide an assembly file with the JLI table
> for the final link. This is usefully when we want to have a table in ROM
> and a second table in the RAM memory.
> 
> The jli instruction usage can be also forced without the need to annotate
> the source code via '-mjli-always' command.
> 
> gcc/
> 2017-02-10  Claudiu Zissulescu  <claziss@synopsys.com>
> 	    John Eric Martin <John.Martin@emmicro-us.com>
> 
> 	* config/arc/arc-protos.h: Add arc_is_jli_call_p proto.
> 	* config/arc/arc.c (_arc_jli_section): New struct.
> 	(arc_jli_section): New type.
> 	(rc_jli_sections): New static variable.
> 	(arc_handle_jli_attribute): New function.
> 	(arc_attribute_table): Add jli_always and jli_fixed attribute.
> 	(arc_file_end): New function.
> 	(TARGET_ASM_FILE_END): Define.
> 	(arc_print_operand): Reuse 'S' letter for JLI output instruction.
> 	(arc_add_jli_section): New function.
> 	(jli_call_scan): Likewise.
> 	(arc_reorg): Call jli_call_scan.
> 	(arc_output_addsi): Remove 'S' from printing asm operand.
> 	(arc_is_jli_call_p): New function.
> 	* config/arc/arc.md (movqi_insn): Remove 'S' from printing asm
> 	operand.
> 	(movhi_insn): Likewise.
> 	(movsi_insn): Likewise.
> 	(movsi_set_cc_insn): Likewise.
> 	(loadqi_update): Likewise.
> 	(load_zeroextendqisi_update): Likewise.
> 	(load_signextendqisi_update): Likewise.
> 	(loadhi_update): Likewise.
> 	(load_zeroextendhisi_update): Likewise.
> 	(load_signextendhisi_update): Likewise.
> 	(loadsi_update): Likewise.
> 	(loadsf_update): Likewise.
> 	(movsicc_insn): Likewise.
> 	(bset_insn): Likewise.
> 	(bxor_insn): Likewise.
> 	(bclr_insn): Likewise.
> 	(bmsk_insn): Likewise.
> 	(bicsi3_insn): Likewise.
> 	(cmpsi_cc_c_insn): Likewise.
> 	(movsi_ne): Likewise.
> 	(movsi_cond_exec): Likewise.
> 	(clrsbsi2): Likewise.
> 	(norm_f): Likewise.
> 	(normw): Likewise.
> 	(swap): Likewise.
> 	(divaw): Likewise.
> 	(flag): Likewise.
> 	(sr): Likewise.
> 	(kflag): Likewise.
> 	(ffs): Likewise.
> 	(ffs_f): Likewise.
> 	(fls): Likewise.
> 	(call_i): Remove 'S' asm letter, add jli instruction.
> 	(call_value_i): Likewise.
> 	* config/arc/arc.op (mjli-always): New option.
> 	* config/arc/constraints.md (Cji): New constraint.
> 	* config/arc/fpx.md (addsf3_fpx): Remove 'S' from printing asm
> 	operand.
> 	(subsf3_fpx): Likewise.
> 	(mulsf3_fpx): Likewise.
> 	* config/arc/simdext.md (vendrec_insn): Remove 'S' from printing
> 	asm operand.
> 	* doc/extend.texi (ARC): Document 'jli-always' and 'jli-fixed'
> 	function attrbutes.
> 	* doc/invoke.texi (ARC): Document mjli-always option.
> 
> gcc/testsuite
> 2017-02-10  Claudiu Zissulescu  <claziss@synopsys.com>
> 
> 	* gcc.target/arc/jli-1.c: New file.
> 	* gcc.target/arc/jli-2.c: Likewise.

This looks fine, but I wonder if there should be some documentation
that mentions the new .jlitab section added?

There's one whitespace issue I also spotted...

> @@ -5026,6 +5062,36 @@ static void arc_file_start (void)
>    fprintf (asm_out_file, "\t.cpu %s\n", arc_cpu_string);
>  }
>  
> +/* Implement `TARGET_ASM_FILE_END'.  */
> +/* Outputs to the stdio stream FILE jli related text.  */
> +
> +void arc_file_end (void)
> +{
> +  arc_jli_section *sec = arc_jli_sections;
> +
> +  while (sec != NULL)
> +  {

I think the '{' is not indented correctly.

Thanks,
Andrew

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

* Re: [PATCH 2/6] [ARC] Add SJLI support.
  2017-11-02 12:34 ` [PATCH 2/6] [ARC] Add SJLI support Claudiu Zissulescu
@ 2018-01-16 10:37   ` Andrew Burgess
  0 siblings, 0 replies; 18+ messages in thread
From: Andrew Burgess @ 2018-01-16 10:37 UTC (permalink / raw)
  To: Claudiu Zissulescu; +Cc: gcc-patches, Francois.Bedard

* Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com> [2017-11-02 13:30:31 +0100]:

> gcc/
> 2017-02-20  Claudiu Zissulescu  <claziss@synopsys.com>
> 
> 	* config/arc/arc-protos.h: Add arc_is_secure_call_p proto.
> 	* config/arc/arc.c (arc_handle_secure_attribute): New function.
> 	(arc_attribute_table): Add 'secure_call' attribute.
> 	(arc_print_operand): Print secure call operand.
> 	(arc_function_ok_for_sibcall): Don't optimize tail calls when
> 	secure.
> 	(arc_is_secure_call_p): New function.
> 	* config/arc/arc.md (call_i): Add support for sjli instruction.
> 	(call_value_i): Likewise.
> 	* config/arc/constraints.md (Csc): New constraint.
> ---
>  gcc/config/arc/arc-protos.h   |   1 +
>  gcc/config/arc/arc.c          | 164 +++++++++++++++++++++++++++++++-----------
>  gcc/config/arc/arc.md         |  32 +++++----
>  gcc/config/arc/constraints.md |   7 ++
>  gcc/doc/extend.texi           |   6 ++
>  5 files changed, 155 insertions(+), 55 deletions(-)

Looks fine, few comments inline below.

Thanks
Andrew

> 
> @@ -3939,6 +3985,9 @@ arc_print_operand (FILE *file, rtx x, int code)
>  			    : NULL_TREE);
>  	      if (lookup_attribute ("jli_fixed", attrs))
>  		{
> +		  /* No special treatment for jli_fixed functions.  */
> +		  if (code == 'j' )

Extra space before ')'.

> +		    break;
>  		  fprintf (file, "%ld\t; @",
>  			   TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs))));
>  		  assemble_name (file, XSTR (x, 0));
> @@ -3947,6 +3996,22 @@ arc_print_operand (FILE *file, rtx x, int code)
>  	    }
>  	  fprintf (file, "@__jli.");
>  	  assemble_name (file, XSTR (x, 0));
> +	  if (code == 'j')
> +	    arc_add_jli_section (x);
> +	  return;
> +	}
> +      if (GET_CODE (x) == SYMBOL_REF
> +	  && arc_is_secure_call_p (x))
> +	{
> +	  /* No special treatment for secure functions.  */
> +	  if (code == 'j' )
> +	    break;
> +	  tree attrs = (TREE_TYPE (SYMBOL_REF_DECL (x)) != error_mark_node
> +			? TYPE_ATTRIBUTES (TREE_TYPE (SYMBOL_REF_DECL (x)))
> +			: NULL_TREE);
> +	  fprintf (file, "%ld\t; @",
> +		   TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs))));
> +	  assemble_name (file, XSTR (x, 0));
>  	  return;
>  	}
>        break;
> @@ -6897,6 +6962,8 @@ arc_function_ok_for_sibcall (tree decl,
>  	return false;
>        if (lookup_attribute ("jli_fixed", attrs))
>  	return false;
> +      if (lookup_attribute ("secure_call", attrs))
> +	return false;
>      }
>  
>    /* Everything else is ok.  */
> @@ -7594,46 +7661,6 @@ arc_reorg_loops (void)
>    reorg_loops (true, &arc_doloop_hooks);
>  }
>  
> -/* Add the given function declaration to emit code in JLI section.  */
> -
> -static void
> -arc_add_jli_section (rtx pat)
> -{
> -  const char *name;
> -  tree attrs;
> -  arc_jli_section *sec = arc_jli_sections, *new_section;
> -  tree decl = SYMBOL_REF_DECL (pat);
> -
> -  if (!pat)
> -    return;
> -
> -  if (decl)
> -    {
> -      /* For fixed locations do not generate the jli table entry.  It
> -	 should be provided by the user as an asm file.  */
> -      attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
> -      if (lookup_attribute ("jli_fixed", attrs))
> -	return;
> -    }
> -
> -  name = XSTR (pat, 0);
> -
> -  /* Don't insert the same symbol twice.  */
> -  while (sec != NULL)
> -    {
> -      if(strcmp (name, sec->name) == 0)
> -	return;
> -      sec = sec->next;
> -    }
> -
> -  /* New name, insert it.  */
> -  new_section = (arc_jli_section *) xmalloc (sizeof (arc_jli_section));
> -  gcc_assert (new_section != NULL);
> -  new_section->name = name;
> -  new_section->next = arc_jli_sections;
> -  arc_jli_sections = new_section;
> -}
> -
>  /* Scan all calls and add symbols to be emitted in the jli section if
>     needed.  */
>  
> @@ -10968,6 +10995,63 @@ arc_handle_jli_attribute (tree *node ATTRIBUTE_UNUSED,
>     return NULL_TREE;
>  }
>  
> +/* Handle and "scure" attribute; arguments as in struct
> +   attribute_spec.handler.  */
> +
> +static tree
> +arc_handle_secure_attribute (tree *node ATTRIBUTE_UNUSED,
> +			  tree name, tree args, int,
> +			  bool *no_add_attrs)
> +{
> +  if (!TARGET_EM)
> +    {
> +      warning (OPT_Wattributes,
> +	       "%qE attribute only valid for ARC EM architecture",
> +	       name);
> +      *no_add_attrs = true;
> +    }
> +
> +  if (args == NULL_TREE)
> +    {
> +      warning (OPT_Wattributes,
> +	       "argument of %qE attribute is missing",
> +	       name);
> +      *no_add_attrs = true;
> +    }
> +  else
> +    {
> +      if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
> +	TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
> +      tree arg = TREE_VALUE (args);
> +      if (TREE_CODE (arg) != INTEGER_CST)
> +	{
> +	  warning (0, "%qE attribute allows only an integer constant argument",
> +		   name);
> +	  *no_add_attrs = true;
> +	}
> +      /* FIXME! add range check.  TREE_INT_CST_LOW (arg) */

Should this be fixed in this commit?

> +    }
> +   return NULL_TREE;
> +}
> +
> +/* Return nonzero if the symbol is a secure function.  */
> +
> +bool
> +arc_is_secure_call_p (rtx pat)
> +{
> +  tree attrs;
> +  tree decl = SYMBOL_REF_DECL (pat);
> +
> +  if (!decl)
> +    return false;
> +
> +  attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
> +  if (lookup_attribute ("secure_call", attrs))
> +    return true;
> +
> +  return false;
> +}
> +
>  /* Implement TARGET_USE_ANCHORS_FOR_SYMBOL_P.  We don't want to use
>     anchors for small data: the GP register acts as an anchor in that
>     case.  We also don't want to use them for PC-relative accesses,
> diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
> index c72420c..48625d3 100644
> --- a/gcc/config/arc/arc.md
> +++ b/gcc/config/arc/arc.md
> @@ -736,10 +736,10 @@
>     mov%? %0,%1		;11
>     add %0,%1		;12
>     add %0,pcl,%1@pcl    ;13
> -   mov%? %0,%1  	;14
> -   mov%? %0,%1		;15
> -   mov%? %0,%1		;16
> -   ld%?%U1 %0,%1	;17
> +   mov%? %0,%j1 	;14
> +   mov%? %0,%j1		;15
> +   mov%? %0,%j1		;16
> +   ld%? %0,%1		;17
>     st%? %1,%0%&		;18
>     * return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\");
>     * return arc_short_long (insn, \"pop%? %0%&\",  \"ld%U1 %0,%1%&\");
> @@ -4229,7 +4229,7 @@
>  ; alternative 1 ("q"), that means that we can't use the short form.
>  (define_insn "*call_i"
>    [(call (mem:SI (match_operand:SI 0
> -		  "call_address_operand" "Rcq,q,c,Cji,Cbp,Cbr,L,I,Cal"))
> +		  "call_address_operand" "Rcq,q,c,Cji,Csc,Cbp,Cbr,L,I,Cal"))
>  	 (match_operand 1 "" ""))
>     (clobber (reg:SI 31))]
>    ""
> @@ -4238,15 +4238,16 @@
>     jl%!%* [%0]%&
>     jl%!%* [%0]
>     jli_s %S0
> +   sjli  %S0
>     bl%!%* %P0
>     bl%!%* %P0
>     jl%!%* %0
>     jl%* %0
>     jl%! %0"
> -  [(set_attr "type" "call,call,call,call_no_delay_slot,call,call,call,call,call_no_delay_slot")
> -   (set_attr "iscompact" "maybe,false,*,true,*,*,*,*,*")
> -   (set_attr "predicable" "no,no,yes,no,yes,no,yes,no,yes")
> -   (set_attr "length" "*,*,4,2,4,4,4,4,8")])
> +  [(set_attr "type" "call,call,call,call_no_delay_slot,call_no_delay_slot,call,call,call,call,call_no_delay_slot")
> +   (set_attr "iscompact" "maybe,false,*,true,*,*,*,*,*,*")
> +   (set_attr "predicable" "no,no,yes,no,no,yes,no,yes,no,yes")
> +   (set_attr "length" "*,*,4,2,4,4,4,4,4,8")])
>  
>  (define_expand "call_value"
>    ;; operand 2 is stack_size_rtx
> @@ -4272,9 +4273,9 @@
>  ; At instruction output time, if it doesn't match and we end up with
>  ; alternative 1 ("q"), that means that we can't use the short form.
>  (define_insn "*call_value_i"
> -  [(set (match_operand 0 "dest_reg_operand"  "=Rcq,q,w,  w,  w,  w,w,w,  w")
> +  [(set (match_operand 0 "dest_reg_operand"  "=Rcq,q,w,  w,  w,  w,  w,w,w,  w")
>  	(call (mem:SI (match_operand:SI 1
> -		       "call_address_operand" "Rcq,q,c,Cji,Cbp,Cbr,L,I,Cal"))
> +		       "call_address_operand" "Rcq,q,c,Cji,Csc,Cbp,Cbr,L,I,Cal"))
>  	      (match_operand 2 "" "")))
>     (clobber (reg:SI 31))]
>    ""
> @@ -4283,15 +4284,16 @@
>     jl%!%* [%1]%&
>     jl%!%* [%1]
>     jli_s %S1
> +   sjli  %S1
>     bl%!%* %P1;1
>     bl%!%* %P1;1
>     jl%!%* %1
>     jl%* %1
>     jl%! %1"
> -  [(set_attr "type" "call,call,call,call_no_delay_slot,call,call,call,call,call_no_delay_slot")
> -   (set_attr "iscompact" "maybe,false,*,true,*,*,*,*,*")
> -   (set_attr "predicable" "no,no,yes,no,yes,no,yes,no,yes")
> -   (set_attr "length" "*,*,4,2,4,4,4,4,8")])
> +  [(set_attr "type" "call,call,call,call_no_delay_slot,call_no_delay_slot,call,call,call,call,call_no_delay_slot")
> +   (set_attr "iscompact" "maybe,false,*,true,false,*,*,*,*,*")
> +   (set_attr "predicable" "no,no,yes,no,no,yes,no,yes,no,yes")
> +   (set_attr "length" "*,*,4,2,4,4,4,4,4,8")])
>  
>  ; There is a bl_s instruction (16 bit opcode branch-and-link), but we can't
>  ; use it for lack of inter-procedural branch shortening.
> diff --git a/gcc/config/arc/constraints.md b/gcc/config/arc/constraints.md
> index 7114e6e..3fed018 100644
> --- a/gcc/config/arc/constraints.md
> +++ b/gcc/config/arc/constraints.md
> @@ -407,6 +407,13 @@
>         (match_test "TARGET_CODE_DENSITY")
>         (match_test "arc_is_jli_call_p (op)")))
>  
> +(define_constraint "Csc"
> +  "Secure call"
> +  (and (match_code "symbol_ref")
> +       (match_test "TARGET_CODE_DENSITY")
> +       (match_test "TARGET_EM")
> +       (match_test "arc_is_secure_call_p (op)")))
> +
>  (define_constraint "Cpc"
>    "pc-relative constant"
>    (match_test "arc_legitimate_pic_addr_p (op)"))
> diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
> index 1e16d06..0f8ba05 100644
> --- a/gcc/doc/extend.texi
> +++ b/gcc/doc/extend.texi
> @@ -3761,6 +3761,12 @@ Forces the particular function to be called using jli instruction.
>  Identical like the above one, but the location of the function in the
>  JLI table is known and given as an attribute parameter.
>  
> +@item secure_call
> +@cindex @code{secure_call} function attribute, ARC
> +This attribute allows one to mark secure-code functions that are
> +callable from normal mode.  The location of the secure call function
> +into the SJLI table needs to be passed as argument.
> +
>  @end table
>  
>  @node ARM Function Attributes
> -- 
> 1.9.1
> 

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

* Re: [PATCH 3/6] [ARC] Add support for "register file 16" reduced register set
  2017-11-02 12:34 ` [PATCH 3/6] [ARC] Add support for "register file 16" reduced register set Claudiu Zissulescu
@ 2018-01-16 10:52   ` Andrew Burgess
  0 siblings, 0 replies; 18+ messages in thread
From: Andrew Burgess @ 2018-01-16 10:52 UTC (permalink / raw)
  To: Claudiu Zissulescu; +Cc: gcc-patches, Francois.Bedard

* Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com> [2017-11-02 13:30:32 +0100]:

> gcc/
> 2017-03-20  Claudiu Zissulescu  <claziss@synopsys.com>
> 
> 	* config/arc/arc-arches.def: Option mrf16 valid for all
> 	architectures.
> 	* config/arc/arc-c.def (__ARC_RF16__): New predefined macro.
> 	* config/arc/arc-cpus.def (em_mini): New cpu with rf16 on.
> 	* config/arc/arc-options.def (FL_RF16): Add mrf16 option.
> 	* config/arc/arc-tables.opt: Regenerate.
> 	* config/arc/arc.c (arc_conditional_register_usage): Handle
> 	reduced register file case.
> 	(arc_file_start): Set must have build attributes.
> 	* config/arc/arc.h (MAX_ARC_PARM_REGS): Conditional define using
> 	mrf16 option value.
> 	* config/arc/arc.opt (mrf16): Add new option.
> 	* config/arc/elf.h (ATTRIBUTE_PCS): Define.
> 	* config/arc/genmultilib.awk: Handle new mrf16 option.
> 	* config/arc/linux.h (ATTRIBUTE_PCS): Define.
> 	* config/arc/t-multilib: Regenerate.
> 	* doc/invoke.texi (ARC Options): Document mrf16 option.
> 
> gcc/testsuite/
> 2017-03-20  Claudiu Zissulescu  <claziss@synopsys.com>
> 
> 	* gcc.dg/builtin-apply2.c: Change for the ARC's reduced register
> 	set file case.
> 
> libgcc/
> 2017-09-18  Claudiu Zissulescu  <claziss@synopsys.com>
> 
> 	* config/arc/lib1funcs.S (__udivmodsi4): Use safe version for RF16
> 	option.
> 	(__divsi3): Use RF16 safe registers.
> 	(__modsi3): Likewise.

Looks fine, except I think that the new 'em_mini' cpu needs to be
added to the -mcpu= description in doc/invoke.texi.

Thanks,
Andrew




> ---
>  gcc/config/arc/arc-arches.def         |  8 ++++----
>  gcc/config/arc/arc-c.def              |  1 +
>  gcc/config/arc/arc-cpus.def           |  1 +
>  gcc/config/arc/arc-options.def        |  2 +-
>  gcc/config/arc/arc-tables.opt         |  3 +++
>  gcc/config/arc/arc.c                  | 27 +++++++++++++++++++++++++++
>  gcc/config/arc/arc.h                  |  2 +-
>  gcc/config/arc/arc.opt                |  4 ++++
>  gcc/config/arc/elf.h                  |  4 ++++
>  gcc/config/arc/genmultilib.awk        |  2 ++
>  gcc/config/arc/linux.h                |  9 +++++++++
>  gcc/config/arc/t-multilib             |  4 ++--
>  gcc/doc/invoke.texi                   |  8 +++++++-
>  gcc/testsuite/gcc.dg/builtin-apply2.c |  8 +++++++-
>  libgcc/config/arc/lib1funcs.S         | 22 +++++++++++-----------
>  15 files changed, 84 insertions(+), 21 deletions(-)
> 
> diff --git a/gcc/config/arc/arc-arches.def b/gcc/config/arc/arc-arches.def
> index 29cb9c4..a0d585b 100644
> --- a/gcc/config/arc/arc-arches.def
> +++ b/gcc/config/arc/arc-arches.def
> @@ -40,15 +40,15 @@
>  
>  ARC_ARCH ("arcem", em, FL_MPYOPT_1_6 | FL_DIVREM | FL_CD | FL_NORM	\
>  	  | FL_BS | FL_SWAP | FL_FPUS | FL_SPFP | FL_DPFP		\
> -	  | FL_SIMD | FL_FPUDA | FL_QUARK, 0)
> +	  | FL_SIMD | FL_FPUDA | FL_QUARK | FL_RF16, 0)
>  ARC_ARCH ("archs", hs, FL_MPYOPT_7_9 | FL_DIVREM | FL_NORM | FL_CD	\
>  	  | FL_ATOMIC | FL_LL64 | FL_BS | FL_SWAP			\
> -	  | FL_FPUS | FL_FPUD,						\
> +	  | FL_FPUS | FL_FPUD | FL_RF16,				\
>  	  FL_CD | FL_ATOMIC | FL_BS | FL_NORM | FL_SWAP)
>  ARC_ARCH ("arc6xx", 6xx, FL_BS | FL_NORM | FL_SWAP | FL_MUL64 | FL_MUL32x16 \
> -	  | FL_SPFP | FL_ARGONAUT | FL_DPFP, 0)
> +	  | FL_SPFP | FL_ARGONAUT | FL_DPFP | FL_RF16, 0)
>  ARC_ARCH ("arc700", 700, FL_ATOMIC | FL_BS | FL_NORM | FL_SWAP | FL_EA \
> -	  | FL_SIMD | FL_SPFP | FL_ARGONAUT | FL_DPFP,		       \
> +	  | FL_SIMD | FL_SPFP | FL_ARGONAUT | FL_DPFP | FL_RF16,       \
>  	  FL_BS | FL_NORM | FL_SWAP)
>  
>  /* Local Variables: */
> diff --git a/gcc/config/arc/arc-c.def b/gcc/config/arc/arc-c.def
> index 8c5097e..c9443c9 100644
> --- a/gcc/config/arc/arc-c.def
> +++ b/gcc/config/arc/arc-c.def
> @@ -28,6 +28,7 @@ ARC_C_DEF ("__ARC_NORM__",	TARGET_NORM)
>  ARC_C_DEF ("__ARC_MUL64__",	TARGET_MUL64_SET)
>  ARC_C_DEF ("__ARC_MUL32BY16__", TARGET_MULMAC_32BY16_SET)
>  ARC_C_DEF ("__ARC_SIMD__",	TARGET_SIMD_SET)
> +ARC_C_DEF ("__ARC_RF16__",	TARGET_RF16)
>  
>  ARC_C_DEF ("__ARC_BARREL_SHIFTER__", TARGET_BARREL_SHIFTER)
>  
> diff --git a/gcc/config/arc/arc-cpus.def b/gcc/config/arc/arc-cpus.def
> index 60b4045..c2b0062 100644
> --- a/gcc/config/arc/arc-cpus.def
> +++ b/gcc/config/arc/arc-cpus.def
> @@ -46,6 +46,7 @@
>     TUNE	  Tune value for the given configuration, otherwise NONE.  */
>  
>  ARC_CPU (em,	    em, 0, NONE)
> +ARC_CPU (em_mini,   em, FL_RF16, NONE)
>  ARC_CPU (arcem,	    em, FL_MPYOPT_2|FL_CD|FL_BS, NONE)
>  ARC_CPU (em4,	    em, FL_CD, NONE)
>  ARC_CPU (em4_dmips, em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS, NONE)
> diff --git a/gcc/config/arc/arc-options.def b/gcc/config/arc/arc-options.def
> index be51614..8fc7b50 100644
> --- a/gcc/config/arc/arc-options.def
> +++ b/gcc/config/arc/arc-options.def
> @@ -60,7 +60,7 @@
>  ARC_OPT (FL_CD,	      (1ULL << 0), MASK_CODE_DENSITY,	   "code density")
>  ARC_OPT (FL_DIVREM,   (1ULL << 1), MASK_DIVREM,		   "div/rem")
>  ARC_OPT (FL_NORM,     (1ULL << 2), MASK_NORM_SET,	   "norm")
> -
> +ARC_OPT (FL_RF16,     (1ULL << 3), MASK_RF16,              "rf16")
>  ARC_OPT (FL_ATOMIC,   (1ULL << 4), MASK_ATOMIC,		   "atomic")
>  ARC_OPT (FL_LL64,     (1ULL << 5), MASK_LL64,		   "double load/store")
>  ARC_OPT (FL_BS,	      (1ULL << 6), MASK_BARREL_SHIFTER,	   "barrel shifter")
> diff --git a/gcc/config/arc/arc-tables.opt b/gcc/config/arc/arc-tables.opt
> index ce23a52..21fc2d3 100644
> --- a/gcc/config/arc/arc-tables.opt
> +++ b/gcc/config/arc/arc-tables.opt
> @@ -28,6 +28,9 @@ EnumValue
>  Enum(processor_type) String(em) Value(PROCESSOR_em)
>  
>  EnumValue
> +Enum(processor_type) String(em_mini) Value(PROCESSOR_em_mini)
> +
> +EnumValue
>  Enum(processor_type) String(arcem) Value(PROCESSOR_arcem)
>  
>  EnumValue
> diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
> index 9867e6e..e7194a2 100644
> --- a/gcc/config/arc/arc.c
> +++ b/gcc/config/arc/arc.c
> @@ -1741,6 +1741,19 @@ arc_conditional_register_usage (void)
>  	reg_alloc_order [i] = i;
>      }
>  
> +  /* Reduced configuration: don't use r4-r9, r16-r25.  */
> +  if (TARGET_RF16)
> +    {
> +      for (i = 4; i <= 9; i++)
> +	{
> +	  fixed_regs[i] = call_used_regs[i] = 1;
> +	}
> +      for (i = 16; i <= 25; i++)
> +	{
> +	  fixed_regs[i] = call_used_regs[i] = 1;
> +	}
> +    }
> +
>    for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
>      if (!call_used_regs[regno])
>        CLEAR_HARD_REG_BIT (reg_class_contents[SIBCALL_REGS], regno);
> @@ -5125,6 +5138,20 @@ static void arc_file_start (void)
>  {
>    default_file_start ();
>    fprintf (asm_out_file, "\t.cpu %s\n", arc_cpu_string);
> +
> +  /* Set some want to have build attributes.  */
> +  asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_PCS_config, %d\n",
> +	       ATTRIBUTE_PCS);
> +  asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_rf16, %d\n",
> +	       TARGET_RF16 ? 1 : 0);
> +  asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_pic, %d\n",
> +	       flag_pic ? 2 : 0);
> +  asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_tls, %d\n",
> +	       (arc_tp_regno != -1) ? 1 : 0);
> +  asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_sda, %d\n",
> +	       TARGET_NO_SDATA_SET ? 0 : 2);
> +  asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_exceptions, %d\n",
> +	       TARGET_OPTFPE ? 1 : 0);
>  }
>  
>  /* Implement `TARGET_ASM_FILE_END'.  */
> diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
> index ab12413..de211e2 100644
> --- a/gcc/config/arc/arc.h
> +++ b/gcc/config/arc/arc.h
> @@ -727,7 +727,7 @@ arc_return_addr_rtx(COUNT,FRAME)
>    ((CUM) = 0)
>  
>  /* The number of registers used for parameter passing.  Local to this file.  */
> -#define MAX_ARC_PARM_REGS 8
> +#define MAX_ARC_PARM_REGS (TARGET_RF16 ? 4 : 8)
>  
>  /* 1 if N is a possible register number for function argument passing.  */
>  #define FUNCTION_ARG_REGNO_P(N) \
> diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt
> index 9baaf77..aacb599 100644
> --- a/gcc/config/arc/arc.opt
> +++ b/gcc/config/arc/arc.opt
> @@ -523,3 +523,7 @@ Enum(arc_lpc) String(28) Value(28)
>  
>  EnumValue
>  Enum(arc_lpc) String(32) Value(32)
> +
> +mrf16
> +Target Report Mask(RF16)
> +Enable 16-entry register file.
> diff --git a/gcc/config/arc/elf.h b/gcc/config/arc/elf.h
> index 175e9fd..288a845 100644
> --- a/gcc/config/arc/elf.h
> +++ b/gcc/config/arc/elf.h
> @@ -67,5 +67,9 @@ along with GCC; see the file COPYING3.  If not see
>  #undef TARGET_AUTO_MODIFY_REG_DEFAULT
>  #define TARGET_AUTO_MODIFY_REG_DEFAULT 1
>  
> +/* Build attribute: procedure call standard.  */
> +#undef ATTRIBUTE_PCS
> +#define ATTRIBUTE_PCS 2
> +
>  #undef TARGET_ASM_FILE_END
>  #define TARGET_ASM_FILE_END arc_file_end
> diff --git a/gcc/config/arc/genmultilib.awk b/gcc/config/arc/genmultilib.awk
> index 2734adc..3266bb0 100644
> --- a/gcc/config/arc/genmultilib.awk
> +++ b/gcc/config/arc/genmultilib.awk
> @@ -130,6 +130,8 @@ BEGIN {
>  	    line = line "/spfp"
>  	  else if (cpu_flg[i] == "FL_DPFP")
>  	    line = line "/dpfp"
> +	  else if (cpu_flg[i] == "FL_RF16")
> +	    line = line "/mrf16"
>  	  else
>  	    {
>  	      print "Don't know the flag " cpu_flg[i] > "/dev/stderr"
> diff --git a/gcc/config/arc/linux.h b/gcc/config/arc/linux.h
> index 8abc2c6..5099391 100644
> --- a/gcc/config/arc/linux.h
> +++ b/gcc/config/arc/linux.h
> @@ -92,3 +92,12 @@ along with GCC; see the file COPYING3.  If not see
>  /* Pre/post modify with register displacement are default off.  */
>  #undef TARGET_AUTO_MODIFY_REG_DEFAULT
>  #define TARGET_AUTO_MODIFY_REG_DEFAULT 0
> +
> +#undef SUBTARGET_CPP_SPEC
> +#define SUBTARGET_CPP_SPEC "\
> +   %{pthread:-D_REENTRANT} \
> +"
> +
> +/* Build attribute: procedure call standard.  */
> +#undef ATTRIBUTE_PCS
> +#define ATTRIBUTE_PCS 3
> diff --git a/gcc/config/arc/t-multilib b/gcc/config/arc/t-multilib
> index 9ffd4a6..eb1d8e3 100644
> --- a/gcc/config/arc/t-multilib
> +++ b/gcc/config/arc/t-multilib
> @@ -21,9 +21,9 @@
>  # along with GCC; see the file COPYING3.  If not see
>  # <http://www.gnu.org/licenses/>.
>  
> -MULTILIB_OPTIONS = mcpu=em/mcpu=arcem/mcpu=em4/mcpu=em4_dmips/mcpu=em4_fpus/mcpu=em4_fpuda/mcpu=quarkse_em/mcpu=hs/mcpu=archs/mcpu=hs34/mcpu=hs38/mcpu=hs38_linux/mcpu=arc600/mcpu=arc600_norm/mcpu=arc600_mul64/mcpu=arc600_mul32x16/mcpu=arc601/mcpu=arc601_norm/mcpu=arc601_mul64/mcpu=arc601_mul32x16/mcpu=arc700/mcpu=nps400
> +MULTILIB_OPTIONS = mcpu=em/mcpu=em_mini/mcpu=arcem/mcpu=em4/mcpu=em4_dmips/mcpu=em4_fpus/mcpu=em4_fpuda/mcpu=quarkse_em/mcpu=hs/mcpu=archs/mcpu=hs34/mcpu=hs38/mcpu=hs38_linux/mcpu=hs4x/mcpu=hs4xd/mcpu=arc600/mcpu=arc600_norm/mcpu=arc600_mul64/mcpu=arc600_mul32x16/mcpu=arc601/mcpu=arc601_norm/mcpu=arc601_mul64/mcpu=arc601_mul32x16/mcpu=arc700/mcpu=nps400
>  
> -MULTILIB_DIRNAMES = em arcem em4 em4_dmips em4_fpus em4_fpuda quarkse_em hs archs hs34 hs38 hs38_linux arc600 arc600_norm arc600_mul64 arc600_mul32x16 arc601 arc601_norm arc601_mul64 arc601_mul32x16 arc700 nps400
> +MULTILIB_DIRNAMES = em em_mini arcem em4 em4_dmips em4_fpus em4_fpuda quarkse_em hs archs hs34 hs38 hs38_linux hs4x hs4xd arc600 arc600_norm arc600_mul64 arc600_mul32x16 arc601 arc601_norm arc601_mul64 arc601_mul32x16 arc700 nps400
>  
>  # Aliases:
>  MULTILIB_MATCHES  = mcpu?arc600=mcpu?ARC600
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 041be9a..409f9be 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -625,7 +625,7 @@ Objective-C and Objective-C++ Dialects}.
>  -mmixed-code  -mq-class  -mRcq  -mRcw  -msize-level=@var{level} @gol
>  -mtune=@var{cpu}  -mmultcost=@var{num} @gol
>  -munalign-prob-threshold=@var{probability}  -mmpy-option=@var{multo} @gol
> --mdiv-rem  -mcode-density  -mll64  -mfpu=@var{fpu}}
> +-mdiv-rem  -mcode-density  -mll64  -mfpu=@var{fpu} -mrf16}
>  
>  @emph{ARM Options}
>  @gccoptlist{-mapcs-frame  -mno-apcs-frame @gol
> @@ -14969,6 +14969,12 @@ specified, the compiler and run-time library might continue to use the
>  loop mechanism for various needs.  This option defines macro
>  @code{__ARC_LPC_WIDTH__} with the value of @var{width}.
>  
> +@item -mrf16
> +@opindex mrf16
> +This option instructs the compiler to generate code for a 16-entry
> +register file.  This option defines the @code{__ARC_RF16__}
> +preprocessor macro.
> +
>  @end table
>  
>  The following options are passed through to the assembler, and also
> diff --git a/gcc/testsuite/gcc.dg/builtin-apply2.c b/gcc/testsuite/gcc.dg/builtin-apply2.c
> index 3768caa..d811272 100644
> --- a/gcc/testsuite/gcc.dg/builtin-apply2.c
> +++ b/gcc/testsuite/gcc.dg/builtin-apply2.c
> @@ -19,9 +19,15 @@
>     E, F and G are passed on stack.  So the size of the stack argument
>     data is 20.  */
>  #define STACK_ARGUMENTS_SIZE  20
> -#elif defined __MMIX__ || defined __arc__
> +#elif defined __MMIX__
>  /* No parameters on stack for bar.  */
>  #define STACK_ARGUMENTS_SIZE 0
> +#elif defined __arc__
> +# ifdef __ARC_RF16__
> +#  define STACK_ARGUMENTS_SIZE 4*4
> +# else
> +#  define STACK_ARGUMENTS_SIZE 0
> +# endif
>  #else
>  #define STACK_ARGUMENTS_SIZE  64
>  #endif
> diff --git a/libgcc/config/arc/lib1funcs.S b/libgcc/config/arc/lib1funcs.S
> index c3127ad..08e1510 100644
> --- a/libgcc/config/arc/lib1funcs.S
> +++ b/libgcc/config/arc/lib1funcs.S
> @@ -370,7 +370,7 @@ SYM(__udivmodsi4):
>  	mov_s	r0,1
>  	j_s.d	[blink]
>  	mov.c	r0,0
> -#elif !defined (__OPTIMIZE_SIZE__)
> +#elif !defined (__OPTIMIZE_SIZE__) && !defined (__ARC_RF16__)
>  #if defined (__ARC_NORM__) && defined (__ARC_BARREL_SHIFTER__)
>  	lsr_s r2,r0
>  	brhs.d r1,r2,.Lret0_3
> @@ -509,14 +509,14 @@ SYM(__udivsi3):
>  #ifndef __ARC_EA__
>  SYM(__divsi3):
>  	/* A5 / ARC60? */
> -	mov r7,blink
> -	xor r6,r0,r1
> +	mov r12,blink
> +	xor r11,r0,r1
>  	abs_s r0,r0
>  	bl.d @SYM(__udivmodsi4)
> -	 abs_s r1,r1
> -	tst r6,r6
> -	j.d [r7]
> -	 neg.mi r0,r0
> +	abs_s r1,r1
> +	tst r11,r11
> +	j.d [r12]
> +	neg.mi r0,r0
>  #else 	/* !ifndef __ARC_EA__ */
>  	;; We can use the abs, norm, divaw and mpy instructions for ARC700
>  #define MULDIV
> @@ -913,14 +913,14 @@ SYM(__modsi3):
>  #ifndef __ARC_EA__
>  	/* A5 / ARC60? */
>  	mov_s r12,blink
> -	mov_s r6,r0
> +	mov_s r11,r0
>  	abs_s r0,r0
>  	bl.d @SYM(__udivmodsi4)
> -	 abs_s r1,r1
> -	tst r6,r6
> +	abs_s r1,r1
> +	tst r11,r11
>  	neg_s r0,r1
>  	j_s.d [r12]
> -	 mov.pl r0,r1
> +	mov.pl r0,r1
>  #else /* __ARC_EA__ */
>  	abs_s	r2,r1
>  	norm.f	r4,r0
> -- 
> 1.9.1
> 

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

* Re: [PATCH 4/6] [ARC] Rework delegitimate_address hook
  2017-11-02 12:34 ` [PATCH 4/6] [ARC] Rework delegitimate_address hook Claudiu Zissulescu
@ 2018-01-23 23:07   ` Andrew Burgess
  0 siblings, 0 replies; 18+ messages in thread
From: Andrew Burgess @ 2018-01-23 23:07 UTC (permalink / raw)
  To: Claudiu Zissulescu; +Cc: gcc-patches, Francois.Bedard

* Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com> [2017-11-02 13:30:33 +0100]:

> From: claziss <claziss@synopsys.com>
> 
> Delegitimize address is used to undo the obfuscating effect of PIC
> addresses, returning the address in a way which is understood by the
> compiler.
> 
> gcc/
> 2017-04-25  Claudiu Zissulescu  <claziss@synopsys.com>
> 
> 	* config/arc/arc.c (arc_delegitimize_address_0): Refactored to
> 	recognize new pic like addresses.
> 	(arc_delegitimize_address): Clean up.
> 
> testsuite/
> 2017-08-31  Claudiu Zissulescu  <claziss@synopsys.com>
> 
> 	* testsuite/gcc.target/arc/tdelegitimize_addr.c: New test.

Assuming this has passed all of the tests, then this change is fine
with me.

The commit message you propose above describes what delegitimize does
in general, but it doesn't really explain why _this_ change is
needed.  You remove a lot of code, it would be nice if the commit
message explained why we're able to drop all of this complexity.

Thanks,
Andrew



> ---
>  gcc/config/arc/arc.c                              | 91 ++++++++++-------------
>  gcc/testsuite/gcc.target/arc/tdelegitimize_addr.c | 23 ++++++
>  2 files changed, 62 insertions(+), 52 deletions(-)
>  create mode 100755 gcc/testsuite/gcc.target/arc/tdelegitimize_addr.c
> 
> diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
> index e7194a2..07dd072 100644
> --- a/gcc/config/arc/arc.c
> +++ b/gcc/config/arc/arc.c
> @@ -9506,68 +9506,55 @@ arc_legitimize_address (rtx orig_x, rtx oldx, machine_mode mode)
>  }
>  
>  static rtx
> -arc_delegitimize_address_0 (rtx x)
> +arc_delegitimize_address_0 (rtx op)
>  {
> -  rtx u, gp, p;
> -
> -  if (GET_CODE (x) == CONST && GET_CODE (u = XEXP (x, 0)) == UNSPEC)
> +  switch (GET_CODE (op))
>      {
> -      if (XINT (u, 1) == ARC_UNSPEC_GOT
> -	  || XINT (u, 1) == ARC_UNSPEC_GOTOFFPC)
> -	return XVECEXP (u, 0, 0);
> +    case CONST:
> +      return arc_delegitimize_address_0 (XEXP (op, 0));
> +
> +    case UNSPEC:
> +      switch (XINT (op, 1))
> +	{
> +	case ARC_UNSPEC_GOT:
> +	case ARC_UNSPEC_GOTOFFPC:
> +	  return XVECEXP (op, 0, 0);
> +	default:
> +	  break;
> +	}
> +      break;
> +
> +    case PLUS:
> +      {
> +	rtx t1 = arc_delegitimize_address_0 (XEXP (op, 0));
> +	rtx t2 = XEXP (op, 1);
> +
> +	if (t1 && t2)
> +	  return gen_rtx_PLUS (GET_MODE (op), t1, t2);
> +	break;
> +      }
> +
> +    default:
> +      break;
>      }
> -  else if (GET_CODE (x) == CONST && GET_CODE (p = XEXP (x, 0)) == PLUS
> -	   && GET_CODE (u = XEXP (p, 0)) == UNSPEC
> -	   && (XINT (u, 1) == ARC_UNSPEC_GOT
> -	       || XINT (u, 1) == ARC_UNSPEC_GOTOFFPC))
> -    return gen_rtx_CONST
> -	    (GET_MODE (x),
> -	     gen_rtx_PLUS (GET_MODE (p), XVECEXP (u, 0, 0), XEXP (p, 1)));
> -  else if (GET_CODE (x) == PLUS
> -	   && ((REG_P (gp = XEXP (x, 0))
> -		&& REGNO (gp) == PIC_OFFSET_TABLE_REGNUM)
> -	       || (GET_CODE (gp) == CONST
> -		   && GET_CODE (u = XEXP (gp, 0)) == UNSPEC
> -		   && XINT (u, 1) == ARC_UNSPEC_GOT
> -		   && GET_CODE (XVECEXP (u, 0, 0)) == SYMBOL_REF
> -		   && !strcmp (XSTR (XVECEXP (u, 0, 0), 0), "_DYNAMIC")))
> -	   && GET_CODE (XEXP (x, 1)) == CONST
> -	   && GET_CODE (u = XEXP (XEXP (x, 1), 0)) == UNSPEC
> -	   && XINT (u, 1) == ARC_UNSPEC_GOTOFF)
> -    return XVECEXP (u, 0, 0);
> -  else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
> -	   && ((REG_P (gp = XEXP (XEXP (x, 0), 1))
> -		&& REGNO (gp) == PIC_OFFSET_TABLE_REGNUM)
> -	       || (GET_CODE (gp) == CONST
> -		   && GET_CODE (u = XEXP (gp, 0)) == UNSPEC
> -		   && XINT (u, 1) == ARC_UNSPEC_GOT
> -		   && GET_CODE (XVECEXP (u, 0, 0)) == SYMBOL_REF
> -		   && !strcmp (XSTR (XVECEXP (u, 0, 0), 0), "_DYNAMIC")))
> -	   && GET_CODE (XEXP (x, 1)) == CONST
> -	   && GET_CODE (u = XEXP (XEXP (x, 1), 0)) == UNSPEC
> -	   && XINT (u, 1) == ARC_UNSPEC_GOTOFF)
> -    return gen_rtx_PLUS (GET_MODE (x), XEXP (XEXP (x, 0), 0),
> -			 XVECEXP (u, 0, 0));
> -  else if (GET_CODE (x) == PLUS
> -	   && (u = arc_delegitimize_address_0 (XEXP (x, 1))))
> -    return gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0), u);
>    return NULL_RTX;
>  }
>  
>  static rtx
> -arc_delegitimize_address (rtx x)
> +arc_delegitimize_address (rtx orig_x)
>  {
> -  rtx orig_x = x = delegitimize_mem_from_attrs (x);
> -  if (GET_CODE (x) == MEM)
> +  rtx x = orig_x;
> +
> +  if (MEM_P (x))
>      x = XEXP (x, 0);
> +
>    x = arc_delegitimize_address_0 (x);
> -  if (x)
> -    {
> -      if (MEM_P (orig_x))
> -	x = replace_equiv_address_nv (orig_x, x);
> -      return x;
> -    }
> -  return orig_x;
> +  if (!x)
> +    return orig_x;
> +
> +  if (MEM_P (orig_x))
> +    x = replace_equiv_address_nv (orig_x, x);
> +  return x;
>  }
>  
>  /* Return a REG rtx for acc1.  N.B. the gcc-internal representation may
> diff --git a/gcc/testsuite/gcc.target/arc/tdelegitimize_addr.c b/gcc/testsuite/gcc.target/arc/tdelegitimize_addr.c
> new file mode 100755
> index 0000000..0d010ff
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arc/tdelegitimize_addr.c
> @@ -0,0 +1,23 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
> +/* { dg-options "-mcpu=archs -g -O1 -fpic -mlra" } */
> +
> +/* Check if delegitimize address returns correctly the un-obfuscated
> +   address.  */
> +
> +typedef struct {
> +  long long tv_usec;
> +} t_a;
> +
> +static t_a a;
> +
> +int b;
> +extern void fn2 (t_a);
> +
> +void fn1 (void)
> +{
> + again:
> +  fn2(a);
> +  if (b)
> +    goto again;
> +}
> -- 
> 1.9.1
> 

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

* Re: [PATCH 5/6] [ARC] Add 'uncached' attribute.
  2017-11-02 12:34 ` [PATCH 5/6] [ARC] Add 'uncached' attribute Claudiu Zissulescu
  2017-11-03  2:26   ` Sandra Loosemore
@ 2018-01-29 20:23   ` Andrew Burgess
  1 sibling, 0 replies; 18+ messages in thread
From: Andrew Burgess @ 2018-01-29 20:23 UTC (permalink / raw)
  To: Claudiu Zissulescu; +Cc: gcc-patches, Francois.Bedard

* Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com> [2017-11-02 13:30:34 +0100]:

> From: claziss <claziss@synopsys.com>
> 
> The _Uncached type qualifier can be used to bypass the cache without
> resorting to declaring variables as volatile.
> 
> gcc/
> 2017-07-12  Claudiu Zissulescu  <claziss@synopsys.com>
> 
> 	* config/arc/arc-protos.h (arc_is_uncached_mem_p): Function proto.
> 	* config/arc/arc.c (arc_handle_uncached_attribute): New function.
> 	(arc_attribute_table): Add 'uncached' attribute.
> 	(arc_print_operand): Print '.di' flag for uncached memory
> 	accesses.
> 	(arc_in_small_data_p): Do not consider for small data the uncached
> 	types.
> 	(arc_is_uncached_mem_p): New function.
> 	* config/arc/predicates.md (compact_store_memory_operand): Check
> 	for uncached memory accesses.
> 	(nonvol_nonimm_operand): Likewise.
> 
> gcc/testsuite
> 2017-07-12  Claudiu Zissulescu  <claziss@synopsys.com>

Looks good, with the updated documentation.

Thanks,
Andrew


> 
> 	* gcc.target/arc/uncached.c: New test.
> ---
>  gcc/config/arc/arc-protos.h             |  1 +
>  gcc/config/arc/arc.c                    | 65 ++++++++++++++++++++++++++++++++-
>  gcc/config/arc/predicates.md            |  7 +++-
>  gcc/testsuite/gcc.target/arc/uncached.c | 18 +++++++++
>  4 files changed, 88 insertions(+), 3 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/arc/uncached.c
> 
> diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h
> index f8e7937..cc00730 100644
> --- a/gcc/config/arc/arc-protos.h
> +++ b/gcc/config/arc/arc-protos.h
> @@ -47,6 +47,7 @@ extern void arc_expand_compare_and_swap (rtx *);
>  extern bool compact_memory_operand_p (rtx, machine_mode, bool, bool);
>  extern int arc_return_address_register (unsigned int);
>  extern unsigned int arc_compute_function_type (struct function *);
> +extern bool arc_is_uncached_mem_p (rtx);
>  #endif /* RTX_CODE */
>  
>  extern unsigned int arc_compute_frame_size (int);
> diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
> index 07dd072..a397cbd 100644
> --- a/gcc/config/arc/arc.c
> +++ b/gcc/config/arc/arc.c
> @@ -222,7 +222,7 @@ static tree arc_handle_interrupt_attribute (tree *, tree, tree, int, bool *);
>  static tree arc_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
>  static tree arc_handle_jli_attribute (tree *, tree, tree, int, bool *);
>  static tree arc_handle_secure_attribute (tree *, tree, tree, int, bool *);
> -
> +static tree arc_handle_uncached_attribute (tree *, tree, tree, int, bool *);
>  
>  /* Initialized arc_attribute_table to NULL since arc doesnot have any
>     machine specific supported attributes.  */
> @@ -254,6 +254,9 @@ const struct attribute_spec arc_attribute_table[] =
>    /* Call a function using secure-mode.  */
>    { "secure_call",  1, 1, false, true, true, arc_handle_secure_attribute,
>      false },
> +  /* Bypass caches using .di flag.  */
> +  { "uncached", 0, 0, false, true, false, arc_handle_uncached_attribute,
> +    false },
>    { NULL, 0, 0, false, false, false, NULL, false }
>  };
>  static int arc_comp_type_attributes (const_tree, const_tree);
> @@ -4135,7 +4138,8 @@ arc_print_operand (FILE *file, rtx x, int code)
>  	 refs are defined to use the cache bypass mechanism.  */
>        if (GET_CODE (x) == MEM)
>  	{
> -	  if (MEM_VOLATILE_P (x) && !TARGET_VOLATILE_CACHE_SET )
> +	  if ((MEM_VOLATILE_P (x) && !TARGET_VOLATILE_CACHE_SET)
> +	      || arc_is_uncached_mem_p (x))
>  	    fputs (".di", file);
>  	}
>        else
> @@ -8038,6 +8042,7 @@ static bool
>  arc_in_small_data_p (const_tree decl)
>  {
>    HOST_WIDE_INT size;
> +  tree attr;
>  
>    /* Only variables are going into small data area.  */
>    if (TREE_CODE (decl) != VAR_DECL)
> @@ -8061,6 +8066,11 @@ arc_in_small_data_p (const_tree decl)
>        && TREE_THIS_VOLATILE (decl))
>      return false;
>  
> +  /* Likewise for uncached data.  */
> +  attr = TYPE_ATTRIBUTES (TREE_TYPE (decl));
> +  if (lookup_attribute ("uncached", attr))
> +    return false;
> +
>    if (DECL_SECTION_NAME (decl) != 0)
>      {
>        const char *name = DECL_SECTION_NAME (decl);
> @@ -11066,6 +11076,57 @@ arc_is_secure_call_p (rtx pat)
>    return false;
>  }
>  
> +/* Handle "uncached" qualifier.  */
> +
> +static tree
> +arc_handle_uncached_attribute (tree *node,
> +			       tree name, tree args,
> +			       int flags ATTRIBUTE_UNUSED,
> +			       bool *no_add_attrs)
> +{
> +  if (DECL_P (*node) && TREE_CODE (*node) != TYPE_DECL)
> +    {
> +      error ("%qE attribute only applies to types",
> +	     name);
> +      *no_add_attrs = true;
> +    }
> +  else if (args)
> +    {
> +      warning (OPT_Wattributes, "argument of %qE attribute ignored", name);
> +    }
> +  return NULL_TREE;
> +}
> +
> +/* Return TRUE if PAT is a memory addressing an uncached data.  */
> +
> +bool
> +arc_is_uncached_mem_p (rtx pat)
> +{
> +  tree attrs;
> +  tree ttype;
> +  struct mem_attrs *refattrs;
> +
> +  if (!MEM_P (pat))
> +    return false;
> +
> +  /* Get the memory attributes.  */
> +  refattrs = MEM_ATTRS (pat);
> +  if (!refattrs
> +      || !refattrs->expr)
> +    return false;
> +
> +  /* Get the type declaration.  */
> +  ttype = TREE_TYPE (refattrs->expr);
> +  if (!ttype)
> +    return false;
> +
> +  /* Get the type attributes.  */
> +  attrs = TYPE_ATTRIBUTES (ttype);
> +  if (lookup_attribute ("uncached", attrs))
> +    return true;
> +  return false;
> +}
> +
>  /* Implement TARGET_USE_ANCHORS_FOR_SYMBOL_P.  We don't want to use
>     anchors for small data: the GP register acts as an anchor in that
>     case.  We also don't want to use them for PC-relative accesses,
> diff --git a/gcc/config/arc/predicates.md b/gcc/config/arc/predicates.md
> index 3dfe0ca..68887be 100644
> --- a/gcc/config/arc/predicates.md
> +++ b/gcc/config/arc/predicates.md
> @@ -217,6 +217,10 @@
>    if (MEM_VOLATILE_P (op) && !TARGET_VOLATILE_CACHE_SET)
>       return 0;
>  
> +  /* likewise for uncached types.  */
> +  if (arc_is_uncached_mem_p (op))
> +     return 0;
> +
>    size = GET_MODE_SIZE (mode);
>  
>    /* dword operations really put out 2 instructions, so eliminate them.  */
> @@ -412,7 +416,8 @@
>  ;; and only the standard movXX patterns are set up to handle them.
>  (define_predicate "nonvol_nonimm_operand"
>    (and (match_code "subreg, reg, mem")
> -       (match_test "(GET_CODE (op) != MEM || !MEM_VOLATILE_P (op)) && nonimmediate_operand (op, mode)"))
> +       (match_test "(GET_CODE (op) != MEM || !MEM_VOLATILE_P (op)) && nonimmediate_operand (op, mode)")
> +       (match_test "!arc_is_uncached_mem_p (op)"))
>  )
>  
>  ;; Return 1 if OP is a comparison operator valid for the mode of CC.
> diff --git a/gcc/testsuite/gcc.target/arc/uncached.c b/gcc/testsuite/gcc.target/arc/uncached.c
> new file mode 100644
> index 0000000..367e8dc
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arc/uncached.c
> @@ -0,0 +1,18 @@
> +/* { dg-do compile } */
> +
> +/* Check 'uncached' type attribute.  */
> +
> +typedef volatile unsigned int RwReg  __attribute__ ((uncached));
> +
> +typedef struct {
> +  RwReg UART_THR;
> +  int SIDE_DISH;
> +} UART;
> +
> +void uart_putc(UART *port, char c)
> +{
> +    port->UART_THR = c;
> +    port->SIDE_DISH = c;
> +}
> +
> +/* { dg-final { scan-assembler-times "st\.di" 1 } } */
> -- 
> 1.9.1
> 

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

* Re: [PATCH 6/6] [ARC] Add 'aux' variable attribute.
  2017-11-02 12:34 ` [PATCH 6/6] [ARC] Add 'aux' variable attribute Claudiu Zissulescu
@ 2018-01-29 20:28   ` Andrew Burgess
  0 siblings, 0 replies; 18+ messages in thread
From: Andrew Burgess @ 2018-01-29 20:28 UTC (permalink / raw)
  To: Claudiu Zissulescu; +Cc: gcc-patches, Francois.Bedard

* Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com> [2017-11-02 13:30:35 +0100]:

> From: claziss <claziss@synopsys.com>
> 
> The 'aux' variable attribute is used to directly access the auxiliary
> register space from C.
> 
> gcc/
> 2017-07-25  Claudiu Zissulescu  <claziss@synopsys.com>
> 
> 	* config/arc/arc.c (arc_handle_aux_attribute): New function.
> 	(arc_attribute_table): Add 'aux' attribute.
> 	(arc_in_small_data_p): Consider aux like variables.
> 	(arc_is_aux_reg_p): New function.
> 	(arc_asm_output_aligned_decl_local): Ignore 'aux' like variables.
> 	(arc_get_aux_arg): New function.
> 	(prepare_move_operands): Handle aux-register access.
> 	(arc_handle_aux_attribute): New function.
> 	* doc/extend.texi (ARC Variable attributes): Add subsection.
> 
> testsuite/
> 2017-07-25  Claudiu Zissulescu  <claziss@synopsys.com>
> 
> 	* gcc.target/arc/taux-1.c: New test.
> 	* gcc.target/arc/taux-2.c: Likewise.

Looks good.

Sorry for the time taken to review this series.

Thanks,
Andrew


> ---
>  gcc/config/arc/arc.c                  | 160 +++++++++++++++++++++++++++++++++-
>  gcc/doc/extend.texi                   |  13 +++
>  gcc/testsuite/gcc.target/arc/taux-1.c |  38 ++++++++
>  gcc/testsuite/gcc.target/arc/taux-2.c |  15 ++++
>  4 files changed, 225 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/gcc.target/arc/taux-1.c
>  create mode 100644 gcc/testsuite/gcc.target/arc/taux-2.c
> 
> diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
> index a397cbd..33f68ef 100644
> --- a/gcc/config/arc/arc.c
> +++ b/gcc/config/arc/arc.c
> @@ -223,6 +223,7 @@ static tree arc_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
>  static tree arc_handle_jli_attribute (tree *, tree, tree, int, bool *);
>  static tree arc_handle_secure_attribute (tree *, tree, tree, int, bool *);
>  static tree arc_handle_uncached_attribute (tree *, tree, tree, int, bool *);
> +static tree arc_handle_aux_attribute (tree *, tree, tree, int, bool *);
>  
>  /* Initialized arc_attribute_table to NULL since arc doesnot have any
>     machine specific supported attributes.  */
> @@ -257,6 +258,8 @@ const struct attribute_spec arc_attribute_table[] =
>    /* Bypass caches using .di flag.  */
>    { "uncached", 0, 0, false, true, false, arc_handle_uncached_attribute,
>      false },
> +  /* Declare a variable as aux.  */
> +  { "aux", 0, 1, true, false, false, arc_handle_aux_attribute, false },
>    { NULL, 0, 0, false, false, false, NULL, false }
>  };
>  static int arc_comp_type_attributes (const_tree, const_tree);
> @@ -8071,6 +8074,11 @@ arc_in_small_data_p (const_tree decl)
>    if (lookup_attribute ("uncached", attr))
>      return false;
>  
> +  /* and for aux regs.  */
> +  attr = DECL_ATTRIBUTES (decl);
> +  if (lookup_attribute ("aux", attr))
> +    return false;
> +
>    if (DECL_SECTION_NAME (decl) != 0)
>      {
>        const char *name = DECL_SECTION_NAME (decl);
> @@ -8238,6 +8246,35 @@ compact_sda_memory_operand (rtx op, machine_mode mode, bool short_p)
>    return false;
>  }
>  
> +/* Return TRUE if PAT is accessing an aux-reg.  */
> +
> +static bool
> +arc_is_aux_reg_p (rtx pat)
> +{
> +  tree attrs = NULL_TREE;
> +  tree addr;
> +
> +  if (!MEM_P (pat))
> +    return false;
> +
> +  /* Get the memory attributes.  */
> +  addr = MEM_EXPR (pat);
> +  if (!addr)
> +    return false;
> +
> +  /* Get the attributes.  */
> +  if (TREE_CODE (addr) == VAR_DECL)
> +    attrs = DECL_ATTRIBUTES (addr);
> +  else if (TREE_CODE (addr) == MEM_REF)
> +    attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 0)));
> +  else
> +    return false;
> +
> +  if (lookup_attribute ("aux", attrs))
> +    return true;
> +  return false;
> +}
> +
>  /* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL.  */
>  
>  void
> @@ -8246,7 +8283,14 @@ arc_asm_output_aligned_decl_local (FILE * stream, tree decl, const char * name,
>  				   unsigned HOST_WIDE_INT align,
>  				   unsigned HOST_WIDE_INT globalize_p)
>  {
> -  int in_small_data =   arc_in_small_data_p (decl);
> +  int in_small_data = arc_in_small_data_p (decl);
> +  rtx mem = decl == NULL_TREE ? NULL_RTX : DECL_RTL (decl);
> +
> +  /* Don't output aux-reg symbols.  */
> +  if (mem != NULL_RTX && MEM_P (mem)
> +      && SYMBOL_REF_P (XEXP (mem, 0))
> +      && arc_is_aux_reg_p (mem))
> +    return;
>  
>    if (in_small_data)
>      switch_to_section (get_named_section (NULL, ".sbss", 0));
> @@ -8586,12 +8630,80 @@ arc_expand_movmem (rtx *operands)
>    return true;
>  }
>  
> +static bool
> +arc_get_aux_arg (rtx pat, int *auxr)
> +{
> +  tree attr, addr = MEM_EXPR (pat);
> +  if (TREE_CODE (addr) != VAR_DECL)
> +    return false;
> +
> +  attr = DECL_ATTRIBUTES (addr);
> +  if (lookup_attribute ("aux", attr))
> +    {
> +      tree arg = TREE_VALUE (attr);
> +      if (arg)
> +	{
> +	  *auxr = TREE_INT_CST_LOW (TREE_VALUE (arg));
> +	  return true;
> +	}
> +    }
> +
> +  return false;
> +}
> +
>  /* Prepare operands for move in MODE.  Return true iff the move has
>     been emitted.  */
>  
>  bool
>  prepare_move_operands (rtx *operands, machine_mode mode)
>  {
> +  /* First handle aux attribute.  */
> +  if (mode == SImode
> +      && (MEM_P (operands[0]) || MEM_P (operands[1])))
> +    {
> +      rtx tmp;
> +      int auxr = 0;
> +      if (MEM_P (operands[0]) && arc_is_aux_reg_p (operands[0]))
> +	{
> +	  /* Save operation.  */
> +	  if (arc_get_aux_arg (operands[0], &auxr))
> +	    {
> +	      tmp = gen_reg_rtx (SImode);
> +	      emit_move_insn (tmp, GEN_INT (auxr));
> +	    }
> +	  else
> +	    {
> +	      tmp = XEXP (operands[0], 0);
> +	    }
> +
> +	  operands[1] = force_reg (SImode, operands[1]);
> +	  emit_insn (gen_rtx_UNSPEC_VOLATILE
> +		     (VOIDmode, gen_rtvec (2, operands[1], tmp),
> +		      VUNSPEC_ARC_SR));
> +	  return true;
> +	}
> +      if (MEM_P (operands[1]) && arc_is_aux_reg_p (operands[1]))
> +	{
> +	  if (arc_get_aux_arg (operands[1], &auxr))
> +	    {
> +	      tmp = gen_reg_rtx (SImode);
> +	      emit_move_insn (tmp, GEN_INT (auxr));
> +	    }
> +	  else
> +	    {
> +	      tmp = XEXP (operands[1], 0);
> +	      gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
> +	    }
> +	  /* Load operation.  */
> +	  gcc_assert (REG_P (operands[0]));
> +	  emit_insn (gen_rtx_SET (operands[0],
> +				  gen_rtx_UNSPEC_VOLATILE
> +				  (SImode, gen_rtvec (1, tmp),
> +				   VUNSPEC_ARC_LR)));
> +	  return true;
> +	}
> +    }
> +
>    /* We used to do this only for MODE_INT Modes, but addresses to floating
>       point variables may well be in the small data section.  */
>    if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[0], Pmode))
> @@ -11127,6 +11239,52 @@ arc_is_uncached_mem_p (rtx pat)
>    return false;
>  }
>  
> +/* Handle aux attribute.  The auxiliary registers are addressed using
> +   special instructions lr and sr.  The attribute 'aux' indicates if a
> +   variable refers to the aux-regs and what is the register number
> +   desired.  */
> +
> +static tree
> +arc_handle_aux_attribute (tree *node,
> +			  tree name, tree args, int,
> +			  bool *no_add_attrs)
> +{
> +  /* Isn't it better to use address spaces for the aux-regs?  */
> +  if (DECL_P (*node))
> +    {
> +      if (TREE_CODE (*node) != VAR_DECL)
> +	{
> +	  error ("%qE attribute only applies to variables",  name);
> +	  *no_add_attrs = true;
> +	}
> +      else if (args)
> +	{
> +	  if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
> +	    TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
> +	  tree arg = TREE_VALUE (args);
> +	  if (TREE_CODE (arg) != INTEGER_CST)
> +	    {
> +	      warning (0, "%qE attribute allows only an integer "
> +		       "constant argument", name);
> +	      *no_add_attrs = true;
> +	    }
> +	  /* FIXME! add range check.  TREE_INT_CST_LOW (arg) */
> +	}
> +
> +      if (TREE_CODE (*node) == VAR_DECL)
> +	{
> +	  tree fntype = TREE_TYPE (*node);
> +	  if (fntype && TREE_CODE (fntype) == POINTER_TYPE)
> +	    {
> +	      tree attrs = tree_cons (get_identifier ("aux"), NULL_TREE,
> +				      TYPE_ATTRIBUTES (fntype));
> +	      TYPE_ATTRIBUTES (fntype) = attrs;
> +	    }
> +	}
> +    }
> +  return NULL_TREE;
> +}
> +
>  /* Implement TARGET_USE_ANCHORS_FOR_SYMBOL_P.  We don't want to use
>     anchors for small data: the GP register acts as an anchor in that
>     case.  We also don't want to use them for PC-relative accesses,
> diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
> index 0f8ba05..1f6ef4e 100644
> --- a/gcc/doc/extend.texi
> +++ b/gcc/doc/extend.texi
> @@ -5803,6 +5803,7 @@ attributes.
>  
>  @menu
>  * Common Variable Attributes::
> +* ARC Variable Attributes::
>  * AVR Variable Attributes::
>  * Blackfin Variable Attributes::
>  * H8/300 Variable Attributes::
> @@ -6165,6 +6166,18 @@ The @code{weak} attribute is described in
>  
>  @end table
>  
> +@node ARC Variable Attributes
> +@subsection ARC Variable Attributes
> +
> +@table @code
> +@item aux
> +@cindex @code{aux} variable attribute, ARC
> +The @code{aux} attribute is used to directly access the ARC's
> +auxiliary register space from C.  The auxilirary register number is
> +given via attribute argument.
> +
> +@end table
> +
>  @node AVR Variable Attributes
>  @subsection AVR Variable Attributes
>  
> diff --git a/gcc/testsuite/gcc.target/arc/taux-1.c b/gcc/testsuite/gcc.target/arc/taux-1.c
> new file mode 100644
> index 0000000..a2b7778
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arc/taux-1.c
> @@ -0,0 +1,38 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O1 */
> +
> +
> +#define __aux() __attribute__((aux))
> +
> +__aux() int *a_ptr;
> +extern __aux() int a_var;
> +
> +/* Generates:
> +   mov r0, @a_var
> +   sr  10,[r0]
> +*/
> +void foo (void)
> +{
> +  a_var = 10;
> +}
> +
> +/* Generates:
> +   mov r0, @a_ptr
> +   sr  a_var,[r0]
> +*/
> +void foo1 (void)
> +{
> +  a_ptr = &a_var;
> +}
> +
> +/* Generates:
> +   lr  %r1,[a_ptr]
> +   sr  10,[%r1]
> +*/
> +void foo2 (void)
> +{
> +  *a_ptr = 10;
> +}
> +
> +/* { dg-final { scan-assembler-times "sr" 3 } } */
> +/* { dg-final { scan-assembler-times "lr" 1 } } */
> diff --git a/gcc/testsuite/gcc.target/arc/taux-2.c b/gcc/testsuite/gcc.target/arc/taux-2.c
> new file mode 100644
> index 0000000..5644bcd
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arc/taux-2.c
> @@ -0,0 +1,15 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O1 */
> +
> +#define __aux(r) __attribute__((aux(r)))
> +static volatile __aux(0x1000) int var;
> +
> +int foo (void)
> +{
> +  var++;
> +}
> +
> +/* { dg-final { scan-assembler-times "sr" 1 } } */
> +/* { dg-final { scan-assembler-times "lr" 1 } } */
> +/* { dg-final { scan-assembler "4096" } } */
> +/* { dg-final { scan-assembler-not "\\.type\tvar, @object" } } */
> -- 
> 1.9.1
> 

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

* RE: [PATCH 0/6] [ARC] New baremetal features and fixes
  2017-11-02 12:34 [PATCH 0/6] [ARC] New baremetal features and fixes Claudiu Zissulescu
                   ` (5 preceding siblings ...)
  2017-11-02 12:34 ` [PATCH 5/6] [ARC] Add 'uncached' attribute Claudiu Zissulescu
@ 2018-02-01 10:10 ` Claudiu Zissulescu
  6 siblings, 0 replies; 18+ messages in thread
From: Claudiu Zissulescu @ 2018-02-01 10:10 UTC (permalink / raw)
  To: gcc-patches; +Cc: Francois.Bedard, andrew.burgess

>   [ARC] Add JLI support.
>   [ARC] Add SJLI support.
>   [ARC] Add support for "register file 16" reduced register set
>   [ARC] Rework delegitimate_address hook
>   [ARC] Add 'uncached' attribute.
>   [ARC] Add 'aux' variable attribute.

Thank you all for reviewing them.

//Claudiu

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

end of thread, other threads:[~2018-02-01 10:10 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-02 12:34 [PATCH 0/6] [ARC] New baremetal features and fixes Claudiu Zissulescu
2017-11-02 12:34 ` [PATCH 1/6] [ARC] Add JLI support Claudiu Zissulescu
2018-01-16 10:20   ` Andrew Burgess
2017-11-02 12:34 ` [PATCH 4/6] [ARC] Rework delegitimate_address hook Claudiu Zissulescu
2018-01-23 23:07   ` Andrew Burgess
2017-11-02 12:34 ` [PATCH 6/6] [ARC] Add 'aux' variable attribute Claudiu Zissulescu
2018-01-29 20:28   ` Andrew Burgess
2017-11-02 12:34 ` [PATCH 3/6] [ARC] Add support for "register file 16" reduced register set Claudiu Zissulescu
2018-01-16 10:52   ` Andrew Burgess
2017-11-02 12:34 ` [PATCH 2/6] [ARC] Add SJLI support Claudiu Zissulescu
2018-01-16 10:37   ` Andrew Burgess
2017-11-02 12:34 ` [PATCH 5/6] [ARC] Add 'uncached' attribute Claudiu Zissulescu
2017-11-03  2:26   ` Sandra Loosemore
2017-11-03 11:24     ` Claudiu Zissulescu
2017-11-03 18:55       ` Sandra Loosemore
2017-11-09  9:13         ` Claudiu Zissulescu
2018-01-29 20:23   ` Andrew Burgess
2018-02-01 10:10 ` [PATCH 0/6] [ARC] New baremetal features and fixes Claudiu Zissulescu

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).