diff mbox series

[3/6,ARC] Add support for "register file 16" reduced register set

Message ID 1509625835-22344-4-git-send-email-claziss@synopsys.com
State New
Headers show
Series New baremetal features and fixes | expand

Commit Message

Claudiu Zissulescu Nov. 2, 2017, 12:30 p.m. UTC
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(-)

Comments

Andrew Burgess Jan. 16, 2018, 10:51 a.m. UTC | #1
* 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
>
diff mbox series

Patch

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