[committed,2/2] arc: Cleanup addsi3 instruction pattern

Message ID 20230905084234.114788-2-claziss@gmail.com
State Accepted
Headers
Series [committed,1/2] arc: Remove obsolete mbbit-peephole option and unused patterns. |

Checks

Context Check Description
snail/gcc-patch-check success Github commit url

Commit Message

Claudiu Zissulescu Ianculescu Sept. 5, 2023, 8:42 a.m. UTC
  This patch repurposes the code letter 's' to 'x', and 'S' to 'J'.
Also it introduces new CODE letters 'x', 's', 'S', and 'N'.

gcc/ChangeLog:

	* config/arc/arc-protos.h (arc_output_addsi): Remove declaration.
	(split_addsi): Likewise.
	* config/arc/arc.cc (arc_print_operand): Add/repurpose 's', 'S',
	'N', 'x', and 'J' code letters.
	(arc_output_addsi): Make it static.
	(split_addsi): Remove it.
	* config/arc/arc.h (UNSIGNED_INT*): New defines.
	(SINNED_INT*): Likewise.
	* config/arc/arc.md (type): Add add, sub, bxor types.
	(tst_movb): Change code letter from 's' to 'x'.
	(andsi3_i): Likewise.
	(addsi3_mixed): Refurbish the pattern.
	(call_i): Change code letter from 'S' to 'J'.
	* config/arc/arc700.md: Add newly introduced types.
	* config/arc/arcHS.md: Likewsie.
	* config/arc/arcHS4x.md: Likewise.
	* config/arc/constraints.md (Cca, CL2, Csp, C2a): Remove it.
	(CM4): Update description.
	(CP4, C6u, C6n, CIs, C4p): New constraint.

Signed-off-by: Claudiu Zissulescu <claziss@gmail.com>
---
 gcc/config/arc/arc-protos.h   |  2 -
 gcc/config/arc/arc.cc         | 94 +++++++++++++++++++++++------------
 gcc/config/arc/arc.h          | 58 +++++++++++++++------
 gcc/config/arc/arc.md         | 81 +++++++++++++++---------------
 gcc/config/arc/arc700.md      |  2 +-
 gcc/config/arc/arcHS.md       |  2 +-
 gcc/config/arc/arcHS4x.md     |  2 +-
 gcc/config/arc/constraints.md | 71 +++++++++++++-------------
 8 files changed, 184 insertions(+), 128 deletions(-)
  

Patch

diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h
index d47b4756ad4..4f2db7ffb59 100644
--- a/gcc/config/arc/arc-protos.h
+++ b/gcc/config/arc/arc-protos.h
@@ -32,7 +32,6 @@  extern void arc_print_operand (FILE *, rtx, int);
 extern void arc_print_operand_address (FILE *, rtx);
 extern void arc_final_prescan_insn (rtx_insn *, rtx *, int);
 extern const char *arc_output_libcall (const char *);
-extern int arc_output_addsi (rtx *operands, bool, bool);
 extern int arc_output_commutative_cond_exec (rtx *operands, bool);
 extern bool arc_expand_cpymem (rtx *operands);
 extern bool prepare_move_operands (rtx *operands, machine_mode mode);
@@ -86,7 +85,6 @@  extern void arc_init_expanders (void);
 extern int arc_check_millicode (rtx op, int offset, int load_p);
 extern void arc_clear_unalign (void);
 extern void arc_toggle_unalign (void);
-extern void split_addsi (rtx *);
 extern void split_subsi (rtx *);
 extern void arc_split_move (rtx *);
 extern const char *arc_short_long (rtx_insn *insn, const char *, const char *);
