This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH 3/6] [ARC] Add BI/BIH instruction support.


* Claudiu Zissulescu <claziss@gmail.com> [2018-10-10 11:00:13 +0300]:

> Use BI/BIH instruction to implement casesi pattern. Only ARC V2.

This removes the compact-casesi as an option for earlier ARC, right?
Was there a reason why that had to be done?

> 
> gcc/
> 2018-03-21  Claudiu Zissulescu  <claziss@synopsys.com>
> 
> 	* config/arc/arc.c (arc_override_options): Remove
> 	TARGET_COMPACT_CASESI.
> 	* config/arc/arc.h (ASM_OUTPUT_ADDR_DIFF_ELT): Update.
> 	(CASE_VECTOR_MODE): Likewise.
> 	(CASE_VECTOR_PC_RELATIVE): Likewise.
> 	(CASE_VECTOR_SHORTEN_MODE): Likewise.
> 	(CASE_VECTOR_SHORTEN_MODE1): Delete.
> 	(ADDR_VEC_ALIGN): Update.
> 	(ASM_OUTPUT_CASE_LABEL): Undefine.
> 	(ASM_OUTPUT_BEFORE_CASE_LABEL): Undefine.
> 	(TARGET_BI_BIH): Define.
> 	(DEFAULT_BRANCH_INDEX): Likewise.
> 	* config/arc/arc.md (casesi): Rework to accept BI/BIH
> 	instructions, remove compact_casesi use case.
> 	(casesi_compact_jump): Remove.
> 	(casesi_dispatch): New pattern.
> 	* config/arc/arc.opt: Add mbranch-index option. Deprecate
> 	compact_casesi option.
> 	* doc/invoke.texi: Document mbranch-index option.

I guess if you feel that dropping compact-casesi support for earlier
targets is appropriate, then that's fine.  There's some formatting
issues I point out below.  But otherwise seems reasonable.

Thanks,
Andrew

