* Claudiu Zissulescu <claz...@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 <claz...@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 <claz...@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 >