PR target/84064
[official-gcc.git] / gcc / config / nds32 / nds32-multiple.md
blob581a74f0194194f026fdca132861f707f0bfc71b
1 ;; Load/Store Multiple patterns description of Andes NDS32 cpu for GNU compiler
2 ;; Copyright (C) 2012-2018 Free Software Foundation, Inc.
3 ;; Contributed by Andes Technology Corporation.for NDS32.
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.
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/>.
22 ;; Load Multiple Insns.
24 ;; operands[0] is the first of the consecutive registers.
25 ;; operands[1] is the first memory location.
26 ;; operands[2] is the number of consecutive registers.
28 (define_expand "load_multiple"
29   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
30                           (match_operand:SI 1 "" ""))
31                      (use (match_operand:SI 2 "" ""))])]
32   ""
34   int maximum;
36   /* Because reduced-set regsiters has few registers
37      (r0~r5, r6~10, r15, r28~r31, where 'r15' and 'r28~r31' cannot
38      be used for register allocation),
39      using 8 registers for load_multiple may easily consume all of them.
40      It makes register allocation/spilling hard to work.
41      So we only allow maximum=4 registers for load_multiple
42      under reduced-set registers.  */
43   if (TARGET_REDUCED_REGS)
44     maximum = 4;
45   else
46     maximum = 8;
48   /* Here are the conditions that must be all passed,
49      otherwise we have to FAIL this rtx generation:
50        1. The number of consecutive registers must be integer.
51        2. Maximum 4 or 8 registers for lmw.bi instruction
52           (based on this nds32-multiple.md design).
53        3. Minimum 2 registers for lmw.bi instruction
54           (based on this nds32-multiple.md design).
55        4. operands[0] must be register for sure.
56        5. operands[1] must be memory for sure.
57        6. Do not cross $r15 register because it is not allocatable.  */
58   if (GET_CODE (operands[2]) != CONST_INT
59       || INTVAL (operands[2]) > maximum
60       || INTVAL (operands[2]) < 2
61       || GET_CODE (operands[0]) != REG
62       || GET_CODE (operands[1]) != MEM
63       || REGNO (operands[0]) + INTVAL (operands[2]) > TA_REGNUM)
64     FAIL;
66   /* For (mem addr), we force_reg on addr here,
67      so that nds32_expand_load_multiple can easily use it.  */
68   operands[3] = nds32_expand_load_multiple (REGNO (operands[0]),
69                                             INTVAL (operands[2]),
70                                             force_reg (SImode,
71                                                        XEXP (operands[1], 0)),
72                                             operands[1]);
75 ;; Ordinary Load Multiple.
77 (define_insn "*lmwsi8"
78   [(match_parallel 0 "nds32_load_multiple_operation"
79     [(set (match_operand:SI 2 "register_operand" "")
80           (mem:SI (match_operand:SI 1 "register_operand" "r")))
81      (set (match_operand:SI 3 "register_operand" "")
82           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
83      (set (match_operand:SI 4 "register_operand" "")
84           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
85      (set (match_operand:SI 5 "register_operand" "")
86           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
87      (set (match_operand:SI 6 "register_operand" "")
88           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
89      (set (match_operand:SI 7 "register_operand" "")
90           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
91      (set (match_operand:SI 8 "register_operand" "")
92           (mem:SI (plus:SI (match_dup 1) (const_int 24))))
93      (set (match_operand:SI 9 "register_operand" "")
94           (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
95   "(XVECLEN (operands[0], 0) == 8)"
96   "lmw.bi\t%2, [%1], %9, 0x0"
97   [(set_attr "type"   "load")
98    (set_attr "length"    "4")]
101 (define_insn "*lmwsi7"
102   [(match_parallel 0 "nds32_load_multiple_operation"
103     [(set (match_operand:SI 2 "register_operand" "")
104           (mem:SI (match_operand:SI 1 "register_operand" "r")))
105      (set (match_operand:SI 3 "register_operand" "")
106           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
107      (set (match_operand:SI 4 "register_operand" "")
108           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
109      (set (match_operand:SI 5 "register_operand" "")
110           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
111      (set (match_operand:SI 6 "register_operand" "")
112           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
113      (set (match_operand:SI 7 "register_operand" "")
114           (mem:SI (plus:SI (match_dup 1) (const_int 20))))
115      (set (match_operand:SI 8 "register_operand" "")
116           (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
117   "(XVECLEN (operands[0], 0) == 7)"
118   "lmw.bi\t%2, [%1], %8, 0x0"
119   [(set_attr "type"   "load")
120    (set_attr "length"    "4")]
123 (define_insn "*lmwsi6"
124   [(match_parallel 0 "nds32_load_multiple_operation"
125     [(set (match_operand:SI 2 "register_operand" "")
126           (mem:SI (match_operand:SI 1 "register_operand" "r")))
127      (set (match_operand:SI 3 "register_operand" "")
128           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
129      (set (match_operand:SI 4 "register_operand" "")
130           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
131      (set (match_operand:SI 5 "register_operand" "")
132           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
133      (set (match_operand:SI 6 "register_operand" "")
134           (mem:SI (plus:SI (match_dup 1) (const_int 16))))
135      (set (match_operand:SI 7 "register_operand" "")
136           (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
137   "(XVECLEN (operands[0], 0) == 6)"
138   "lmw.bi\t%2, [%1], %7, 0x0"
139   [(set_attr "type"   "load")
140    (set_attr "length"    "4")]
143 (define_insn "*lmwsi5"
144   [(match_parallel 0 "nds32_load_multiple_operation"
145     [(set (match_operand:SI 2 "register_operand" "")
146           (mem:SI (match_operand:SI 1 "register_operand" "r")))
147      (set (match_operand:SI 3 "register_operand" "")
148           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
149      (set (match_operand:SI 4 "register_operand" "")
150           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
151      (set (match_operand:SI 5 "register_operand" "")
152           (mem:SI (plus:SI (match_dup 1) (const_int 12))))
153      (set (match_operand:SI 6 "register_operand" "")
154           (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
155   "(XVECLEN (operands[0], 0) == 5)"
156   "lmw.bi\t%2, [%1], %6, 0x0"
157   [(set_attr "type"   "load")
158    (set_attr "length"    "4")]
161 (define_insn "*lmwsi4"
162   [(match_parallel 0 "nds32_load_multiple_operation"
163     [(set (match_operand:SI 2 "register_operand" "")
164           (mem:SI (match_operand:SI 1 "register_operand" "r")))
165      (set (match_operand:SI 3 "register_operand" "")
166           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
167      (set (match_operand:SI 4 "register_operand" "")
168           (mem:SI (plus:SI (match_dup 1) (const_int 8))))
169      (set (match_operand:SI 5 "register_operand" "")
170           (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
171   "(XVECLEN (operands[0], 0) == 4)"
172   "lmw.bi\t%2, [%1], %5, 0x0"
173   [(set_attr "type"   "load")
174    (set_attr "length"    "4")]
177 (define_insn "*lmwsi3"
178   [(match_parallel 0 "nds32_load_multiple_operation"
179     [(set (match_operand:SI 2 "register_operand" "")
180           (mem:SI (match_operand:SI 1 "register_operand" "r")))
181      (set (match_operand:SI 3 "register_operand" "")
182           (mem:SI (plus:SI (match_dup 1) (const_int 4))))
183      (set (match_operand:SI 4 "register_operand" "")
184           (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
185   "(XVECLEN (operands[0], 0) == 3)"
186   "lmw.bi\t%2, [%1], %4, 0x0"
187   [(set_attr "type"   "load")
188    (set_attr "length"    "4")]
191 (define_insn "*lmwsi2"
192   [(match_parallel 0 "nds32_load_multiple_operation"
193     [(set (match_operand:SI 2 "register_operand" "")
194           (mem:SI (match_operand:SI 1 "register_operand" "r")))
195      (set (match_operand:SI 3 "register_operand" "")
196           (mem:SI (plus:SI (match_dup 1) (const_int 4))))])]
197   "(XVECLEN (operands[0], 0) == 2)"
198   "lmw.bi\t%2, [%1], %3, 0x0"
199   [(set_attr "type"   "load")
200    (set_attr "length"    "4")]
204 ;; Store Multiple Insns.
206 ;; operands[0] is the first memory location.
207 ;; opernads[1] is the first of the consecutive registers.
208 ;; operands[2] is the number of consecutive registers.
210 (define_expand "store_multiple"
211   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
212                           (match_operand:SI 1 "" ""))
213                      (use (match_operand:SI 2 "" ""))])]
214   ""
216   int maximum;
218   /* Because reduced-set regsiters has few registers
219      (r0~r5, r6~10, r15, r28~r31, where 'r15' and 'r28~r31' cannot
220      be used for register allocation),
221      using 8 registers for store_multiple may easily consume all of them.
222      It makes register allocation/spilling hard to work.
223      So we only allow maximum=4 registers for store_multiple
224      under reduced-set registers.  */
225   if (TARGET_REDUCED_REGS)
226     maximum = 4;
227   else
228     maximum = 8;
230   /* Here are the conditions that must be all passed,
231      otherwise we have to FAIL this rtx generation:
232        1. The number of consecutive registers must be integer.
233        2. Maximum 4 or 8 registers for smw.bi instruction
234           (based on this nds32-multiple.md design).
235        3. Minimum 2 registers for smw.bi instruction
236           (based on this nds32-multiple.md design).
237        4. operands[0] must be memory for sure.
238        5. operands[1] must be register for sure.
239        6. Do not cross $r15 register because it is not allocatable.  */
240   if (GET_CODE (operands[2]) != CONST_INT
241       || INTVAL (operands[2]) > maximum
242       || INTVAL (operands[2]) < 2
243       || GET_CODE (operands[0]) != MEM
244       || GET_CODE (operands[1]) != REG
245       || REGNO (operands[1]) + INTVAL (operands[2]) > TA_REGNUM)
246     FAIL;
248   /* For (mem addr), we force_reg on addr here,
249      so that nds32_expand_store_multiple can easily use it.  */
250   operands[3] = nds32_expand_store_multiple (REGNO (operands[1]),
251                                              INTVAL (operands[2]),
252                                              force_reg (SImode,
253                                                         XEXP (operands[0], 0)),
254                                              operands[0]);
257 ;; Ordinary Store Multiple.
259 (define_insn "*stmsi8"
260   [(match_parallel 0 "nds32_store_multiple_operation"
261     [(set (mem:SI (match_operand:SI 1 "register_operand" "r"))
262           (match_operand:SI 2 "register_operand" ""))
263      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
264           (match_operand:SI 3 "register_operand" ""))
265      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
266           (match_operand:SI 4 "register_operand" ""))
267      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
268           (match_operand:SI 5 "register_operand" ""))
269      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
270           (match_operand:SI 6 "register_operand" ""))
271      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
272           (match_operand:SI 7 "register_operand" ""))
273      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
274           (match_operand:SI 8 "register_operand" ""))
275      (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
276           (match_operand:SI 9 "register_operand" ""))])]
277   "(XVECLEN (operands[0], 0) == 8)"
278   "smw.bi\t%2, [%1], %9, 0x0"
279   [(set_attr "type"   "store")
280    (set_attr "length"     "4")]
283 (define_insn "*stmsi7"
284   [(match_parallel 0 "nds32_store_multiple_operation"
285     [(set (mem:SI (match_operand:SI 1 "register_operand" "r"))
286           (match_operand:SI 2 "register_operand" ""))
287      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
288           (match_operand:SI 3 "register_operand" ""))
289      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
290           (match_operand:SI 4 "register_operand" ""))
291      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
292           (match_operand:SI 5 "register_operand" ""))
293      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
294           (match_operand:SI 6 "register_operand" ""))
295      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
296           (match_operand:SI 7 "register_operand" ""))
297      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
298           (match_operand:SI 8 "register_operand" ""))])]
299   "(XVECLEN (operands[0], 0) == 7)"
300   "smw.bi\t%2, [%1], %8, 0x0"
301   [(set_attr "type"   "store")
302    (set_attr "length"     "4")]
305 (define_insn "*stmsi6"
306   [(match_parallel 0 "nds32_store_multiple_operation"
307     [(set (mem:SI (match_operand:SI 1 "register_operand" "r"))
308           (match_operand:SI 2 "register_operand" ""))
309      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
310           (match_operand:SI 3 "register_operand" ""))
311      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
312           (match_operand:SI 4 "register_operand" ""))
313      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
314           (match_operand:SI 5 "register_operand" ""))
315      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
316           (match_operand:SI 6 "register_operand" ""))
317      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
318           (match_operand:SI 7 "register_operand" ""))])]
319   "(XVECLEN (operands[0], 0) == 6)"
320   "smw.bi\t%2, [%1], %7, 0x0"
321   [(set_attr "type"   "store")
322    (set_attr "length"     "4")]
325 (define_insn "*stmsi5"
326   [(match_parallel 0 "nds32_store_multiple_operation"
327     [(set (mem:SI (match_operand:SI 1 "register_operand" "r"))
328           (match_operand:SI 2 "register_operand" ""))
329      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
330           (match_operand:SI 3 "register_operand" ""))
331      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
332           (match_operand:SI 4 "register_operand" ""))
333      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
334           (match_operand:SI 5 "register_operand" ""))
335      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
336           (match_operand:SI 6 "register_operand" ""))])]
337   "(XVECLEN (operands[0], 0) == 5)"
338   "smw.bi\t%2, [%1], %6, 0x0"
339   [(set_attr "type"   "store")
340    (set_attr "length"     "4")]
343 (define_insn "*stmsi4"
344   [(match_parallel 0 "nds32_store_multiple_operation"
345     [(set (mem:SI (match_operand:SI 1 "register_operand" "r"))
346           (match_operand:SI 2 "register_operand" ""))
347      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
348           (match_operand:SI 3 "register_operand" ""))
349      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
350           (match_operand:SI 4 "register_operand" ""))
351      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
352           (match_operand:SI 5 "register_operand" ""))])]
353   "(XVECLEN (operands[0], 0) == 4)"
354   "smw.bi\t%2, [%1], %5, 0x0"
355   [(set_attr "type"   "store")
356    (set_attr "length"     "4")]
359 (define_insn "*stmsi3"
360   [(match_parallel 0 "nds32_store_multiple_operation"
361     [(set (mem:SI (match_operand:SI 1 "register_operand" "r"))
362           (match_operand:SI 2 "register_operand" ""))
363      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
364           (match_operand:SI 3 "register_operand" ""))
365      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
366           (match_operand:SI 4 "register_operand" ""))])]
367   "(XVECLEN (operands[0], 0) == 3)"
368   "smw.bi\t%2, [%1], %4, 0x0"
369   [(set_attr "type"   "store")
370    (set_attr "length"     "4")]
373 (define_insn "*stmsi2"
374   [(match_parallel 0 "nds32_store_multiple_operation"
375     [(set (mem:SI (match_operand:SI 1 "register_operand" "r"))
376           (match_operand:SI 2 "register_operand" ""))
377      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
378           (match_operand:SI 3 "register_operand" ""))])]
379   "(XVECLEN (operands[0], 0) == 2)"
380   "smw.bi\t%2, [%1], %3, 0x0"
381   [(set_attr "type"   "store")
382    (set_attr "length"     "4")]
385 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
386 ;; We could let this apply for blocks of less than this, but it clobbers so
387 ;; many registers that there is then probably a better way.
389 ;; operands[0] is the destination block of memory.
390 ;; operands[1] is the source block of memory.
391 ;; operands[2] is the number of bytes to move.
392 ;; operands[3] is the known shared alignment.
394 (define_expand "movmemqi"
395   [(match_operand:BLK 0 "general_operand" "")
396    (match_operand:BLK 1 "general_operand" "")
397    (match_operand:SI 2 "const_int_operand" "")
398    (match_operand:SI 3 "const_int_operand" "")]
399   ""
401   if (nds32_expand_movmemqi (operands[0],
402                              operands[1],
403                              operands[2],
404                              operands[3]))
405     DONE;
407   FAIL;
410 ;; ------------------------------------------------------------------------