> 
> gcc/testsuite
> Claudiu Zissulescu  <claziss@synopsys.com>
> 
> 	* gcc.target/arc/jumptable.c: New test.
> ---
>  gcc/config/arc/arc.c                     |  19 --
>  gcc/config/arc/arc.h                     | 106 ++++++-----
>  gcc/config/arc/arc.md                    | 218 +++++++----------------
>  gcc/config/arc/arc.opt                   |   6 +-
>  gcc/doc/invoke.texi                      |   9 +-
>  gcc/testsuite/gcc.target/arc/jumptable.c |  34 ++++
>  6 files changed, 171 insertions(+), 221 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/arc/jumptable.c
> 
> diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
> index 56f566795ff..18dd0de6af7 100644
> --- a/gcc/config/arc/arc.c
> +++ b/gcc/config/arc/arc.c
> @@ -1291,33 +1291,14 @@ arc_override_options (void)
>    if (arc_size_opt_level == 3)
>      optimize_size = 1;
>  
> -  /* Compact casesi is not a valid option for ARCv2 family.  */
> -  if (TARGET_V2)
> -    {
> -      if (TARGET_COMPACT_CASESI)
> -	{
> -	  warning (OPT_mcompact_casesi,
> -		   "compact-casesi is not applicable to ARCv2");
> -	  TARGET_COMPACT_CASESI = 0;
> -	}
> -    }
> -  else if (optimize_size == 1
> -	   && !global_options_set.x_TARGET_COMPACT_CASESI)
> -    TARGET_COMPACT_CASESI = 1;
> -
>    if (flag_pic)
>      target_flags |= MASK_NO_SDATA_SET;
>  
>    if (flag_no_common == 255)
>      flag_no_common = !TARGET_NO_SDATA_SET;
>  
> -  /* TARGET_COMPACT_CASESI needs the "q" register class.  */
>    if (TARGET_MIXED_CODE)
>      TARGET_Q_CLASS = 1;
> -  if (!TARGET_Q_CLASS)
> -    TARGET_COMPACT_CASESI = 0;
> -  if (TARGET_COMPACT_CASESI)
> -    TARGET_CASE_VECTOR_PC_RELATIVE = 1;
>  
>    /* Check for small data option */
>    if (!global_options_set.x_g_switch_value && !TARGET_NO_SDATA_SET)
> diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
> index dd78a6bbbd1..cb48b85d6e7 100644
> --- a/gcc/config/arc/arc.h
> +++ b/gcc/config/arc/arc.h
> @@ -1264,25 +1264,39 @@ do {							\
>  } while (0)
>  
>  /* This is how to output an element of a case-vector that is relative.  */
> -#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
> -do {							\
> -  char label[30];					\
> -  ASM_GENERATE_INTERNAL_LABEL (label, "L", VALUE);	\
> -  switch (GET_MODE (BODY))				\
> -    {							\
> -    case E_QImode: fprintf (FILE, "\t.byte "); break;	\
> -    case E_HImode: fprintf (FILE, "\t.hword "); break;	\
> -    case E_SImode: fprintf (FILE, "\t.word "); break;	\
> -    default: gcc_unreachable ();			\
> -    }							\
> -  assemble_name (FILE, label);				\
> -  fprintf (FILE, "-");					\
> -  ASM_GENERATE_INTERNAL_LABEL (label, "L", REL);	\
> -  assemble_name (FILE, label);				\
> -  if (TARGET_COMPACT_CASESI)				\
> -    fprintf (FILE, " + %d", 4 + arc_get_unalign ());	\
> -  fprintf(FILE, "\n");                                  \
> -} while (0)
> +#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL)	\
> +  do {								\
> +    char label[30];						\
> +    ASM_GENERATE_INTERNAL_LABEL (label, "L", VALUE);		\
> +    if (!TARGET_BI_BIH)						\
> +      {								\
> +	switch (GET_MODE (BODY))				\
> +	  {							\
> +	  case E_QImode: fprintf (FILE, "\t.byte "); break;	\
> +	  case E_HImode: fprintf (FILE, "\t.hword "); break;	\
> +	  case E_SImode: fprintf (FILE, "\t.word "); break;	\
> +	  default: gcc_unreachable ();				\
> +	  }							\
> +	assemble_name (FILE, label);				\
> +	fprintf (FILE, "-");					\
> +	ASM_GENERATE_INTERNAL_LABEL (label, "L", REL);		\
> +	assemble_name (FILE, label);				\
> +	fprintf(FILE, "\n");					\

Missing whitespace before (.

> +      } else {							\

Split the '} else {' over separate lines.

> +      switch (GET_MODE (BODY))					\
> +	{							\
> +	case E_SImode: fprintf (FILE, "\tb\t@"); break;		\
> +	case E_HImode:						\
> +	case E_QImode: fprintf (FILE, "\tb_s\t@"); break;	\
> +	default: gcc_unreachable ();				\
> +	}							\
> +      assemble_name (FILE, label);				\
> +      fprintf(FILE, "\n");					\

Missing whitespace before (.

> +    }								\
> +  } while (0)
> +
> +/* Defined to also emit an .align in elfos.h.  We don't want that.  */
> +#undef ASM_OUTPUT_CASE_LABEL
>  
>  /* ADDR_DIFF_VECs are in the text section and thus can affect the
>     current alignment.  */
> @@ -1380,36 +1394,34 @@ do { \
>     for the index in the tablejump instruction.
>     If we have pc relative case vectors, we start the case vector shortening
>     with QImode.  */
> -#define CASE_VECTOR_MODE \
> -  ((optimize && (CASE_VECTOR_PC_RELATIVE || flag_pic)) ? QImode : Pmode)
> +#define CASE_VECTOR_MODE						\
> +  (TARGET_BI_BIH ? SImode						\
> +   : (optimize && (CASE_VECTOR_PC_RELATIVE || flag_pic)) ? QImode : Pmode)
>  
>  /* Define as C expression which evaluates to nonzero if the tablejump
>     instruction expects the table to contain offsets from the address of the
>     table.
>     Do not define this if the table should contain absolute addresses.  */
> -#define CASE_VECTOR_PC_RELATIVE TARGET_CASE_VECTOR_PC_RELATIVE
> -
> -#define CASE_VECTOR_SHORTEN_MODE(MIN_OFFSET, MAX_OFFSET, BODY) \
> -  CASE_VECTOR_SHORTEN_MODE_1 \
> -    (MIN_OFFSET, TARGET_COMPACT_CASESI ? MAX_OFFSET + 6 : MAX_OFFSET, BODY)
> -
> -#define CASE_VECTOR_SHORTEN_MODE_1(MIN_OFFSET, MAX_OFFSET, BODY) \
> -((MIN_OFFSET) >= 0 && (MAX_OFFSET) <= 255 \
> - ? (ADDR_DIFF_VEC_FLAGS (BODY).offset_unsigned = 1, QImode) \
> - : (MIN_OFFSET) >= -128 && (MAX_OFFSET) <= 127 \
> - ? (ADDR_DIFF_VEC_FLAGS (BODY).offset_unsigned = 0, QImode) \
> - : (MIN_OFFSET) >= 0 && (MAX_OFFSET) <= 65535 \
> - ? (ADDR_DIFF_VEC_FLAGS (BODY).offset_unsigned = 1, HImode) \
> - : (MIN_OFFSET) >= -32768 && (MAX_OFFSET) <= 32767 \
> - ? (ADDR_DIFF_VEC_FLAGS (BODY).offset_unsigned = 0, HImode) \
> - : SImode)
> -
> -#define ADDR_VEC_ALIGN(VEC_INSN) \
> -  (exact_log2 (GET_MODE_SIZE (as_a <scalar_int_mode> \
> -			      (GET_MODE (PATTERN (VEC_INSN))))))
> -#undef ASM_OUTPUT_BEFORE_CASE_LABEL
> -#define ASM_OUTPUT_BEFORE_CASE_LABEL(FILE, PREFIX, NUM, TABLE) \
> -  ASM_OUTPUT_ALIGN ((FILE), ADDR_VEC_ALIGN (TABLE))
> +#define CASE_VECTOR_PC_RELATIVE					\
> +  (TARGET_CASE_VECTOR_PC_RELATIVE || TARGET_BI_BIH)
> +
> +#define CASE_VECTOR_SHORTEN_MODE(MIN_OFFSET, MAX_OFFSET, BODY)		\
> +  (TARGET_BI_BIH ?						\
> +   ((MIN_OFFSET) >= -512 && (MAX_OFFSET) <= 508 ? HImode : SImode)	\
> +   : ((MIN_OFFSET) >= 0 && (MAX_OFFSET) <= 255				\
> +      ? (ADDR_DIFF_VEC_FLAGS (BODY).offset_unsigned = 1, QImode)	\
> +      : (MIN_OFFSET) >= -128 && (MAX_OFFSET) <= 127			\
> +      ? (ADDR_DIFF_VEC_FLAGS (BODY).offset_unsigned = 0, QImode)	\
> +      : (MIN_OFFSET) >= 0 && (MAX_OFFSET) <= 65535			\
> +      ? (ADDR_DIFF_VEC_FLAGS (BODY).offset_unsigned = 1, HImode)	\
> +      : (MIN_OFFSET) >= -32768 && (MAX_OFFSET) <= 32767			\
> +      ? (ADDR_DIFF_VEC_FLAGS (BODY).offset_unsigned = 0, HImode)	\
> +      : SImode))
> +
> +#define ADDR_VEC_ALIGN(VEC_INSN)					\
> +  (TARGET_BI_BIH ? 0							\
> +   : exact_log2 (GET_MODE_SIZE (as_a <scalar_int_mode>			\
> +				(GET_MODE (PATTERN (VEC_INSN))))))
>  
>  #define INSN_LENGTH_ALIGNMENT(INSN)		  \
>    ((JUMP_TABLE_DATA_P (INSN)			  \
> @@ -1636,4 +1648,10 @@ enum
>  #define TARGET_LRA arc_lra_p()
>  #endif
>  
> +/* BI/BIH feature macro.  */
> +#define TARGET_BI_BIH (TARGET_BRANCH_INDEX && TARGET_CODE_DENSITY)
> +
> +/* The default option for BI/BIH instructions.  */
> +#define DEFAULT_BRANCH_INDEX 0
> +
>  #endif /* GCC_ARC_H */
> diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
> index 6ea67791627..1ed230fa5f0 100644
> --- a/gcc/config/arc/arc.md
> +++ b/gcc/config/arc/arc.md
> @@ -3968,60 +3968,72 @@ archs4x, archs4xd, archs4xd_slow"
>     (set_attr "cond" "canuse,canuse_limm,canuse,canuse,canuse")])
>  
>  ;; Implement a switch statement.
> -
>  (define_expand "casesi"
> -  [(set (match_dup 5)
> -	(minus:SI (match_operand:SI 0 "register_operand" "")
> -		  (match_operand:SI 1 "nonmemory_operand" "")))
> -   (set (reg:CC CC_REG)
> -	(compare:CC (match_dup 5)
> -		    (match_operand:SI 2 "nonmemory_operand" "")))
> -   (set (pc)
> -	(if_then_else (gtu (reg:CC CC_REG)
> -			   (const_int 0))
> -		      (label_ref (match_operand 4 "" ""))
> -		      (pc)))
> -   (set (match_dup 6)
> -	(unspec:SI [(match_operand 3 "" "")
> -		    (match_dup 5) (match_dup 7)] UNSPEC_ARC_CASESI))
> -   (parallel [(set (pc) (match_dup 6)) (use (match_dup 7))])]
> +  [(match_operand:SI 0 "register_operand" "")	; Index
> +   (match_operand:SI 1 "const_int_operand" "")	; Lower bound
> +   (match_operand:SI 2 "const_int_operand" "")	; Total range
> +   (match_operand:SI 3 "" "")		; Table label
> +   (match_operand:SI 4 "" "")]		; Out of range label
>    ""
> -  "
> -{
> -  rtx x;
> -
> -  operands[5] = gen_reg_rtx (SImode);
> -  operands[6] = gen_reg_rtx (SImode);
> -  operands[7] = operands[3];
> -  emit_insn (gen_subsi3 (operands[5], operands[0], operands[1]));
> -  emit_insn (gen_cmpsi_cc_insn_mixed (operands[5], operands[2]));
> -  x = gen_rtx_GTU (VOIDmode, gen_rtx_REG (CCmode, CC_REG), const0_rtx);
> -  x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
> -			    gen_rtx_LABEL_REF (VOIDmode, operands[4]), pc_rtx);
> -  emit_jump_insn (gen_rtx_SET (pc_rtx, x));
> -  if (TARGET_COMPACT_CASESI)
> -    {
> -      emit_jump_insn (gen_casesi_compact_jump (operands[5], operands[7]));
> -    }
> -  else
> -    {
> +  {
> +   if (operands[1] != const0_rtx)
> +     {
> +       rtx reg = gen_reg_rtx (SImode);
> +       emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
> +       operands[0] = reg;
> +      }

Indentation seems wonky here.

> +   emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, operands[0],
> +							operands[2]),
> +				   operands[0], operands[2], operands[4]));
> +   if (TARGET_BI_BIH)
> +     {
> +      emit_jump_insn (gen_casesi_dispatch (operands[0], operands[3]));
> +     }

Don't think the {} are needed for a single line.

> +   else
> +   {

Shouldn't the '{' be indented? And the block below accordingly?

> +      rtx reg = gen_reg_rtx (SImode);
> +      rtx lbl = operands[3];
>        operands[3] = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
> -      if (flag_pic || !cse_not_expected)
> +      if (flag_pic)
>  	operands[3] = force_reg (Pmode, operands[3]);
> -      emit_insn (gen_casesi_load (operands[6],
> -				  operands[3], operands[5], operands[7]));
> +      emit_insn (gen_casesi_load (reg,
> +				  operands[3], operands[0], lbl));
>        if (CASE_VECTOR_PC_RELATIVE || flag_pic)
> -	emit_insn (gen_addsi3 (operands[6], operands[6], operands[3]));
> -      emit_jump_insn (gen_casesi_jump (operands[6], operands[7]));
> +	emit_insn (gen_addsi3 (reg, reg, operands[3]));
> +      emit_jump_insn (gen_casesi_jump (reg, lbl));
> +     }
> +   DONE;
> +  })
> +
> +(define_insn "casesi_dispatch"
> +  [(set (pc)
> +	(unspec:SI [(match_operand:SI 0 "register_operand" "r")
> +		    (label_ref (match_operand 1 "" ""))]
> +		   UNSPEC_ARC_CASESI))]
> +  "TARGET_BI_BIH"
> +  {
> +   rtx diff_vec = PATTERN (next_nonnote_insn (as_a<rtx_insn *> (operands[1])));
> +   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
> +   switch (GET_MODE (diff_vec))
> +   {

Indent the { I think.

> +    case E_SImode:
> +     return \"bi\\t[%0]\";
> +    case E_HImode:
> +    case E_QImode:
> +    return \"bih\\t[%0]\";
> +    default: gcc_unreachable ();
>      }
> -  DONE;
> -}")
> +   }
> +  [(set_attr "type" "brcc_no_delay_slot")
> +   (set_attr "iscompact" "false")
> +   (set_attr "length" "4")])
>  
>  (define_insn "casesi_load"
> -  [(set (match_operand:SI 0 "register_operand"             "=Rcq,r,r")
> -	(unspec:SI [(match_operand:SI 1 "nonmemory_operand" "Rcq,c,Cal")
> -		    (match_operand:SI 2 "register_operand"  "Rcq,c,c")
> -		    (label_ref (match_operand 3 "" ""))] UNSPEC_ARC_CASESI))]
> +  [(set (match_operand:SI 0 "register_operand"             "=q,r,r")
> +	(mem:SI (unspec:SI [(match_operand:SI 1 "nonmemory_operand" "q,r,Cal")
> +			    (match_operand:SI 2 "register_operand"  "q,r,r")]
> +			   UNSPEC_ARC_CASESI)))
> +   (use (label_ref (match_operand 3 "" "")))]
>    ""
>    "*
>  {
> @@ -4037,15 +4049,15 @@ archs4x, archs4xd, archs4xd_slow"
>    switch (GET_MODE (diff_vec))
>      {
>      case E_SImode:
> -      return \"ld.as %0,[%1,%2]%&\";
> +      return \"ld.as\\t%0,[%1,%2]%&\";
>      case E_HImode:
>        if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
> -	return \"ld%_.as %0,[%1,%2]\";
> -      return \"ld%_.x.as %0,[%1,%2]\";
> +	return \"ld%_.as\\t%0,[%1,%2]\";
> +      return \"ld%_.x.as\\t%0,[%1,%2]\";
>      case E_QImode:
>        if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
> -	return \"ldb%? %0,[%1,%2]%&\";
> -      return \"ldb.x %0,[%1,%2]\";
> +	return \"ldb%?\\t%0,[%1,%2]%&\";
> +      return \"ldb.x\\t%0,[%1,%2]\";
>      default:
>        gcc_unreachable ();
>      }
> @@ -4085,110 +4097,6 @@ archs4x, archs4xd, archs4xd_slow"
>     (set_attr "iscompact" "false,maybe,false")
>     (set_attr "cond" "canuse")])
>  
> -(define_insn "casesi_compact_jump"
> -  [(set (pc)
> -	(unspec:SI [(match_operand:SI 0 "register_operand" "c,q")]
> -		   UNSPEC_ARC_CASESI))
> -   (use (label_ref (match_operand 1 "" "")))
> -   (clobber (match_scratch:SI 2 "=q,0"))]
> -  "TARGET_COMPACT_CASESI"
> -  "*
> -{
> -  rtx diff_vec = PATTERN (next_nonnote_insn (as_a<rtx_insn *> (operands[1])));
> -  int unalign = arc_get_unalign ();
> -  rtx xop[3];
> -  const char *s;
> -
> -  xop[0] = operands[0];
> -  xop[2] = operands[2];
> -  gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
> -
> -  switch (GET_MODE (diff_vec))
> -    {
> -    case E_SImode:
> -      /* Max length can be 12 in this case, but this is OK because
> -	 2 of these are for alignment, and are anticipated in the length
> -	 of the ADDR_DIFF_VEC.  */
> -      if (unalign && !satisfies_constraint_Rcq (xop[0]))
> -	s = \"add2 %2,pcl,%0\n\tld_s %2,[%2,12]\";
> -      else if (unalign)
> -	s = \"add_s %2,%0,2\n\tld.as %2,[pcl,%2]\";
> -      else
> -	s = \"add %2,%0,2\n\tld.as %2,[pcl,%2]\";
> -      arc_clear_unalign ();
> -      break;
> -    case E_HImode:
> -      if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
> -	{
> -	  if (satisfies_constraint_Rcq (xop[0]))
> -	    {
> -	      s = \"add_s %2,%0,%1\n\tld%_.as %2,[pcl,%2]\";
> -	      xop[1] = GEN_INT ((10 - unalign) / 2U);
> -	    }
> -	  else
> -	    {
> -	      s = \"add1 %2,pcl,%0\n\tld%__s %2,[%2,%1]\";
> -	      xop[1] = GEN_INT (10 + unalign);
> -	    }
> -	}
> -      else
> -	{
> -	  if (satisfies_constraint_Rcq (xop[0]))
> -	    {
> -	      s = \"add_s %2,%0,%1\n\tld%_.x.as %2,[pcl,%2]\";
> -	      xop[1] = GEN_INT ((10 - unalign) / 2U);
> -	    }
> -	  else
> -	    {
> -	      s = \"add1 %2,pcl,%0\n\tld%__s.x %2,[%2,%1]\";
> -	      xop[1] = GEN_INT (10 + unalign);
> -	    }
> -	}
> -      arc_toggle_unalign ();
> -      break;
> -    case E_QImode:
> -      if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
> -	{
> -	  if ((rtx_equal_p (xop[2], xop[0])
> -	       || find_reg_note (insn, REG_DEAD, xop[0]))
> -	      && satisfies_constraint_Rcq (xop[0]))
> -	    {
> -	      s = \"add_s %0,%0,pcl\n\tldb_s %2,[%0,%1]\";
> -	      xop[1] = GEN_INT (8 + unalign);
> -	    }
> -	  else
> -	    {
> -	      s = \"add %2,%0,pcl\n\tldb_s %2,[%2,%1]\";
> -	      xop[1] = GEN_INT (10 + unalign);
> -	      arc_toggle_unalign ();
> -	    }
> -	}
> -      else if ((rtx_equal_p (xop[0], xop[2])
> -		|| find_reg_note (insn, REG_DEAD, xop[0]))
> -	       && satisfies_constraint_Rcq (xop[0]))
> -	{
> -	  s = \"add_s %0,%0,%1\n\tldb.x %2,[pcl,%0]\";
> -	  xop[1] = GEN_INT (10 - unalign);
> -	  arc_toggle_unalign ();
> -	}
> -      else
> -	{
> -	  /* ??? Length is 12.  */
> -	  s = \"add %2,%0,%1\n\tldb.x %2,[pcl,%2]\";
> -	  xop[1] = GEN_INT (8 + unalign);
> -	}
> -      break;
> -    default:
> -      gcc_unreachable ();
> -    }
> -  output_asm_insn (s, xop);
> -  return \"add_s %2,%2,pcl\n\tj_s%* [%2]\";
> -}"
> -  [(set_attr "length" "10")
> -   (set_attr "type" "jump")
> -   (set_attr "iscompact" "true")
> -   (set_attr "cond" "nocond")])
> -
>  (define_expand "call"
>    ;; operands[1] is stack_size_rtx
>    ;; operands[2] is next_arg_register
> diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt
> index ee06c063837..3e96b58375d 100644
> --- a/gcc/config/arc/arc.opt
> +++ b/gcc/config/arc/arc.opt
> @@ -328,7 +328,7 @@ Target Var(TARGET_CASE_VECTOR_PC_RELATIVE)
>  Use pc-relative switch case tables - this enables case table shortening.
>  
>  mcompact-casesi
> -Target Var(TARGET_COMPACT_CASESI)
> +Target Warn(%qs is deprecated)
>  Enable compact casesi pattern.
>  
>  mq-class
> @@ -528,3 +528,7 @@ Enum(arc_lpc) String(32) Value(32)
>  mrf16
>  Target Report Mask(RF16)
>  Enable 16-entry register file.
> +
> +mbranch-index
> +Target Report Var(TARGET_BRANCH_INDEX) Init(DEFAULT_BRANCH_INDEX)
> +Enable use of BI/BIH instructions when available.
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 802cc642453..454587310c8 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -650,7 +650,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} -mrf16}
> +-mdiv-rem  -mcode-density  -mll64  -mfpu=@var{fpu} -mrf16 -mbranch-index}
>  
>  @emph{ARM Options}
>  @gccoptlist{-mapcs-frame  -mno-apcs-frame @gol
> @@ -15814,6 +15814,11 @@ This option instructs the compiler to generate code for a 16-entry
>  register file.  This option defines the @code{__ARC_RF16__}
>  preprocessor macro.
>  
> +@item -mbranch-index
> +@opindex mbranch-index
> +Enable use of @code{bi} or @code{bih} instructions to implement jump
> +tables.
> +
>  @end table
>  
>  The following options are passed through to the assembler, and also
> @@ -15985,7 +15990,7 @@ This is the default for @option{-Os}.
>  @item -mcompact-casesi
>  @opindex mcompact-casesi
>  Enable compact @code{casesi} pattern.  This is the default for @option{-Os},
> -and only available for ARCv1 cores.
> +and only available for ARCv1 cores.  This option is deprecated.
>  
>  @item -mno-cond-exec
>  @opindex mno-cond-exec
> diff --git a/gcc/testsuite/gcc.target/arc/jumptable.c b/gcc/testsuite/gcc.target/arc/jumptable.c
> new file mode 100644
> index 00000000000..fbc58e33149
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arc/jumptable.c
> @@ -0,0 +1,34 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "" { arc700 || arc6xx } } */
> +/* { dg-options "-O2 -mbranch-index -mcode-density" { target { arcem || archs } } } */
> +
> +extern void max( int,int);
> +
> +int switchCase(int value, int b)
> +{
> +  switch(value){
> +  case 100:
> +    value = b * value;
> +    break;
> +  case 101:
> +    value = b << value;
> +    break;
> +  case 102:
> +    value = b / value;
> +    break;
> +  case 103:
> +    value = b >> value;
> +    break;
> +  case 104:
> +    value = b + value;
> +    break;
> +  case 105:
> +    value = b - value;
> +    break;
> +  }
> +  max(value, b);
> +  return 0;
> +}
> +
> +/* { dg-final { scan-assembler-times "bih" 1 } } */
> +/* { dg-final { scan-assembler-times "b_s" 8 } } */
> -- 
> 2.17.1
> 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]