1*4882a593SmuzhiyunFrom b92c22b144d063c4436a6693045ceb57d344c495 Mon Sep 17 00:00:00 2001
2*4882a593SmuzhiyunFrom: Claudiu Zissulescu <claziss@synopsys.com>
3*4882a593SmuzhiyunDate: Wed, 11 Nov 2020 12:31:10 +0200
4*4882a593SmuzhiyunSubject: [PATCH] arc: Refurbish adc/sbc patterns
5*4882a593Smuzhiyun
6*4882a593SmuzhiyunThe adc/sbc patterns were unecessary spliting, remove that and
7*4882a593Smuzhiyunassociated functions.
8*4882a593Smuzhiyun
9*4882a593Smuzhiyungcc/ChangeLog:
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun2020-10-11  Claudiu Zissulescu  <claziss@synopsys.com>
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun	* config/arc/arc-protos.h (arc_scheduling_not_expected): Remove
14*4882a593Smuzhiyun	it.
15*4882a593Smuzhiyun	(arc_sets_cc_p): Likewise.
16*4882a593Smuzhiyun	(arc_need_delay): Likewise.
17*4882a593Smuzhiyun	* config/arc/arc.c (arc_sets_cc_p): Likewise.
18*4882a593Smuzhiyun	(arc_need_delay): Likewise.
19*4882a593Smuzhiyun	(arc_scheduling_not_expected): Likewise.
20*4882a593Smuzhiyun	* config/arc/arc.md: Convert adc/sbc patterns to simple
21*4882a593Smuzhiyun	instruction definitions.
22*4882a593Smuzhiyun
23*4882a593SmuzhiyunSigned-off-by: Claudiu Zissulescu <claziss@synopsys.com>
24*4882a593Smuzhiyun
25*4882a593SmuzhiyunDownloaded from upstream commit
26*4882a593Smuzhiyunhttps://github.com/foss-for-synopsys-dwc-arc-processors/gcc/commit/b92c22b144d063c4436a6693045ceb57d344c495
27*4882a593Smuzhiyun
28*4882a593SmuzhiyunSigned-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
29*4882a593Smuzhiyun---
30*4882a593Smuzhiyun gcc/config/arc/arc-protos.h |  3 --
31*4882a593Smuzhiyun gcc/config/arc/arc.c        | 53 ---------------------
32*4882a593Smuzhiyun gcc/config/arc/arc.md       | 95 +++++++++++--------------------------
33*4882a593Smuzhiyun 3 files changed, 29 insertions(+), 122 deletions(-)
34*4882a593Smuzhiyun
35*4882a593Smuzhiyundiff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h
36*4882a593Smuzhiyunindex c72d78e3b9e..de4cf47c818 100644
37*4882a593Smuzhiyun--- a/gcc/config/arc/arc-protos.h
38*4882a593Smuzhiyun+++ b/gcc/config/arc/arc-protos.h
39*4882a593Smuzhiyun@@ -90,10 +90,7 @@ extern void split_subsi (rtx *);
40*4882a593Smuzhiyun extern void arc_split_move (rtx *);
41*4882a593Smuzhiyun extern const char *arc_short_long (rtx_insn *insn, const char *, const char *);
42*4882a593Smuzhiyun extern rtx arc_regno_use_in (unsigned int, rtx);
43*4882a593Smuzhiyun-extern bool arc_scheduling_not_expected (void);
44*4882a593Smuzhiyun-extern bool arc_sets_cc_p (rtx_insn *insn);
45*4882a593Smuzhiyun extern int arc_label_align (rtx_insn *label);
46*4882a593Smuzhiyun-extern bool arc_need_delay (rtx_insn *insn);
47*4882a593Smuzhiyun extern bool arc_text_label (rtx_insn *insn);
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun extern bool arc_short_comparison_p (rtx, int);
50*4882a593Smuzhiyundiff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
51*4882a593Smuzhiyunindex 5a7b0cb6696..c3ee9181f93 100644
52*4882a593Smuzhiyun--- a/gcc/config/arc/arc.c
53*4882a593Smuzhiyun+++ b/gcc/config/arc/arc.c
54*4882a593Smuzhiyun@@ -10341,59 +10341,6 @@ arc_attr_type (rtx_insn *insn)
55*4882a593Smuzhiyun   return get_attr_type (insn);
56*4882a593Smuzhiyun }
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun-/* Return true if insn sets the condition codes.  */
59*4882a593Smuzhiyun-
60*4882a593Smuzhiyun-bool
61*4882a593Smuzhiyun-arc_sets_cc_p (rtx_insn *insn)
62*4882a593Smuzhiyun-{
63*4882a593Smuzhiyun-  if (NONJUMP_INSN_P (insn))
64*4882a593Smuzhiyun-    if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (PATTERN (insn)))
65*4882a593Smuzhiyun-      insn = seq->insn (seq->len () - 1);
66*4882a593Smuzhiyun-  return arc_attr_type (insn) == TYPE_COMPARE;
67*4882a593Smuzhiyun-}
68*4882a593Smuzhiyun-
69*4882a593Smuzhiyun-/* Return true if INSN is an instruction with a delay slot we may want
70*4882a593Smuzhiyun-   to fill.  */
71*4882a593Smuzhiyun-
72*4882a593Smuzhiyun-bool
73*4882a593Smuzhiyun-arc_need_delay (rtx_insn *insn)
74*4882a593Smuzhiyun-{
75*4882a593Smuzhiyun-  rtx_insn *next;
76*4882a593Smuzhiyun-
77*4882a593Smuzhiyun-  if (!flag_delayed_branch)
78*4882a593Smuzhiyun-    return false;
79*4882a593Smuzhiyun-  /* The return at the end of a function needs a delay slot.  */
80*4882a593Smuzhiyun-  if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == USE
81*4882a593Smuzhiyun-      && (!(next = next_active_insn (insn))
82*4882a593Smuzhiyun-	  || ((!NONJUMP_INSN_P (next) || GET_CODE (PATTERN (next)) != SEQUENCE)
83*4882a593Smuzhiyun-	      && arc_attr_type (next) == TYPE_RETURN))
84*4882a593Smuzhiyun-      && (!TARGET_PAD_RETURN
85*4882a593Smuzhiyun-	  || (prev_active_insn (insn)
86*4882a593Smuzhiyun-	      && prev_active_insn (prev_active_insn (insn))
87*4882a593Smuzhiyun-	      && prev_active_insn (prev_active_insn (prev_active_insn (insn))))))
88*4882a593Smuzhiyun-    return true;
89*4882a593Smuzhiyun-  if (NONJUMP_INSN_P (insn)
90*4882a593Smuzhiyun-      ? (GET_CODE (PATTERN (insn)) == USE
91*4882a593Smuzhiyun-	 || GET_CODE (PATTERN (insn)) == CLOBBER
92*4882a593Smuzhiyun-	 || GET_CODE (PATTERN (insn)) == SEQUENCE)
93*4882a593Smuzhiyun-      : JUMP_P (insn)
94*4882a593Smuzhiyun-      ? (GET_CODE (PATTERN (insn)) == ADDR_VEC
95*4882a593Smuzhiyun-	 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
96*4882a593Smuzhiyun-      : !CALL_P (insn))
97*4882a593Smuzhiyun-    return false;
98*4882a593Smuzhiyun-  return num_delay_slots (insn) != 0;
99*4882a593Smuzhiyun-}
100*4882a593Smuzhiyun-
101*4882a593Smuzhiyun-/* Return true if the scheduling pass(es) has/have already run,
102*4882a593Smuzhiyun-   i.e. where possible, we should try to mitigate high latencies
103*4882a593Smuzhiyun-   by different instruction selection.  */
104*4882a593Smuzhiyun-
105*4882a593Smuzhiyun-bool
106*4882a593Smuzhiyun-arc_scheduling_not_expected (void)
107*4882a593Smuzhiyun-{
108*4882a593Smuzhiyun-  return cfun->machine->arc_reorg_started;
109*4882a593Smuzhiyun-}
110*4882a593Smuzhiyun-
111*4882a593Smuzhiyun /* Code has a minimum p2 alignment of 1, which we must restore after
112*4882a593Smuzhiyun    an ADDR_DIFF_VEC.  */
113*4882a593Smuzhiyun
114*4882a593Smuzhiyundiff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
115*4882a593Smuzhiyunindex f91adbc0d94..c635b69ddd5 100644
116*4882a593Smuzhiyun--- a/gcc/config/arc/arc.md
117*4882a593Smuzhiyun+++ b/gcc/config/arc/arc.md
118*4882a593Smuzhiyun@@ -2847,43 +2847,25 @@ archs4x, archs4xd"
119*4882a593Smuzhiyun    (set_attr "type" "compare")
120*4882a593Smuzhiyun    (set_attr "length" "4,4,8")])
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun-; w/c/c comes first (rather than w/0/C_0) to prevent the middle-end
123*4882a593Smuzhiyun-; needlessly prioritizing the matching constraint.
124*4882a593Smuzhiyun-; Rcw/0/C_0 comes before w/c/L so that the lower latency conditional
125*4882a593Smuzhiyun-; execution is used where possible.
126*4882a593Smuzhiyun-(define_insn_and_split "adc"
127*4882a593Smuzhiyun-  [(set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w,Rcw,w")
128*4882a593Smuzhiyun-	(plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
129*4882a593Smuzhiyun-			  (match_operand:SI 1 "nonmemory_operand"
130*4882a593Smuzhiyun-							 "%c,0,c,0,cCal"))
131*4882a593Smuzhiyun-		 (match_operand:SI 2 "nonmemory_operand" "c,C_0,L,I,cCal")))]
132*4882a593Smuzhiyun+(define_insn "adc"
133*4882a593Smuzhiyun+  [(set (match_operand:SI 0 "register_operand"    "=r,  r,r,r,  r,r")
134*4882a593Smuzhiyun+	(plus:SI
135*4882a593Smuzhiyun+	 (plus:SI
136*4882a593Smuzhiyun+	  (ltu:SI (reg:CC_C CC_REG) (const_int 0))
137*4882a593Smuzhiyun+	  (match_operand:SI 1 "nonmemory_operand" "%r,  0,r,0,Cal,r"))
138*4882a593Smuzhiyun+	 (match_operand:SI 2 "nonmemory_operand"   "r,C_0,L,I,  r,Cal")))]
139*4882a593Smuzhiyun   "register_operand (operands[1], SImode)
140*4882a593Smuzhiyun    || register_operand (operands[2], SImode)"
141*4882a593Smuzhiyun   "@
142*4882a593Smuzhiyun-	adc %0,%1,%2
143*4882a593Smuzhiyun-	add.cs %0,%1,1
144*4882a593Smuzhiyun-	adc %0,%1,%2
145*4882a593Smuzhiyun-	adc %0,%1,%2
146*4882a593Smuzhiyun-	adc %0,%1,%2"
147*4882a593Smuzhiyun-  ; if we have a bad schedule after sched2, split.
148*4882a593Smuzhiyun-  "reload_completed
149*4882a593Smuzhiyun-   && !optimize_size && (!TARGET_ARC600_FAMILY)
150*4882a593Smuzhiyun-   && arc_scheduling_not_expected ()
151*4882a593Smuzhiyun-   && arc_sets_cc_p (prev_nonnote_insn (insn))
152*4882a593Smuzhiyun-   /* If next comes a return or other insn that needs a delay slot,
153*4882a593Smuzhiyun-      expect the adc to get into the delay slot.  */
154*4882a593Smuzhiyun-   && next_nonnote_insn (insn)
155*4882a593Smuzhiyun-   && !arc_need_delay (next_nonnote_insn (insn))
156*4882a593Smuzhiyun-   /* Restore operands before emitting.  */
157*4882a593Smuzhiyun-   && (extract_insn_cached (insn), 1)"
158*4882a593Smuzhiyun-  [(set (match_dup 0) (match_dup 3))
159*4882a593Smuzhiyun-   (cond_exec
160*4882a593Smuzhiyun-     (ltu (reg:CC_C CC_REG) (const_int 0))
161*4882a593Smuzhiyun-     (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))))]
162*4882a593Smuzhiyun-  "operands[3] = simplify_gen_binary (PLUS, SImode, operands[1], operands[2]);"
163*4882a593Smuzhiyun+    adc\\t%0,%1,%2
164*4882a593Smuzhiyun+    add.cs\\t%0,%1,1
165*4882a593Smuzhiyun+    adc\\t%0,%1,%2
166*4882a593Smuzhiyun+    adc\\t%0,%1,%2
167*4882a593Smuzhiyun+    adc\\t%0,%1,%2
168*4882a593Smuzhiyun+    adc\\t%0,%1,%2"
169*4882a593Smuzhiyun   [(set_attr "cond" "use")
170*4882a593Smuzhiyun    (set_attr "type" "cc_arith")
171*4882a593Smuzhiyun-   (set_attr "length" "4,4,4,4,8")])
172*4882a593Smuzhiyun+   (set_attr "length" "4,4,4,4,8,8")])
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun ; combiner-splitter cmp / scc -> cmp / adc
175*4882a593Smuzhiyun (define_split
176*4882a593Smuzhiyun@@ -3015,7 +2997,7 @@ archs4x, archs4xd"
177*4882a593Smuzhiyun       DONE;
178*4882a593Smuzhiyun     }
179*4882a593Smuzhiyun   emit_insn (gen_sub_f (l0, l1, l2));
180*4882a593Smuzhiyun-  emit_insn (gen_sbc (h0, h1, h2, gen_rtx_REG (CCmode, CC_REG)));
181*4882a593Smuzhiyun+  emit_insn (gen_sbc (h0, h1, h2));
182*4882a593Smuzhiyun   DONE;
183*4882a593Smuzhiyun   ")
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun@@ -3030,44 +3012,25 @@ archs4x, archs4xd"
186*4882a593Smuzhiyun    (set_attr "type" "cc_arith")
187*4882a593Smuzhiyun    (set_attr "length" "4")])
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun-; w/c/c comes first (rather than Rcw/0/C_0) to prevent the middle-end
190*4882a593Smuzhiyun-; needlessly prioritizing the matching constraint.
191*4882a593Smuzhiyun-; Rcw/0/C_0 comes before w/c/L so that the lower latency conditional execution
192*4882a593Smuzhiyun-; is used where possible.
193*4882a593Smuzhiyun-(define_insn_and_split "sbc"
194*4882a593Smuzhiyun-  [(set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w,Rcw,w")
195*4882a593Smuzhiyun-	(minus:SI (minus:SI (match_operand:SI 1 "nonmemory_operand"
196*4882a593Smuzhiyun-						"c,0,c,0,cCal")
197*4882a593Smuzhiyun-			    (ltu:SI (match_operand:CC_C 3 "cc_use_register")
198*4882a593Smuzhiyun-				    (const_int 0)))
199*4882a593Smuzhiyun-		  (match_operand:SI 2 "nonmemory_operand" "c,C_0,L,I,cCal")))]
200*4882a593Smuzhiyun+(define_insn "sbc"
201*4882a593Smuzhiyun+  [(set (match_operand:SI 0 "dest_reg_operand"   "=r,r,r,r,r,r")
202*4882a593Smuzhiyun+	(minus:SI
203*4882a593Smuzhiyun+	 (minus:SI
204*4882a593Smuzhiyun+	  (match_operand:SI 1 "nonmemory_operand" "r,  0,r,0,  r,Cal")
205*4882a593Smuzhiyun+	  (ltu:SI (reg:CC_C CC_REG) (const_int 0)))
206*4882a593Smuzhiyun+	 (match_operand:SI 2 "nonmemory_operand"  "r,C_0,L,I,Cal,r")))]
207*4882a593Smuzhiyun   "register_operand (operands[1], SImode)
208*4882a593Smuzhiyun    || register_operand (operands[2], SImode)"
209*4882a593Smuzhiyun   "@
210*4882a593Smuzhiyun-	sbc %0,%1,%2
211*4882a593Smuzhiyun-	sub.cs %0,%1,1
212*4882a593Smuzhiyun-	sbc %0,%1,%2
213*4882a593Smuzhiyun-	sbc %0,%1,%2
214*4882a593Smuzhiyun-	sbc %0,%1,%2"
215*4882a593Smuzhiyun-  ; if we have a bad schedule after sched2, split.
216*4882a593Smuzhiyun-  "reload_completed
217*4882a593Smuzhiyun-   && !optimize_size && (!TARGET_ARC600_FAMILY)
218*4882a593Smuzhiyun-   && arc_scheduling_not_expected ()
219*4882a593Smuzhiyun-   && arc_sets_cc_p (prev_nonnote_insn (insn))
220*4882a593Smuzhiyun-   /* If next comes a return or other insn that needs a delay slot,
221*4882a593Smuzhiyun-      expect the adc to get into the delay slot.  */
222*4882a593Smuzhiyun-   && next_nonnote_insn (insn)
223*4882a593Smuzhiyun-   && !arc_need_delay (next_nonnote_insn (insn))
224*4882a593Smuzhiyun-   /* Restore operands before emitting.  */
225*4882a593Smuzhiyun-   && (extract_insn_cached (insn), 1)"
226*4882a593Smuzhiyun-  [(set (match_dup 0) (match_dup 4))
227*4882a593Smuzhiyun-   (cond_exec
228*4882a593Smuzhiyun-     (ltu (reg:CC_C CC_REG) (const_int 0))
229*4882a593Smuzhiyun-     (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1))))]
230*4882a593Smuzhiyun-  "operands[4] = simplify_gen_binary (MINUS, SImode, operands[1], operands[2]);"
231*4882a593Smuzhiyun+    sbc\\t%0,%1,%2
232*4882a593Smuzhiyun+    sub.cs\\t%0,%1,1
233*4882a593Smuzhiyun+    sbc\\t%0,%1,%2
234*4882a593Smuzhiyun+    sbc\\t%0,%1,%2
235*4882a593Smuzhiyun+    sbc\\t%0,%1,%2
236*4882a593Smuzhiyun+    sbc\\t%0,%1,%2"
237*4882a593Smuzhiyun   [(set_attr "cond" "use")
238*4882a593Smuzhiyun    (set_attr "type" "cc_arith")
239*4882a593Smuzhiyun-   (set_attr "length" "4,4,4,4,8")])
240*4882a593Smuzhiyun+   (set_attr "length" "4,4,4,4,8,8")])
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun (define_insn "sub_f"
243*4882a593Smuzhiyun   [(set (reg:CC CC_REG)
244