diff --git a/gcc/config/arc/arc.cc b/gcc/config/arc/arc.cc
index 8ee7387286e..f8c9bf17e2c 100644
--- a/gcc/config/arc/arc.cc
+++ b/gcc/config/arc/arc.cc
@@ -4501,8 +4501,8 @@  static int output_sdata = 0;
 
 /* Print operand X (an rtx) in assembler syntax to file FILE.
    CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
-   For `%' followed by punctuation, CODE is the punctuation and X is null.  */
-/* In final.cc:output_asm_insn:
+   For `%' followed by punctuation, CODE is the punctuation and X is null.
+   In final.cc:output_asm_insn:
     'l' : label
     'a' : address
     'c' : constant address if CONSTANT_ADDRESS_P
@@ -4512,7 +4512,10 @@  static int output_sdata = 0;
     'z': log2
     'M': log2(~x)
     'p': bit Position of lsb
-    's': size of bit field
+    's': scalled immediate
+    'S': Scalled immediate, to be used in pair with 's'.
+    'N': Negative immediate, to be used in pair with 's'.
+    'x': size of bit field
     '#': condbranch delay slot suffix
     '*': jump delay slot suffix
     '?' : nonjump-insn suffix for conditional execution or short instruction
@@ -4521,7 +4524,7 @@  static int output_sdata = 0;
     'd'
     'D'
     'R': Second word
-    'S': JLI instruction
+    'J': JLI instruction
     'j': used by mov instruction to properly emit jli related labels.
     'B': Branch comparison operand - suppress sda reference
     'H': Most significant word
@@ -4538,6 +4541,10 @@  static int output_sdata = 0;
 void
 arc_print_operand (FILE *file, rtx x, int code)
 {
+  HOST_WIDE_INT ival;
+  unsigned scalled = 0;
+  int sign = 1;
+
   switch (code)
     {
     case 'Z':
@@ -4580,6 +4587,56 @@  arc_print_operand (FILE *file, rtx x, int code)
       return;
 
     case 's':
+      if (REG_P (x))
+	return;
+      if (!CONST_INT_P (x))
+	{
+	  output_operand_lossage ("invalid operand for %%s code");
+	  return;
+	}
+      ival = INTVAL (x);
+      if ((ival & 0x07) == 0)
+	  scalled = 3;
+      else if ((ival & 0x03) == 0)
+	  scalled = 2;
+      else if ((ival & 0x01) == 0)
+	  scalled = 1;
+
+      if (scalled)
+	asm_fprintf (file, "%d", scalled);
+      return;
+
+    case 'N':
+      if (REG_P (x))
+	{
+	  output_operand_lossage ("invalid operand for %%N code");
+	  return;
+	}
+      sign = -1;
+      /* fall through */
+    case 'S':
+      if (REG_P (x))
+	{
+	  asm_fprintf (file, "%s", reg_names [REGNO (x)]);
+	  return;
+	}
+      if (!CONST_INT_P (x))
+	{
+	  output_operand_lossage ("invalid operand for %%N or %%S code");
+	  return;
+	}
+      ival = sign * INTVAL (x);
+      if ((ival & 0x07) == 0)
+	  scalled = 3;
+      else if ((ival & 0x03) == 0)
+	  scalled = 2;
+      else if ((ival & 0x01) == 0)
+	  scalled = 1;
+
+      asm_fprintf (file, "%wd", (ival >> scalled));
+      return;
+
+    case 'x':
       if (GET_CODE (x) == CONST_INT)
 	{
 	  HOST_WIDE_INT i = INTVAL (x);
@@ -4738,7 +4795,7 @@  arc_print_operand (FILE *file, rtx x, int code)
 	output_operand_lossage ("invalid operand to %%R code");
       return;
     case 'j':
-    case 'S' :
+    case 'J' :
       if (GET_CODE (x) == SYMBOL_REF
 	  && arc_is_jli_call_p (x))
 	{
@@ -8989,7 +9046,7 @@  arc_register_move_cost (machine_mode,
    Return the length of the instruction.
    If OUTPUT_P is false, don't actually output the instruction, just return
    its length.  */
-int
+static int
 arc_output_addsi (rtx *operands, bool cond_p, bool output_p)
 {
   char format[35];
@@ -10016,31 +10073,6 @@  arc_toggle_unalign (void)
   cfun->machine->unalign ^= 2;
 }
 
-/* Operands 0..2 are the operands of a addsi which uses a 12 bit
-   constant in operand 2, but which would require a LIMM because of
-   operand mismatch.
-   operands 3 and 4 are new SET_SRCs for operands 0.  */
-
-void
-split_addsi (rtx *operands)
-{
-  int val = INTVAL (operands[2]);
-
-  /* Try for two short insns first.  Lengths being equal, we prefer
-     expansions with shorter register lifetimes.  */
-  if (val > 127 && val <= 255
-      && arc_check_short_reg_p (operands[0]))
-    {
-      operands[3] = operands[2];
-      operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[1]);
-    }
-  else
-    {
-      operands[3] = operands[1];
-      operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[2]);
-    }
-}
-
 /* Operands 0..2 are the operands of a subsi which uses a 12 bit
    constant in operand 1, but which would require a LIMM because of
    operand mismatch.
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index c3756394025..8daae41ff5b 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -615,25 +615,53 @@  extern enum reg_class arc_regno_reg_class[];
 ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
 
 #define SMALL_INT(X) ((unsigned) ((X) + 0x100) < 0x200)
-#define SMALL_INT_RANGE(X, OFFSET, SHIFT) \
-  ((unsigned) (((X) >> (SHIFT)) + 0x100) \
+#define SMALL_INT_RANGE(X, OFFSET, SHIFT)	\
+  ((unsigned) (((X) >> (SHIFT)) + 0x100)	\
    < 0x200 - ((unsigned) (OFFSET) >> (SHIFT)))
-#define SIGNED_INT12(X) ((unsigned) ((X) + 0x800) < 0x1000)
-#define SIGNED_INT16(X) ((unsigned) ((X) + 0x8000) < 0x10000)
-#define LARGE_INT(X) \
-(((X) < 0) \
- ? (X) >= (-(HOST_WIDE_INT) 0x7fffffff - 1) \
- : (unsigned HOST_WIDE_INT) (X) <= (unsigned HOST_WIDE_INT) 0xffffffff)
-#define UNSIGNED_INT3(X) ((unsigned) (X) < 0x8)
-#define UNSIGNED_INT5(X) ((unsigned) (X) < 0x20)
-#define UNSIGNED_INT6(X) ((unsigned) (X) < 0x40)
-#define UNSIGNED_INT7(X) ((unsigned) (X) < 0x80)
-#define UNSIGNED_INT8(X) ((unsigned) (X) < 0x100)
-#define UNSIGNED_INT12(X) ((unsigned) (X) < 0x800)
-#define UNSIGNED_INT16(X) ((unsigned) (X) < 0x10000)
+#define LARGE_INT(X)				\
+  (((X) < 0)					\
+   ? (X) >= (-(HOST_WIDE_INT) 0x7fffffff - 1)				\
+   : (unsigned HOST_WIDE_INT) (X) <= (unsigned HOST_WIDE_INT) 0xffffffff)
+
 #define IS_ONE(X) ((X) == 1)
 #define IS_ZERO(X) ((X) == 0)
 
+#define SIGNED(X,V)							\
+  ((unsigned long long) ((X) + (1ULL << (V - 1))) < (1ULL << V))
+#define UNSIGNED(X,V) ((unsigned long long) (X) < (1ULL << V))
+#define VERIFY_SHIFT(X,S) ((X & ((1 << S) - 1)) == 0)
+
+#define UNSIGNED_INT3(X) (UNSIGNED(X,3))
+#define UNSIGNED_INT5(X) (UNSIGNED(X,5))
+#define UNSIGNED_INT6(X) (UNSIGNED(X,6))
+#define UNSIGNED_INT7(X) (UNSIGNED(X,7))
+#define UNSIGNED_INT8(X) (UNSIGNED(X,8))
+#define UNSIGNED_INT9(X) (UNSIGNED(X,9))
+#define UNSIGNED_INT10(X) (UNSIGNED(X,10))
+#define UNSIGNED_INT12(X) (UNSIGNED(X,12))
+#define UNSIGNED_INT16(X) (UNSIGNED(X,16))
+
+#define SIGNED_INT3(X) (SIGNED(X,3))
+#define SIGNED_INT6(X) (SIGNED(X,6))
+#define SIGNED_INT7(X) (SIGNED(X,7))
+#define SIGNED_INT8(X) (SIGNED(X,8))
+#define SIGNED_INT9(X) (SIGNED(X,9))
+#define SIGNED_INT10(X) (SIGNED(X,10))
+#define SIGNED_INT11(X) (SIGNED(X,11))
+#define SIGNED_INT12(X) (SIGNED(X,12))
+#define SIGNED_INT13(X) (SIGNED(X,13))
+#define SIGNED_INT16(X) (SIGNED(X,16))
+#define SIGNED_INT21(X) (SIGNED(X,21))
+#define SIGNED_INT25(X) (SIGNED(X,25))
+
+#define UNSIGNED_INT7_SHIFTED(X,S) (VERIFY_SHIFT(X,S) && UNSIGNED_INT6(X >> S))
+#define UNSIGNED_INT8_SHIFTED(X,S) (VERIFY_SHIFT(X,S) && UNSIGNED_INT6(X >> S))
+#define UNSIGNED_INT9_SHIFTED(X,S) (VERIFY_SHIFT(X,S) && UNSIGNED_INT6(X >> S))
+
+#define SIGNED_INT13_SHIFTED(X,S) (VERIFY_SHIFT(X,S) && SIGNED_INT12(X >> S))
+#define SIGNED_INT14_SHIFTED(X,S) (VERIFY_SHIFT(X,S) && SIGNED_INT12(X >> S))
+#define SIGNED_INT15_SHIFTED(X,S) (VERIFY_SHIFT(X,S) && SIGNED_INT12(X >> S))
+
 /* Stack layout and stack pointer usage.  */
 
 /* Define this macro if pushing a word onto the stack moves the stack
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index d401e600f42..d37ecbf4292 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -242,11 +242,12 @@  (define_attr "is_sfunc" "no,yes" (const_string "no"))
 ; via r12.
 
 (define_attr "type"
-  "move,load,store,cmove,unary,binary,compare,shift,uncond_branch,jump,branch,
-   brcc,brcc_no_delay_slot,call,sfunc,call_no_delay_slot,rtie,
-   multi,umulti, two_cycle_core,lr,sr,divaw,loop_setup,loop_end,return,
-   misc,spfp,dpfp_mult,dpfp_addsub,mulmac_600,cc_arith,
-   simd_vload, simd_vload128, simd_vstore, simd_vmove, simd_vmove_else_zero,
+  "add,sub,bxor,move,load,store,cmove,unary,binary,compare,shift,uncond_branch,
+   jump,branch,brcc,brcc_no_delay_slot,call,sfunc,call_no_delay_slot,rtie,
+   multi,umulti,
+   two_cycle_core,lr,sr,divaw,loop_setup,loop_end,return,
+   misc,spfp,dpfp_mult,dpfp_addsub,mulmac_600,cc_arith, simd_vload,
+   simd_vload128, simd_vstore, simd_vmove, simd_vmove_else_zero,
    simd_vmove_with_acc, simd_varith_1cycle, simd_varith_2cycle,
    simd_varith_with_acc, simd_vlogic, simd_vlogic_with_acc,
    simd_vcompare, simd_vpermute, simd_vpack, simd_vpack_with_acc,
@@ -1004,7 +1005,7 @@  (define_insn_and_split "*tst_movb"
 	(const_int 0)]))
    (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,Rrq,1,c"))]
   "TARGET_NPS_BITOPS"
-  "movb.f.cl %3,%1,%p2,%p2,%s2"
+  "movb.f.cl %3,%1,%p2,%p2,%x2"
   "TARGET_NPS_BITOPS && reload_completed
    && (extract_constrain_insn_cached (insn), (which_alternative & ~1) != 6)"
   [(set (match_dup 0) (match_dup 4))])
@@ -2018,44 +2019,40 @@  (define_insn "sminsi3"
 
 ;; Arithmetic instructions.
 
-; We say an insn can be conditionalized if this doesn't introduce a long
-; immediate.  We set the type such that we still have good scheduling if the
-; insn is conditionalized.
-; ??? It would make sense to allow introduction of long immediates, but
-;     we'd need to communicate to the ccfsm machinery the extra cost.
 ; The alternatives in the constraints still serve three purposes:
 ; - estimate insn size assuming conditional execution
 ; - guide reload to re-order the second and third operand to get a better fit.
 ; - give tentative insn type to guide scheduling
 ;   N.B. "%" for commutativity doesn't help when there is another matching
 ;   (but longer) alternative.
-; We avoid letting this pattern use LP_COUNT as a register by specifying
-;  register class 'W' instead of 'w'.
-(define_insn_and_split "*addsi3_mixed"
-  ;;                                                      0  1    2     3   4   5   6  7  8  9 a    b     c   d e   f  10  11  12
-  [(set (match_operand:SI 0 "dest_reg_operand"           "=q,q,   h,!*Rsd,  q,Rcb,  q, q, q, r,r,   r,    W,  W,W,  W,  q,  r,  W")
-	(plus:SI (match_operand:SI 1 "register_operand"  "%0,c,   0,    q,  0,  0,Rcb, q, 0, 0,r,   0,    c,  c,0,  0,  0,  0,  c")
-		 (match_operand:SI 2 "nonmemory_operand" "cL,0, Cm1,    L,CL2,Csp,CM4,qK,cO,rL,0,rCca,cLCmL,Cca,I,C2a,Cal,Cal,Cal")))]
+(define_insn "*addsi3_mixed"
+  ;;                                                      0    1     2   3   4   5  6  7  8  9   a   b   c   d   e   f  10
+  [(set (match_operand:SI 0 "register_operand"           "=q,  h,!*Rsd,Rcb,Rcb,  q, q, q, r,r,   r,  r,  r,  r,  q,  r,  r")
+	(plus:SI (match_operand:SI 1 "register_operand"  "%0,  0,    q,  0,  0,Rcb, q, 0, 0,r,   r,  r,  0,  r,  0,  0,  r")
+		 (match_operand:SI 2 "nonmemory_operand" "hL,Cm1,    L,CP4,CM4,CM4,qK, O,rL,0,rC6u,C6n,CIs,C4p,Cal,Cal,Cal")))]
   ""
-{
-  arc_output_addsi (operands, arc_ccfsm_cond_exec_p (), true);
-  return "";
-}
-  "&& reload_completed && get_attr_length (insn) == 8
-   && satisfies_constraint_I (operands[2])
-   && GET_CODE (PATTERN (insn)) != COND_EXEC"
-  [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))]
-  "split_addsi (operands);"
-  [(set_attr "type" "*,*,*,*,two_cycle_core,two_cycle_core,*,*,*,*,*,two_cycle_core,*,two_cycle_core,*,two_cycle_core,*,*,*")
-   (set (attr "iscompact")
-	(cond [(match_test "~arc_output_addsi (operands, false, false) & 2")
-	       (const_string "false")
-	       (match_operand 2 "long_immediate_operand" "")
-	       (const_string "maybe_limm")]
-	      (const_string "maybe")))
-   (set_attr "length"     "*,*,*,*,*,*,*,*,*,4,4,4,4,4,4,4,*,8,8")
-   (set_attr "predicable" "no,no,no,no,no,no,no,no,no,yes,yes,yes,no,no,no,no,no,yes,no")
-   (set_attr "cond"       "canuse,nocond,nocond,nocond,canuse,canuse,nocond,nocond,nocond,canuse,canuse,canuse,nocond,nocond,canuse_limm,canuse_limm,canuse,canuse,nocond")
+  "@
+  add_s\\t%0,%1,%2   ;b,b,h
+  add_s\\t%0,%1,%2   ;h,h,s3
+  add_s\\t%0,%1,%2   ;R0/R1,b,u6
+  sub_s\\t%0,%1,%n2  ;sp,sp,u7
+  add_s\\t%0,%1,%2   ;sp,sp,u7
+  add_s\\t%0,%1,%2   ;b,sp,u7
+  add_s\\t%0,%1,%2   ;a,b,c/u3
+  add_s\\t%0,%1,%2   ;b,b,u7
+  add%?\\t%0,%1,%2   ;(p)b,b,c/u6
+  add%?\\t%0,%2,%1   ;(p)b,b,c
+  add%s2\\t%0,%1,%S2 ;a,b,c/u6
+  sub%s2\\t%0,%1,%N2 ;a,b,u6
+  add%s2\\t%0,%1,%S2 ;b,b,s12
+  bxor\\t%0,%1,31
+  add_s\\t%0,%1,%2   ;b,b,limm
+  add%?\\t%0,%1,%2   ;(p)b,b,limm
+  add\\t%0,%1,%2     ;a,b,limm"
+  [(set_attr "type"       "add,add,add,sub,add,add,add,add,add,add,add,sub,add,bxor,add,add,add")
+   (set_attr "iscompact"  "true,true,true,true,true,true,true,true,false,false,false,false,false,false,true_limm,false,false")
+   (set_attr "length"     "2,2,2,2,2,2,2,2,4,4,4,4,4,4,6,8,8")
+   (set_attr "predicable" "no,no,no,no,no,no,no,no,yes,yes,no,no,no,no,no,yes,no")
 ])
 
 ;; ARCv2 MPYW and MPYUW
@@ -3236,7 +3233,7 @@  (define_insn "andsi3_i"                                     ;0 1   2   3   4  5
 	      ? "extb%? %0,%1%&" : "ext%_%? %0,%1%&");
     case 9: case 14: return \"bic%? %0,%1,%n2-1\";
     case 15:
-      return "movb.cl %0,%1,%p2,%p2,%s2";
+      return "movb.cl %0,%1,%p2,%p2,%x2";
 
     case 19:
       const char *tmpl;
@@ -4090,8 +4087,8 @@  (define_insn "*call_i"
   "@
    jl%!%* [%0]%&
    jl%!%* [%0]
-   jli_s %S0
-   sjli  %S0
+   jli_s %J0
+   sjli  %J0
    bl%!%* %P0
    bl%!%* %P0
    jl%!%* %0
@@ -4134,8 +4131,8 @@  (define_insn "*call_value_i"
   "@
    jl%!%* [%1]%&
    jl%!%* [%1]
-   jli_s %S1
-   sjli  %S1
+   jli_s %J1
+   sjli  %J1
    bl%!%* %P1;1
    bl%!%* %P1;1
    jl%!%* %1
diff --git a/gcc/config/arc/arc700.md b/gcc/config/arc/arc700.md
index cf8e3da4818..7c181f8e329 100644
--- a/gcc/config/arc/arc700.md
+++ b/gcc/config/arc/arc700.md
@@ -46,7 +46,7 @@  (define_insn_reservation "sr" 1
 
 (define_insn_reservation "core_insn" 1
   (and (eq_attr "tune_arc700" "true")
-       (eq_attr "type" "unary, move, binary"))
+       (eq_attr "type" "unary, move, binary, add, sub, bxor"))
   "issue+core, nothing, write_port")
 
 (define_insn_reservation "cmove" 1
diff --git a/gcc/config/arc/arcHS.md b/gcc/config/arc/arcHS.md
index 404f82797ce..2b383b26af1 100644
--- a/gcc/config/arc/arcHS.md
+++ b/gcc/config/arc/arcHS.md
@@ -46,7 +46,7 @@  (define_insn_reservation "hs_alu0" 4
 (define_insn_reservation "hs_alu1" 4
   (and (match_test "TARGET_HS")
        (eq_attr "tune" "none")
-       (eq_attr "type" "move, cmove, unary, binary, compare, misc"))
+       (eq_attr "type" "move, cmove, unary, binary, compare, misc, add, sub, bxor"))
   "hs_issue+x1, nothing*3")
 
 (define_insn_reservation "hs_divrem" 13
diff --git a/gcc/config/arc/arcHS4x.md b/gcc/config/arc/arcHS4x.md
index 169a94027fd..a6696f092df 100644
--- a/gcc/config/arc/arcHS4x.md
+++ b/gcc/config/arc/arcHS4x.md
@@ -77,7 +77,7 @@  (define_insn_reservation "hs4x_adv_alul_op" 6
 (define_insn_reservation "hs4x_basic_alue_op" 1
   (and (match_test "TARGET_HS")
        (eq_attr "tune" "archs4x, archs4xd")
-       (eq_attr "type" "move, cmove, unary, binary, compare, misc"))
+       (eq_attr "type" "move, cmove, unary, binary, compare, misc, add, sub, bxor"))
   "(hs4x_issue0 | hs4x_issue1) + hs4x_y1")
 
 (define_insn_reservation "hs4x_basic_alul_op" 4
diff --git a/gcc/config/arc/constraints.md b/gcc/config/arc/constraints.md
index a0e949bd1e6..f843f40bbf0 100644
--- a/gcc/config/arc/constraints.md
+++ b/gcc/config/arc/constraints.md
@@ -112,12 +112,6 @@  (define_constraint "CnL"
   (and (match_code "const_int")
        (match_test "UNSIGNED_INT6 (~ival)")))
 
-(define_constraint "CmL"
-  "@internal
-   Two's complement of a 6-bit unsigned integer constant"
-  (and (match_code "const_int")
-       (match_test "UNSIGNED_INT6 (-ival)")))
-
 (define_constraint "C16"
   "@internal
    A 16-bit signed integer constant"
@@ -160,42 +154,17 @@  (define_constraint "Cn0"
   (and (match_code "const_int")
        (match_test "ival <= 0")))
 
-(define_constraint "Cca"
-  "@internal
-   Conditional or three-address add / sub constant"
-  (and (match_code "const_int")
-       (match_test "ival == (HOST_WIDE_INT)(HOST_WIDE_INT_M1U << 31)
-		    || (ival >= -0x1f8 && ival <= 0x1f8
-			&& ((ival >= 0 ? ival : -ival)
-			    <= 0x3f * (ival & -ival)))")))
-
-; intersection of "O" and "Cca".
-(define_constraint "CL2"
-  "@internal
-   A 6-bit unsigned integer constant times 2"
-  (and (match_code "const_int")
-       (match_test "!(ival & ~126)")))
-
 (define_constraint "CM4"
   "@internal
-   A 5-bit unsigned integer constant times 4"
+   A valid 5-bit unsigned stack offset for a short add"
   (and (match_code "const_int")
        (match_test "!(ival & ~124)")))
 
-(define_constraint "Csp"
+(define_constraint "CP4"
   "@internal
-   A valid stack pointer offset for a short add"
+   A valid 5-bit unsigned stack offset for a short sub"
   (and (match_code "const_int")
-       (match_test "!(ival & ~124) || !(-ival & ~124)")))
-
-(define_constraint "C2a"
-  "@internal
-   Unconditional two-address add / sub constant"
-  (and (match_code "const_int")
-       (match_test "ival == (HOST_WIDE_INT) (HOST_WIDE_INT_M1U << 31)
-		    || (ival >= -0x4000 && ival <= 0x4000
-			&& ((ival >= 0 ? ival : -ival)
-			    <= 0x7ff * (ival & -ival)))")))
+       (match_test "!(-ival & ~124)")))
 
 (define_constraint "C0p"
  "@internal
@@ -532,3 +501,35 @@  (define_register_constraint "Rzd"
   "TARGET_CODE_DENSITY ? R0_REGS : NO_REGS"
   "@internal
    @code{r0} register for code density instructions.")
+
+(define_constraint "C6u" "@internal
+  A 6-bit unsigned integer constant shifted by x-bit(s)"
+  (and (match_code "const_int")
+       (ior (match_test "UNSIGNED_INT9_SHIFTED (ival,3)")
+	    (match_test "UNSIGNED_INT8_SHIFTED (ival,2)")
+	    (match_test "UNSIGNED_INT7_SHIFTED (ival,1)")
+	    (match_test "UNSIGNED_INT6 (ival)"))))
+
+(define_constraint "C6n" "@internal
+  A negative 6-bit integer constant shifted by x-bit(s) used by add."
+  (and (match_code "const_int")
+       (match_test "ival < 0")
+       (match_test "SIGNED_INT10(ival)")
+       (ior (match_test "UNSIGNED_INT9_SHIFTED (-ival,3)")
+	    (match_test "UNSIGNED_INT8_SHIFTED (-ival,2)")
+	    (match_test "UNSIGNED_INT7_SHIFTED (-ival,1)")
+	    (match_test "UNSIGNED_INT6 (-ival)"))))
+
+(define_constraint "CIs" "@internal
+  A 12-bit signed integer constant shifted by x-bit(s)"
+  (and (match_code "const_int")
+       (ior (match_test "SIGNED_INT15_SHIFTED (ival,3)")
+	    (match_test "SIGNED_INT14_SHIFTED (ival,2)")
+	    (match_test "SIGNED_INT13_SHIFTED (ival,1)")
+	    (match_test "SIGNED_INT12 (ival)"))))
+
+(define_constraint "C4p"
+ "@internal
+  Matches 0x8000_0000"
+  (and (match_code "const_int")
+       (match_test "ival == (HOST_WIDE_INT) (HOST_WIDE_INT_M1U << 31)")))