1 ;; Machine Descriptions for R8C/M16C/M32C
2 ;; Copyright (C) 2005-2025 Free Software Foundation, Inc.
3 ;; Contributed by Red Hat.
5 ;; This file is part of GCC.
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.
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.
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/>.
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.
28 ; Other than compensating for the above, the patterns below are pretty
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"))]
39 mov.b\t%2,r1h\n\tsha.b\tr1h,%0"
40 [(set_attr "flags" "oszc,oszc")]
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"))]
51 mov.b\t%2,r1h\n\tsha.b\tr1h,%0"
52 [(set_attr "flags" "oszc,oszc")]
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"))]
63 mov.b\t%2,r1h\n\tshl.b\tr1h,%0"
64 [(set_attr "flags" "szc,szc")]
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 ""))])]
74 "if (m32c_prepare_shift (operands, 1, ASHIFT))
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 ""))])]
84 "if (m32c_prepare_shift (operands, -1, ASHIFTRT))
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 ""))])]
94 "if (m32c_prepare_shift (operands, -1, LSHIFTRT))
98 ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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"))]
108 mov.b\t%2,r1h\n\tsha.w\tr1h,%0"
109 [(set_attr "flags" "oszc,oszc")]
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"))]
120 mov.b\t%2,r1h\n\tsha.w\tr1h,%0"
121 [(set_attr "flags" "oszc,oszc")]
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"))]
132 mov.b\t%2,r1h\n\tshl.w\tr1h,%0"
133 [(set_attr "flags" "szc,szc")]
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 ""))])]
143 "if (m32c_prepare_shift (operands, 1, ASHIFT))
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 ""))])]
153 "if (m32c_prepare_shift (operands, -1, ASHIFTRT))
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 ""))])]
163 "if (m32c_prepare_shift (operands, -1, LSHIFTRT))
170 ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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"))]
181 mov.b\t%2,r1h\n\tsha.l\tr1h,%0"
182 [(set_attr "flags" "oszc,oszc")]
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"))]
193 mov.b\t%2,r1h\n\tsha.l\tr1h,%0"
194 [(set_attr "flags" "oszc,oszc")]
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"))]
205 mov.b\t%2,r1h\n\tshl.l\tr1h,%0"
206 [(set_attr "flags" "szc,szc")]
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 ""))])]
216 "if (m32c_prepare_shift (operands, 1, ASHIFT))
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 ""))])]
226 "if (m32c_prepare_shift (operands, -1, ASHIFTRT))
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 ""))])]
236 "if (m32c_prepare_shift (operands, -1, LSHIFTRT))
240 ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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
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"))]
257 mov.b\t%2,r1h\n\tsha.l\tr1h,%0"
258 [(set_attr "flags" "oszc,oszc")]
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"))]
269 mov.b\t%2,r1h\n\tsha.l\tr1h,%0"
270 [(set_attr "flags" "oszc,oszc")]
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"))]
281 mov.b\t%2,r1h\n\tshl.l\tr1h,%0"
282 [(set_attr "flags" "szc,szc")]
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"))]
295 mov.b\t%2,r1h\n\tsha.l\tr1h,%0"
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"))]
306 mov.b\t%2,r1h\n\tsha.l\tr1h,%0"
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"))]
317 mov.b\t%2,r1h\n\tshl.l\tr1h,%0"
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 ""))])]
329 "if (m32c_prepare_shift (operands, 1, ASHIFT))
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 ""))])]
339 "if (m32c_prepare_shift (operands, -1, ASHIFTRT))
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 ""))])]
349 "if (m32c_prepare_shift (operands, -1, LSHIFTRT))