1;; Machine Descriptions for R8C/M16C/M32C
2;; Copyright (C) 2005-2014 Free Software Foundation, Inc.
3;; Contributed by Red Hat.
4;;
5;; This file is part of GCC.
6;;
7;; GCC is free software; you can redistribute it and/or modify it
8;; under the terms of the GNU General Public License as published
9;; by the Free Software Foundation; either version 3, or (at your
10;; option) any later version.
11;;
12;; GCC is distributed in the hope that it will be useful, but WITHOUT
13;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15;; License for more details.
16;;
17;; You should have received a copy of the GNU General Public License
18;; along with GCC; see the file COPYING3.  If not see
19;; <http://www.gnu.org/licenses/>.
20
21;; bit shifting
22
23; Shifts are unusual for m32c.  We only support shifting in one
24; "direction" but the shift count is signed.  Also, immediate shift
25; counts have a limited range, and variable shift counts have to be in
26; $r1h which GCC normally doesn't even know about.
27
28; Other than compensating for the above, the patterns below are pretty
29; straightforward.
30
31(define_insn "ashlqi3_i"
32  [(set (match_operand:QI 0 "mra_operand" "=RqiSd*Rmm,RqiSd*Rmm")
33	(ashift:QI (match_operand:QI 1 "mra_operand" "0,0")
34		   (match_operand:QI 2 "mrai_operand" "In4,RqiSd")))
35   (clobber (match_scratch:HI 3 "=X,R1w"))]
36  ""
37  "@
38   sha.b\t%2,%0
39   mov.b\t%2,r1h\n\tsha.b\tr1h,%0"
40  [(set_attr "flags" "oszc,oszc")]
41  )
42
43(define_insn "ashrqi3_i"
44  [(set (match_operand:QI 0 "mra_operand" "=RqiSd*Rmm,RqiSd*Rmm")
45	(ashiftrt:QI (match_operand:QI 1 "mra_operand" "0,0")
46		     (neg:QI (match_operand:QI 2 "mrai_operand" "In4,RqiSd"))))
47   (clobber (match_scratch:HI 3 "=X,R1w"))]
48  ""
49  "@
50   sha.b\t%2,%0
51   mov.b\t%2,r1h\n\tsha.b\tr1h,%0"
52  [(set_attr "flags" "oszc,oszc")]
53  )
54
55(define_insn "lshrqi3_i"
56  [(set (match_operand:QI 0 "mra_operand" "=RqiSd*Rmm,RqiSd*Rmm")
57	(lshiftrt:QI (match_operand:QI 1 "mra_operand" "0,0")
58		     (neg:QI (match_operand:QI 2 "mrai_operand" "In4,RqiSd"))))
59   (clobber (match_scratch:HI 3 "=X,R1w"))]
60  ""
61  "@
62   shl.b\t%2,%0
63   mov.b\t%2,r1h\n\tshl.b\tr1h,%0"
64  [(set_attr "flags" "szc,szc")]
65  )
66
67
68(define_expand "ashlqi3"
69  [(parallel [(set (match_operand:QI 0 "mra_operand" "")
70	(ashift:QI (match_operand:QI 1 "mra_operand" "")
71		   (match_operand:QI 2 "general_operand" "")))
72   (clobber (match_scratch:HI 3 ""))])]
73  ""
74  "if (m32c_prepare_shift (operands, 1, ASHIFT))
75     DONE;"
76  )
77
78(define_expand "ashrqi3"
79  [(parallel [(set (match_operand:QI 0 "mra_operand" "")
80	(ashiftrt:QI (match_operand:QI 1 "mra_operand" "")
81		     (neg:QI (match_operand:QI 2 "general_operand" ""))))
82   (clobber (match_scratch:HI 3 ""))])]
83  ""
84  "if (m32c_prepare_shift (operands, -1, ASHIFTRT))
85     DONE;"
86  )
87
88(define_expand "lshrqi3"
89  [(parallel [(set (match_operand:QI 0 "mra_operand" "")
90		   (lshiftrt:QI (match_operand:QI 1 "mra_operand" "")
91				(neg:QI (match_operand:QI 2 "general_operand" ""))))
92	      (clobber (match_scratch:HI 3 ""))])]
93  ""
94  "if (m32c_prepare_shift (operands, -1, LSHIFTRT))
95     DONE;"
96  )
97
98; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
99
100(define_insn "ashlhi3_i"
101  [(set (match_operand:HI 0 "mra_operand" "=SdRhi*Rmm,SdRhi*Rmm")
102	(ashift:HI (match_operand:HI 1 "mra_operand" "0,0")
103		   (match_operand:QI 2 "mrai_operand" "In4,RqiSd")))
104   (clobber (match_scratch:HI 3 "=X,R1w"))]
105  ""
106  "@
107   sha.w\t%2,%0
108   mov.b\t%2,r1h\n\tsha.w\tr1h,%0"
109  [(set_attr "flags" "oszc,oszc")]
110  )
111
112(define_insn "ashrhi3_i"
113  [(set (match_operand:HI 0 "mra_operand" "=SdRhi*Rmm,SdRhi*Rmm")
114	(ashiftrt:HI (match_operand:HI 1 "mra_operand" "0,0")
115		     (neg:QI (match_operand:QI 2 "mrai_operand" "In4,RqiSd"))))
116   (clobber (match_scratch:HI 3 "=X,R1w"))]
117  ""
118  "@
119   sha.w\t%2,%0
120   mov.b\t%2,r1h\n\tsha.w\tr1h,%0"
121  [(set_attr "flags" "oszc,oszc")]
122  )
123
124(define_insn "lshrhi3_i"
125  [(set (match_operand:HI 0 "mra_operand" "=RhiSd*Rmm,RhiSd*Rmm")
126	(lshiftrt:HI (match_operand:HI 1 "mra_operand" "0,0")
127		     (neg:QI (match_operand:QI 2 "mrai_operand" "In4,RqiSd"))))
128   (clobber (match_scratch:HI 3 "=X,R1w"))]
129  ""
130  "@
131   shl.w\t%2,%0
132   mov.b\t%2,r1h\n\tshl.w\tr1h,%0"
133  [(set_attr "flags" "szc,szc")]
134  )
135
136
137(define_expand "ashlhi3"
138  [(parallel [(set (match_operand:HI 0 "mra_operand" "")
139		   (ashift:HI (match_operand:HI 1 "mra_operand" "")
140			      (match_operand:QI 2 "general_operand" "")))
141	      (clobber (match_scratch:HI 3 ""))])]
142  ""
143  "if (m32c_prepare_shift (operands, 1, ASHIFT))
144     DONE;"
145  )
146
147(define_expand "ashrhi3"
148  [(parallel [(set (match_operand:HI 0 "mra_operand" "")
149		   (ashiftrt:HI (match_operand:HI 1 "mra_operand" "")
150				(neg:QI (match_operand:QI 2 "general_operand" ""))))
151	      (clobber (match_scratch:HI 3 ""))])]
152  ""
153  "if (m32c_prepare_shift (operands, -1, ASHIFTRT))
154     DONE;"
155  )
156
157(define_expand "lshrhi3"
158  [(parallel [(set (match_operand:HI 0 "mra_operand" "")
159		   (lshiftrt:HI (match_operand:HI 1 "mra_operand" "")
160				(neg:QI (match_operand:QI 2 "general_operand" ""))))
161	      (clobber (match_scratch:HI 3 ""))])]
162  ""
163  "if (m32c_prepare_shift (operands, -1, LSHIFTRT))
164     DONE;"
165  )
166
167
168
169
170; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
171
172
173(define_insn "ashlpsi3_i"
174  [(set (match_operand:PSI 0 "mra_operand" "=R02RaaSd*Rmm,R02RaaSd*Rmm")
175	(ashift:PSI (match_operand:PSI 1 "mra_operand" "0,0")
176		    (match_operand:QI 2 "shiftcount_operand" "In4,RqiSd")))
177   (clobber (match_scratch:HI 3 "=X,R1w"))]
178  "TARGET_A24"
179  "@
180   sha.l\t%2,%0
181   mov.b\t%2,r1h\n\tsha.l\tr1h,%0"
182  [(set_attr "flags" "oszc,oszc")]
183  )
184
185(define_insn "ashrpsi3_i"
186  [(set (match_operand:PSI 0 "mra_operand" "=R02RaaSd*Rmm,R02RaaSd*Rmm")
187	(ashiftrt:PSI (match_operand:PSI 1 "mra_operand" "0,0")
188		      (neg:QI (match_operand:QI 2 "shiftcount_operand" "In4,RqiSd"))))
189   (clobber (match_scratch:HI 3 "=X,R1w"))]
190  "TARGET_A24"
191  "@
192   sha.l\t%2,%0
193   mov.b\t%2,r1h\n\tsha.l\tr1h,%0"
194  [(set_attr "flags" "oszc,oszc")]
195  )
196
197(define_insn "lshrpsi3_i"
198  [(set (match_operand:PSI 0 "mra_operand" "=R02RaaSd,??Rmm")
199	(lshiftrt:PSI (match_operand:PSI 1 "mra_operand" "0,0")
200		      (neg:QI (match_operand:QI 2 "shiftcount_operand" "In4,RqiSd"))))
201   (clobber (match_scratch:HI 3 "=X,R1w"))]
202  "TARGET_A24"
203  "@
204   shl.l\t%2,%0
205   mov.b\t%2,r1h\n\tshl.l\tr1h,%0"
206  [(set_attr "flags" "szc,szc")]
207  )
208
209
210(define_expand "ashlpsi3"
211  [(parallel [(set (match_operand:PSI 0 "mra_operand" "")
212		   (ashift:PSI (match_operand:PSI 1 "mra_operand" "")
213			       (match_operand:QI 2 "shiftcount_operand" "")))
214	      (clobber (match_scratch:HI 3 ""))])]
215  "TARGET_A24"
216  "if (m32c_prepare_shift (operands, 1, ASHIFT))
217     DONE;"
218  )
219
220(define_expand "ashrpsi3"
221  [(parallel [(set (match_operand:PSI 0 "mra_operand" "")
222		   (ashiftrt:PSI (match_operand:PSI 1 "mra_operand" "")
223				 (neg:QI (match_operand:QI 2 "shiftcount_operand" ""))))
224	      (clobber (match_scratch:HI 3 ""))])]
225  "TARGET_A24"
226  "if (m32c_prepare_shift (operands, -1, ASHIFTRT))
227     DONE;"
228  )
229
230(define_expand "lshrpsi3"
231  [(parallel [(set (match_operand:PSI 0 "mra_operand" "")
232		   (lshiftrt:PSI (match_operand:PSI 1 "mra_operand" "")
233				 (neg:QI (match_operand:QI 2 "shiftcount_operand" ""))))
234	      (clobber (match_scratch:HI 3 ""))])]
235  "TARGET_A24"
236  "if (m32c_prepare_shift (operands, -1, LSHIFTRT))
237     DONE;"
238  )
239
240; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
241
242; The m16c has a maximum shift count of -16..16, even when in a
243; register.  It's optimal to use multiple shifts of -8..8 rather than
244; loading larger constants into R1H multiple time.  The m32c can shift
245; -32..32 either via immediates or in registers.  Hence, separate
246; patterns.
247
248
249(define_insn "ashlsi3_16"
250  [(set (match_operand:SI 0 "r0123_operand" "=R03,R03")
251	(ashift:SI (match_operand:SI 1 "r0123_operand" "0,0")
252		   (match_operand:QI 2 "shiftcount_operand" "In4,RqiSd")))
253   (clobber (match_scratch:HI 3 "=X,R1w"))]
254  "TARGET_A16"
255  "@
256   sha.l\t%2,%0
257   mov.b\t%2,r1h\n\tsha.l\tr1h,%0"
258  [(set_attr "flags" "oszc,oszc")]
259  )
260
261(define_insn "ashrsi3_16"
262  [(set (match_operand:SI 0 "r0123_operand" "=R03,R03")
263	(ashiftrt:SI (match_operand:SI 1 "r0123_operand" "0,0")
264		     (neg:QI (match_operand:QI 2 "shiftcount_operand" "In4,RqiSd"))))
265   (clobber (match_scratch:HI 3 "=X,R1w"))]
266  "TARGET_A16"
267  "@
268   sha.l\t%2,%0
269   mov.b\t%2,r1h\n\tsha.l\tr1h,%0"
270  [(set_attr "flags" "oszc,oszc")]
271  )
272
273(define_insn "lshrsi3_16"
274  [(set (match_operand:SI 0 "r0123_operand" "=R03,R03")
275	(lshiftrt:SI (match_operand:SI 1 "r0123_operand" "0,0")
276		     (neg:QI (match_operand:QI 2 "shiftcount_operand" "In4,RqiSd"))))
277   (clobber (match_scratch:HI 3 "=X,R1w"))]
278  "TARGET_A16"
279  "@
280   shl.l\t%2,%0
281   mov.b\t%2,r1h\n\tshl.l\tr1h,%0"
282  [(set_attr "flags" "szc,szc")]
283  )
284
285
286
287(define_insn "ashlsi3_24"
288  [(set (match_operand:SI 0 "r0123_operand" "=R03,R03")
289	(ashift:SI (match_operand:SI 1 "r0123_operand" "0,0")
290		   (match_operand:QI 2 "longshiftcount_operand" "In6,RqiSd")))
291   (clobber (match_scratch:HI 3 "=X,R1w"))]
292  "TARGET_A24"
293  "@
294   sha.l\t%2,%0
295   mov.b\t%2,r1h\n\tsha.l\tr1h,%0"
296  )
297
298(define_insn "ashrsi3_24"
299  [(set (match_operand:SI 0 "r0123_operand" "=R03,R03")
300	(ashiftrt:SI (match_operand:SI 1 "r0123_operand" "0,0")
301		     (neg:QI (match_operand:QI 2 "longshiftcount_operand" "In6,RqiSd"))))
302   (clobber (match_scratch:HI 3 "=X,R1w"))]
303  "TARGET_A24"
304  "@
305   sha.l\t%2,%0
306   mov.b\t%2,r1h\n\tsha.l\tr1h,%0"
307  )
308
309(define_insn "lshrsi3_24"
310  [(set (match_operand:SI 0 "r0123_operand" "=R03,R03")
311	(lshiftrt:SI (match_operand:SI 1 "r0123_operand" "0,0")
312		     (neg:QI (match_operand:QI 2 "longshiftcount_operand" "In6,RqiSd"))))
313   (clobber (match_scratch:HI 3 "=X,R1w"))]
314  "TARGET_A24"
315  "@
316   shl.l\t%2,%0
317   mov.b\t%2,r1h\n\tshl.l\tr1h,%0"
318  )
319
320
321
322
323(define_expand "ashlsi3"
324  [(parallel [(set (match_operand:SI 0 "r0123_operand" "")
325		   (ashift:SI (match_operand:SI 1 "r0123_operand" "")
326			      (match_operand:QI 2 "mrai_operand" "")))
327	      (clobber (match_scratch:HI 3 ""))])]
328  ""
329  "if (m32c_prepare_shift (operands, 1, ASHIFT))
330     DONE;"
331  )
332
333(define_expand "ashrsi3"
334  [(parallel [(set (match_operand:SI 0 "r0123_operand" "")
335		   (ashiftrt:SI (match_operand:SI 1 "r0123_operand" "")
336				(neg:QI (match_operand:QI 2 "mrai_operand" ""))))
337	      (clobber (match_scratch:HI 3 ""))])]
338  ""
339  "if (m32c_prepare_shift (operands, -1, ASHIFTRT))
340     DONE;"
341  )
342
343(define_expand "lshrsi3"
344  [(parallel [(set (match_operand:SI 0 "r0123_operand" "")
345		   (lshiftrt:SI (match_operand:SI 1 "r0123_operand" "")
346				(neg:QI (match_operand:QI 2 "mrai_operand" ""))))
347	      (clobber (match_scratch:HI 3 ""))])]
348  ""
349  "if (m32c_prepare_shift (operands, -1, LSHIFTRT))
350     DONE;"
351  )
352